1 48 49 package org.jpublish.action; 50 51 import java.io.IOException ; 52 import java.util.*; 53 54 import com.anthonyeden.lib.config.Configuration; 55 import com.anthonyeden.lib.config.ConfigurationException; 56 import com.anthonyeden.lib.util.ClassUtilities; 57 import com.anthonyeden.lib.util.MessageUtilities; 58 import org.apache.bsf.BSFManager; 59 import org.apache.commons.logging.Log; 60 import org.apache.commons.logging.LogFactory; 61 import org.apache.commons.vfs.FileContent; 62 import org.apache.commons.vfs.FileName; 63 import org.apache.commons.vfs.FileObject; 64 import org.apache.commons.vfs.FileSystemManager; 65 import org.jpublish.*; 66 import org.jpublish.action.bsf.BSFScriptHandler; 67 import org.jpublish.cache.CacheEntry; 68 import org.jpublish.cache.CacheStorage; 69 import org.jpublish.cache.HashMapCacheStorage; 70 import org.jpublish.module.Module; 71 import org.jpublish.util.PathUtilities; 72 73 78 79 public class DefaultActionManager extends ManagerBase implements ActionManager { 80 81 85 public static final String DEFAULT_PATH = "*"; 86 87 private static final String ATTRIBUTE_NAME = "name"; 88 private static final String ATTRIBUTE_PATH = "path"; 89 private static final String ATTRIBUTE_CLASSNAME = "classname"; 90 private static final String ATTRIBUTE_NAMESPACE = "namespace"; 91 private static final String ATTRIBUTE_EXECUTE_RESULT = "execute-result"; 92 private static final String ATTRIBUTE_EXTENSION = "extension"; 93 94 private static Log log = LogFactory.getLog(DefaultActionManager.class); 95 96 private Map scriptHandlers = new HashMap(); 97 private Map definedActions = new HashMap(); 98 private List startupActions = new ArrayList(); 99 private List shutdownActions = new ArrayList(); 100 private List globalActions = new ArrayList(); 101 private List pathActions = new ArrayList(); 102 private List preEvaluationActions = new ArrayList(); 103 private List postEvaluationActions = new ArrayList(); 104 105 private CacheStorage scriptActionCache = null; 106 private ScriptHandlerDefinition defaultHandlerDefinition = null; 107 108 111 112 public DefaultActionManager() { 113 log.debug("Configuring BSF"); 114 configureBSF(); 116 } 117 118 123 124 public synchronized CacheStorage getScriptActionCache() { 125 if (scriptActionCache == null) { 126 scriptActionCache = new HashMapCacheStorage(); 127 } 128 return scriptActionCache; 129 } 130 131 137 138 public void setScriptActionCache(CacheStorage scriptActionCache) { 139 this.scriptActionCache = scriptActionCache; 140 } 141 142 148 149 public synchronized FileSystemManager getFileSystemManager() 150 throws IOException { 151 if (fileSystemManager == null) { 152 configureDefaultFileSystemManager(SiteContext.DEFAULT_ACTION_ROOT); 153 } 154 return fileSystemManager; 155 } 156 157 162 163 public Map getDefinedActions() { 164 return definedActions; 165 } 166 167 172 173 public List getStartupActions() { 174 return startupActions; 175 } 176 177 182 183 public List getShutdownActions() { 184 return shutdownActions; 185 } 186 187 192 193 public List getGlobalActions() { 194 return globalActions; 195 } 196 197 202 203 public List getPathActions() { 204 return pathActions; 205 } 206 207 213 214 public List getPreEvaluationActions() { 215 return preEvaluationActions; 216 } 217 218 224 225 public List getPostEvaluationActions() { 226 return postEvaluationActions; 227 } 228 229 232 233 public void executeStartupActions() { 234 log.debug("Executing startup actions"); 235 Iterator actions = getStartupActions().iterator(); 236 while (actions.hasNext()) { 237 ActionWrapper action = (ActionWrapper) actions.next(); 238 action.execute(null); 239 } 240 } 241 242 245 246 public void executeShutdownActions() { 247 log.debug("Executing shutdown actions"); 248 Iterator actions = getShutdownActions().iterator(); 249 while (actions.hasNext()) { 250 ActionWrapper action = (ActionWrapper) actions.next(); 251 action.execute(null); 252 } 253 } 254 255 260 261 public void executeGlobalActions(RequestContext context) { 262 Iterator actions = globalActions.iterator(); 263 while (actions.hasNext()) { 264 ActionWrapper action = (ActionWrapper) actions.next(); 265 action.execute(context); 266 } 267 } 268 269 275 276 public void executePathActions(String path, RequestContext context) { 277 Iterator actions = getPathActions().iterator(); 278 while (actions.hasNext()) { 279 ActionWrapper actionWrapper = (ActionWrapper) actions.next(); 280 PathAction action = (PathAction) actionWrapper.getAction(); 281 if (PathUtilities.match(path, action.getPath())) { 282 actionWrapper.execute(context); 283 } 284 } 285 } 286 287 301 302 public boolean executePreEvaluationActions(String path, 303 RequestContext context) { 304 Iterator actions = getPreEvaluationActions().iterator(); 305 while (actions.hasNext()) { 306 ActionWrapper actionWrapper = (ActionWrapper) actions.next(); 307 PathAction action = (PathAction) actionWrapper.getAction(); 308 if (PathUtilities.match(path, action.getPath())) { 309 actionWrapper.execute(context); 310 if (context.getStopProcessing() != null) { 311 return true; 312 } 313 } 314 } 315 return false; 316 } 317 318 324 325 public void executePostEvaluationActions(String path, 326 RequestContext context) { 327 Iterator actions = getPostEvaluationActions().iterator(); 328 while (actions.hasNext()) { 329 ActionWrapper actionWrapper = (ActionWrapper) actions.next(); 330 PathAction action = (PathAction) actionWrapper.getAction(); 331 if (PathUtilities.match(path, action.getPath())) { 332 actionWrapper.execute(context); 333 } 334 } 335 } 336 337 342 public void execute(String name) { 343 RequestContext context = RequestContext.getRequestContext(); 344 execute(name, context); 345 } 346 347 353 354 public void execute(String name, RequestContext context) { 355 if (log.isDebugEnabled()) { 356 log.debug("Executing action: " + name); 357 } 358 359 Action action = findAction(name); 360 if (action != null) { 361 action.execute(context, null); 362 } 363 } 364 365 374 375 public Action findAction(String name) { 376 377 log.debug("Looking for registered action."); 379 Action action = (Action) definedActions.get(name); 380 if (action != null) { 381 log.debug("Registered action found."); 382 return action; 383 } 384 385 log.debug("Looking for action in modules."); 387 Iterator modules = siteContext.getModules().iterator(); 388 while (modules.hasNext()) { 389 Module module = (Module) modules.next(); 390 action = (Action) (module.getDefinedActions().get(name)); 391 if (action != null) { 392 log.debug("Action found in module."); 393 return action; 394 } 395 } 396 397 Action scriptAction = findScriptAction(name); 399 if (scriptAction != null) { 400 return scriptAction; 401 } 402 403 try { 405 log.debug("Looking for action in the classpath."); 406 action = (Action) ClassUtilities.loadClass(name).newInstance(); 407 return action; 408 } catch (ClassNotFoundException e) { 409 if (log.isDebugEnabled()) { 410 log.debug("Action not found in classpath"); 411 } 412 } catch (Exception e) { 413 Object [] args = {name, e.getMessage()}; 414 throw new ActionNotFoundException(MessageUtilities.getMessage(getClass(), JPublishEngine.MESSAGE_PACKAGE, "actionNotFound", 415 args), e, name); 416 } 417 418 log.error("Action not found: " + name); 419 420 Object [] args = {name}; 421 throw new ActionNotFoundException(MessageUtilities.getMessage(getClass(), JPublishEngine.MESSAGE_PACKAGE, "actionNotFound", 422 args), name); 423 424 } 425 426 432 433 private Action findScriptAction(String name) { 434 CacheStorage scriptActionCache = getScriptActionCache(); 435 CacheEntry cacheEntry = (CacheEntry) scriptActionCache.get(name); 436 Action action = null; 437 try { 438 log.debug("Looking for action in scripts."); 439 FileSystemManager fileSystemManager = getFileSystemManager(); 440 FileObject baseFile = fileSystemManager.getBaseFile(); 441 FileObject file = fileSystemManager.resolveFile(baseFile, 442 PathUtilities.toRelativePath(name)); 443 FileName fileName = file.getName(); 444 FileContent content = file.getContent(); 445 String extension = fileName.getExtension(); 446 447 ScriptHandlerDefinition scriptHandlerDefinition = 448 (ScriptHandlerDefinition) scriptHandlers.get(extension); 449 if (scriptHandlerDefinition == null) { 450 scriptHandlerDefinition = defaultHandlerDefinition; 451 } 452 453 if (cacheEntry == null) { 454 log.debug("Action not in cache"); 455 if (file.exists()) { 456 if (log.isDebugEnabled()) { 457 log.debug("Script action found [" + file + "]"); 458 } 459 action = new ScriptAction(siteContext, file, 460 scriptHandlerDefinition); 461 scriptActionCache.put(name, new CacheEntry(action, 462 content.getLastModifiedTime())); 463 } 464 } else { 465 log.debug("Action found in cache"); 466 action = (Action) cacheEntry.getObject(); 467 if (cacheEntry.getLastModified() != 468 content.getLastModifiedTime()) { 469 if (log.isDebugEnabled()) { 470 log.debug("Reloading action [" + file + "]"); 471 } 472 473 action = new ScriptAction(siteContext, file, 474 scriptHandlerDefinition); 475 scriptActionCache.put(name, new CacheEntry(action, 476 content.getLastModifiedTime())); 477 } 478 } 479 } catch (IOException e) { 480 log.error("IO exception: " + e); 481 if (log.isDebugEnabled()) { 482 e.printStackTrace(); 483 } 484 } catch (Exception e) { 485 log.error("Exception: " + e); 486 Object [] args = {name, e.getMessage()}; 487 throw new JPublishRuntimeException(MessageUtilities.getMessage(getClass(), JPublishEngine.MESSAGE_PACKAGE, 488 "errorLoadingScript", args), e); 489 } 490 491 return action; 492 } 493 494 500 501 public void loadConfiguration(Configuration configuration) throws 502 ConfigurationException { 503 super.loadConfiguration(configuration); 504 505 try { 506 Configuration cacheStorageElement = configuration.getChild("cache-storage"); 508 if (cacheStorageElement != null) { 509 String className = cacheStorageElement.getAttribute(ATTRIBUTE_CLASSNAME, 510 HashMapCacheStorage.class.getName()); 511 CacheStorage cache = (CacheStorage) ClassUtilities.loadClass(className).newInstance(); 512 cache.loadConfiguration(cacheStorageElement); 513 setScriptActionCache(cache); 514 } 515 516 Iterator defineActionElements = configuration.getChildren("define-action").iterator(); 518 while (defineActionElements.hasNext()) { 519 Configuration defineActionElement = 520 (Configuration) defineActionElements.next(); 521 String name = defineActionElement.getAttribute(ATTRIBUTE_NAME); 522 String className = 523 defineActionElement.getAttribute(ATTRIBUTE_CLASSNAME); 524 Action action = (Action) ClassUtilities.loadClass(className).newInstance(); 525 if (log.isDebugEnabled()) { 526 log.debug("Defined action: " + name + " [" + 527 className + "]"); 528 } 529 definedActions.put(name, action); 530 } 531 532 Iterator defineXWorkActionElements = configuration.getChildren("define-xwork-action").iterator(); 534 while (defineXWorkActionElements.hasNext()) { 535 Configuration defineXWorkActionElement = 536 (Configuration) defineXWorkActionElements.next(); 537 String name = defineXWorkActionElement.getAttribute(ATTRIBUTE_NAME); 538 String namespace = defineXWorkActionElement.getAttribute(ATTRIBUTE_NAMESPACE); 539 String executeResult = defineXWorkActionElement.getAttribute(ATTRIBUTE_EXECUTE_RESULT); 540 541 XWorkAction action = new XWorkAction(); 542 543 action.setName(name); 544 action.setNamespace(namespace); 545 action.setExecuteResult(executeResult); 546 547 if (log.isDebugEnabled()) { 548 log.debug("Defined XWork action: " + name + " [ns=" + 549 namespace + "]"); 550 } 551 definedActions.put(name, action); 552 } 553 554 log.debug("Loading script handlers"); 556 Iterator scriptHandlerElements = 557 configuration.getChildren("script-handler").iterator(); 558 while (scriptHandlerElements.hasNext()) { 559 Configuration scriptHandlerElement = 560 (Configuration) scriptHandlerElements.next(); 561 String className = scriptHandlerElement.getAttribute(ATTRIBUTE_CLASSNAME); 562 String extension = scriptHandlerElement.getAttribute(ATTRIBUTE_EXTENSION); 563 ScriptHandlerDefinition scriptHandlerDefinition = 564 new ScriptHandlerDefinition(); 565 scriptHandlerDefinition.setHandlerClass(ClassUtilities.loadClass(className)); 566 scriptHandlerDefinition.loadConfiguration(scriptHandlerElement); 567 568 if (log.isDebugEnabled()) { 569 log.debug("Script handler for " + extension + ": " + 570 className); 571 } 572 573 if (extension == null) { 574 defaultHandlerDefinition = scriptHandlerDefinition; 575 } else { 576 scriptHandlers.put(extension, scriptHandlerDefinition); 577 } 578 } 579 580 Iterator startupActionElements = 582 configuration.getChildren("startup-action").iterator(); 583 while (startupActionElements.hasNext()) { 584 Configuration startupActionElement = 585 (Configuration) startupActionElements.next(); 586 String name = startupActionElement.getAttribute(ATTRIBUTE_NAME); 587 startupActions.add(new ActionWrapper(findAction(name), 588 startupActionElement)); 589 } 590 591 Iterator shutdownActionElements = 593 configuration.getChildren("shutdown-action").iterator(); 594 while (shutdownActionElements.hasNext()) { 595 Configuration shutdownActionElement = 596 (Configuration) shutdownActionElements.next(); 597 String name = shutdownActionElement.getAttribute(ATTRIBUTE_NAME); 598 shutdownActions.add(new ActionWrapper(findAction(name), 599 shutdownActionElement)); 600 } 601 602 log.debug("Configuring global actions"); 604 Iterator globalActionElements = 605 configuration.getChildren("global-action").iterator(); 606 while (globalActionElements.hasNext()) { 607 Configuration globalActionElement = 608 (Configuration) globalActionElements.next(); 609 String name = globalActionElement.getAttribute(ATTRIBUTE_NAME); 610 if (log.isDebugEnabled()) { 611 log.debug("Finding global action '" + name + "'"); 612 } 613 Action action = findAction(name); 614 if (action == null) { 615 log.error("No action '" + name + "' found"); 616 } else { 617 if (log.isDebugEnabled()) { 618 log.debug("Action '" + name + "' found"); 619 } 620 globalActions.add(new ActionWrapper(action, 621 globalActionElement)); 622 } 623 } 624 625 Iterator pathActionElements = 627 configuration.getChildren("path-action").iterator(); 628 while (pathActionElements.hasNext()) { 629 Configuration pathActionElement = 630 (Configuration) pathActionElements.next(); 631 String name = pathActionElement.getAttribute(ATTRIBUTE_NAME); 632 String path = pathActionElement.getAttribute(ATTRIBUTE_PATH); 633 if (path == null) { 634 path = DEFAULT_PATH; 635 } 636 637 pathActions.add(new ActionWrapper(new PathAction(path, findAction(name)), pathActionElement)); 638 } 639 640 Iterator preEvaluationActionElements = 642 configuration.getChildren("pre-evaluation-action").iterator(); 643 while (preEvaluationActionElements.hasNext()) { 644 Configuration preEvaluationActionElement = 645 (Configuration) preEvaluationActionElements.next(); 646 String name = preEvaluationActionElement.getAttribute(ATTRIBUTE_NAME); 647 String path = preEvaluationActionElement.getAttribute(ATTRIBUTE_PATH); 648 if (path == null) { 649 path = DEFAULT_PATH; 650 } 651 652 preEvaluationActions.add(new ActionWrapper(new PathAction(path, findAction(name)), 653 preEvaluationActionElement)); 654 } 655 656 Iterator postEvaluationActionElements = 658 configuration.getChildren("post-evaluation-action").iterator(); 659 while (postEvaluationActionElements.hasNext()) { 660 Configuration postEvaluationActionElement = 661 (Configuration) postEvaluationActionElements.next(); 662 String name = postEvaluationActionElement.getAttribute(ATTRIBUTE_NAME); 663 String path = postEvaluationActionElement.getAttribute(ATTRIBUTE_PATH); 664 if (path == null) { 665 path = DEFAULT_PATH; 666 } 667 668 postEvaluationActions.add(new ActionWrapper(new PathAction(path, findAction(name)), 669 postEvaluationActionElement)); 670 } 671 } catch (Exception e) { 672 Object [] args = {e.getMessage()}; 673 throw new ConfigurationException(MessageUtilities.getMessage(getClass(), JPublishEngine.MESSAGE_PACKAGE, 674 "errorLoadingConfiguration", args), e); 675 } 676 } 677 678 681 682 private void configureBSF() { 683 log.debug("Adding Beanshell to BSF"); 684 String [] beanshellExtensions = {"bsh"}; 685 BSFManager.registerScriptingEngine("beanshell", "bsh.util.BeanShellBSFEngine", beanshellExtensions); 686 687 log.debug("Adding Groovy to BSF"); 688 String [] groovyExtensions = {"groovy", "gy"}; 689 BSFManager.registerScriptingEngine("groovy", "org.codehaus.groovy.bsf.GroovyEngine", groovyExtensions); 690 691 defaultHandlerDefinition = new ScriptHandlerDefinition(); 692 defaultHandlerDefinition.setHandlerClass(BSFScriptHandler.class); 693 694 } 695 696 } 697 | Popular Tags |