1 17 package org.alfresco.repo.action; 18 19 import java.io.Serializable ; 20 import java.util.ArrayList ; 21 import java.util.Date ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Set ; 27 28 import org.alfresco.model.ContentModel; 29 import org.alfresco.repo.action.evaluator.ActionConditionEvaluator; 30 import org.alfresco.repo.action.executer.ActionExecuter; 31 import org.alfresco.repo.security.authentication.AuthenticationComponent; 32 import org.alfresco.repo.transaction.AlfrescoTransactionSupport; 33 import org.alfresco.service.cmr.action.Action; 34 import org.alfresco.service.cmr.action.ActionCondition; 35 import org.alfresco.service.cmr.action.ActionConditionDefinition; 36 import org.alfresco.service.cmr.action.ActionDefinition; 37 import org.alfresco.service.cmr.action.ActionService; 38 import org.alfresco.service.cmr.action.ActionServiceException; 39 import org.alfresco.service.cmr.action.CompositeAction; 40 import org.alfresco.service.cmr.action.ParameterizedItem; 41 import org.alfresco.service.cmr.repository.ChildAssociationRef; 42 import org.alfresco.service.cmr.repository.NodeRef; 43 import org.alfresco.service.cmr.repository.NodeService; 44 import org.alfresco.service.cmr.search.SearchService; 45 import org.alfresco.service.namespace.DynamicNamespacePrefixResolver; 46 import org.alfresco.service.namespace.NamespaceService; 47 import org.alfresco.service.namespace.QName; 48 import org.alfresco.service.namespace.RegexQNamePattern; 49 import org.alfresco.util.GUID; 50 import org.apache.commons.logging.Log; 51 import org.apache.commons.logging.LogFactory; 52 import org.springframework.beans.BeansException; 53 import org.springframework.context.ApplicationContext; 54 import org.springframework.context.ApplicationContextAware; 55 56 61 public class ActionServiceImpl implements ActionService, RuntimeActionService, ApplicationContextAware 62 { 63 66 private static final String POST_TRANSACTION_PENDING_ACTIONS = "postTransactionPendingActions"; 67 68 71 private static final String ERR_FAIL = "The action failed to execute due to an error."; 72 73 74 private static final QName ASSOC_NAME_ACTIONS = QName.createQName(ActionModel.ACTION_MODEL_URI, "actions"); 75 76 79 private static Log logger = LogFactory.getLog(ActionServiceImpl.class); 80 81 84 ThreadLocal <Set <String >> currentActionChain = new ThreadLocal <Set <String >>(); 85 86 89 private ApplicationContext applicationContext; 90 91 94 private NodeService nodeService; 95 96 99 private SearchService searchService; 100 101 102 private AuthenticationComponent authenticationComponent; 103 104 107 private AsynchronousActionExecutionQueue asynchronousActionExecutionQueue; 108 109 112 private ActionTransactionListener transactionListener = new ActionTransactionListener(this); 113 114 117 private Map <String , ActionConditionDefinition> conditionDefinitions = new HashMap <String , ActionConditionDefinition>(); 118 119 122 private Map <String , ActionDefinition> actionDefinitions = new HashMap <String , ActionDefinition>(); 123 124 129 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 130 { 131 this.applicationContext = applicationContext; 132 } 133 134 139 public void setNodeService(NodeService nodeService) 140 { 141 this.nodeService = nodeService; 142 } 143 144 149 public void setSearchService(SearchService searchService) 150 { 151 this.searchService = searchService; 152 } 153 154 159 public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) 160 { 161 this.authenticationComponent = authenticationComponent; 162 } 163 164 169 public void setAsynchronousActionExecutionQueue( 170 AsynchronousActionExecutionQueue asynchronousActionExecutionQueue) 171 { 172 this.asynchronousActionExecutionQueue = asynchronousActionExecutionQueue; 173 } 174 175 180 public AsynchronousActionExecutionQueue getAsynchronousActionExecutionQueue() 181 { 182 return asynchronousActionExecutionQueue; 183 } 184 185 191 private NodeRef getSavedActionFolderRef(NodeRef nodeRef) 192 { 193 List <ChildAssociationRef> assocs = this.nodeService.getChildAssocs( 194 nodeRef, 195 RegexQNamePattern.MATCH_ALL, 196 ActionModel.ASSOC_ACTION_FOLDER); 197 if (assocs.size() != 1) 198 { 199 throw new ActionServiceException("Unable to retrieve the saved action folder reference."); 200 } 201 202 return assocs.get(0).getChildRef(); 203 } 204 205 208 public ActionDefinition getActionDefinition(String name) 209 { 210 return this.actionDefinitions.get(name); 211 } 212 213 216 public List <ActionDefinition> getActionDefinitions() 217 { 218 return new ArrayList <ActionDefinition>(this.actionDefinitions.values()); 219 } 220 221 224 public ActionConditionDefinition getActionConditionDefinition(String name) 225 { 226 return this.conditionDefinitions.get(name); 227 } 228 229 232 public List <ActionConditionDefinition> getActionConditionDefinitions() 233 { 234 return new ArrayList <ActionConditionDefinition>(this.conditionDefinitions.values()); 235 } 236 237 240 public ActionCondition createActionCondition(String name) 241 { 242 return new ActionConditionImpl(GUID.generate(), name); 243 } 244 245 248 public ActionCondition createActionCondition(String name, Map <String , Serializable > params) 249 { 250 ActionCondition condition = createActionCondition(name); 251 condition.setParameterValues(params); 252 return condition; 253 } 254 255 258 public Action createAction(String name) 259 { 260 return new ActionImpl(GUID.generate(),name, null); 261 } 262 263 266 public Action createAction(String name, Map <String , Serializable > params) 267 { 268 Action action = createAction(name); 269 action.setParameterValues(params); 270 return action; 271 } 272 273 276 public CompositeAction createCompositeAction() 277 { 278 return new CompositeActionImpl(GUID.generate(), null); 279 } 280 281 284 public boolean evaluateAction(Action action, NodeRef actionedUponNodeRef) 285 { 286 boolean result = true; 287 288 if (action.hasActionConditions() == true) 289 { 290 List <ActionCondition> actionConditions = action.getActionConditions(); 291 for (ActionCondition condition : actionConditions) 292 { 293 result = result && evaluateActionCondition(condition, actionedUponNodeRef); 294 } 295 } 296 297 return result; 298 } 299 300 303 public boolean evaluateActionCondition(ActionCondition condition, NodeRef actionedUponNodeRef) 304 { 305 boolean result = false; 306 307 ActionConditionEvaluator evaluator = (ActionConditionEvaluator)this.applicationContext.getBean(condition.getActionConditionDefinitionName()); 309 result = evaluator.evaluate(condition, actionedUponNodeRef); 310 311 return result; 312 } 313 314 317 public void executeAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions) 318 { 319 executeAction(action, actionedUponNodeRef, checkConditions, action.getExecuteAsychronously()); 320 } 321 322 325 public void executeAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions, boolean executeAsychronously) 326 { 327 Set <String > actionChain = this.currentActionChain.get(); 328 329 if (executeAsychronously == false) 330 { 331 executeActionImpl(action, actionedUponNodeRef, checkConditions, false, actionChain); 332 } 333 else 334 { 335 addPostTransactionPendingAction(action, actionedUponNodeRef, checkConditions, actionChain); 337 } 338 } 339 340 343 public void executeActionImpl( 344 Action action, 345 NodeRef actionedUponNodeRef, 346 boolean checkConditions, 347 boolean executedAsynchronously, 348 Set <String > actionChain) 349 { 350 if (logger.isDebugEnabled() == true) 351 { 352 StringBuilder builder = new StringBuilder ("Exceute action impl action chain = "); 353 if (actionChain == null) 354 { 355 builder.append("null"); 356 } 357 else 358 { 359 for (String value : actionChain) 360 { 361 builder.append(value).append(" "); 362 } 363 } 364 logger.debug(builder.toString()); 365 logger.debug("Current action = " + action.getId()); 366 } 367 368 String currentUserName = this.authenticationComponent.getCurrentUserName(); 370 371 if (actionChain == null || actionChain.contains(action.getId()) == false) 372 { 373 if (logger.isDebugEnabled() == true) 374 { 375 logger.debug("Doing executeActionImpl"); 376 } 377 378 try 379 { 380 Set <String > origActionChain = null; 381 382 if (actionChain == null) 383 { 384 actionChain = new HashSet <String >(); 385 } 386 else 387 { 388 origActionChain = new HashSet <String >(actionChain); 389 } 390 actionChain.add(action.getId()); 391 this.currentActionChain.set(actionChain); 392 393 if (logger.isDebugEnabled() == true) 394 { 395 logger.debug("Adding " + action.getId() + " to action chain."); 396 } 397 398 try 399 { 400 if (checkConditions == false || evaluateAction(action, actionedUponNodeRef) == true) 402 { 403 directActionExecution(action, actionedUponNodeRef); 405 } 406 } 407 finally 408 { 409 if (origActionChain == null) 410 { 411 this.currentActionChain.remove(); 412 } 413 else 414 { 415 this.currentActionChain.set(origActionChain); 416 } 417 418 if (logger.isDebugEnabled() == true) 419 { 420 logger.debug("Resetting the action chain."); 421 } 422 } 423 } 424 catch (Throwable exception) 425 { 426 logger.error( 428 "An error was encountered whilst executing the action '" + action.getActionDefinitionName() + "'.", 429 exception); 430 431 if (executedAsynchronously == true) 432 { 433 Action compensatingAction = action.getCompensatingAction(); 435 if (compensatingAction != null) 436 { 437 ((ActionImpl)compensatingAction).setRunAsUser(currentUserName); 439 440 this.asynchronousActionExecutionQueue.executeAction(this, compensatingAction, actionedUponNodeRef, false, null); 442 } 443 } 444 445 if (exception instanceof RuntimeException ) 447 { 448 throw (RuntimeException )exception; 449 } 450 else 451 { 452 throw new ActionServiceException(ERR_FAIL, exception); 453 } 454 455 } 456 } 457 } 458 459 462 public void directActionExecution(Action action, NodeRef actionedUponNodeRef) 463 { 464 if (logger.isDebugEnabled() == true) 466 { 467 logger.debug("The action is being executed as the user: " + this.authenticationComponent.getCurrentUserName()); 468 } 469 470 ActionExecuter executer = (ActionExecuter)this.applicationContext.getBean(action.getActionDefinitionName()); 472 executer.execute(action, actionedUponNodeRef); 473 } 474 475 478 public void executeAction(Action action, NodeRef actionedUponNodeRef) 479 { 480 executeAction(action, actionedUponNodeRef, true); 481 } 482 483 486 public void registerActionConditionEvaluator(ActionConditionEvaluator actionConditionEvaluator) 487 { 488 ActionConditionDefinition cond = actionConditionEvaluator.getActionConditionDefintion(); 489 this.conditionDefinitions.put(cond.getName(), cond); 490 } 491 492 495 public void registerActionExecuter(ActionExecuter actionExecuter) 496 { 497 ActionDefinition action = actionExecuter.getActionDefinition(); 498 this.actionDefinitions.put(action.getName(), action); 499 } 500 501 508 private NodeRef getActionNodeRefFromId(NodeRef nodeRef, String actionId) 509 { 510 NodeRef result = null; 511 512 if (this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true) 513 { 514 DynamicNamespacePrefixResolver namespacePrefixResolver = new DynamicNamespacePrefixResolver(); 515 namespacePrefixResolver.registerNamespace(NamespaceService.SYSTEM_MODEL_PREFIX, NamespaceService.SYSTEM_MODEL_1_0_URI); 516 517 List <NodeRef> nodeRefs = searchService.selectNodes( 518 getSavedActionFolderRef(nodeRef), 519 "*[@sys:" + ContentModel.PROP_NODE_UUID.getLocalName() + "='" + actionId + "']", 520 null, 521 namespacePrefixResolver, 522 false); 523 if (nodeRefs.size() != 0) 524 { 525 result = nodeRefs.get(0); 526 } 527 } 528 529 return result; 530 } 531 532 535 public void saveAction(NodeRef nodeRef, Action action) 536 { 537 NodeRef actionNodeRef = getActionNodeRefFromId(nodeRef, action.getId()); 538 if (actionNodeRef == null) 539 { 540 if (this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == false) 541 { 542 this.nodeService.addAspect(nodeRef, ActionModel.ASPECT_ACTIONS, null); 544 } 545 546 Map <QName, Serializable > props = new HashMap <QName, Serializable >(2); 547 props.put(ActionModel.PROP_DEFINITION_NAME, action.getActionDefinitionName()); 548 props.put(ContentModel.PROP_NODE_UUID, action.getId()); 549 550 QName actionType = ActionModel.TYPE_ACTION; 551 if(action instanceof CompositeAction) 552 { 553 actionType = ActionModel.TYPE_COMPOSITE_ACTION; 554 } 555 556 actionNodeRef = this.nodeService.createNode( 558 getSavedActionFolderRef(nodeRef), 559 ContentModel.ASSOC_CONTAINS, 560 ASSOC_NAME_ACTIONS, 561 actionType, 562 props).getChildRef(); 563 564 ((ActionImpl)action).setCreator((String )this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_CREATOR)); 566 ((ActionImpl)action).setCreatedDate((Date )this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_CREATED)); 567 } 568 569 saveActionImpl(nodeRef, actionNodeRef, action); 570 } 571 572 575 public void saveActionImpl(NodeRef owningNodeRef, NodeRef actionNodeRef, Action action) 576 { 577 ((ActionImpl)action).setOwningNodeRef(owningNodeRef); 579 580 saveActionProperties(actionNodeRef, action); 582 583 saveParameters(actionNodeRef, action); 585 586 saveConditions(actionNodeRef, action); 588 589 if (action instanceof CompositeAction) 590 { 591 saveActions(actionNodeRef, (CompositeAction)action); 593 } 594 595 ((ActionImpl)action).setModifier((String )this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_MODIFIER)); 597 ((ActionImpl)action).setModifiedDate((Date )this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_MODIFIED)); 598 } 599 600 606 private void saveActionProperties(NodeRef actionNodeRef, Action action) 607 { 608 Map <QName, Serializable > props = this.nodeService.getProperties(actionNodeRef); 610 props.put(ActionModel.PROP_ACTION_TITLE, action.getTitle()); 611 props.put(ActionModel.PROP_ACTION_DESCRIPTION, action.getDescription()); 612 props.put(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY, action.getExecuteAsychronously()); 613 this.nodeService.setProperties(actionNodeRef, props); 614 615 Action compensatingAction = action.getCompensatingAction(); 617 List <ChildAssociationRef> assocs = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_COMPENSATING_ACTION); 618 if (assocs.size() == 0) 619 { 620 if (compensatingAction != null) 621 { 622 Map <QName, Serializable > props2 = new HashMap <QName, Serializable >(2); 623 props2.put(ActionModel.PROP_DEFINITION_NAME, compensatingAction.getActionDefinitionName()); 624 props2.put(ContentModel.PROP_NODE_UUID, compensatingAction.getId()); 625 626 NodeRef compensatingActionNodeRef = this.nodeService.createNode( 627 actionNodeRef, 628 ActionModel.ASSOC_COMPENSATING_ACTION, 629 ActionModel.ASSOC_COMPENSATING_ACTION, 630 ActionModel.TYPE_ACTION, 631 props2).getChildRef(); 632 633 saveActionImpl(compensatingAction.getOwningNodeRef(), compensatingActionNodeRef, compensatingAction); 634 } 635 } 636 else 637 { 638 ChildAssociationRef assoc = assocs.get(0); 639 if (compensatingAction == null) 640 { 641 this.nodeService.removeChild(actionNodeRef, assoc.getChildRef()); 642 } 643 else 644 { 645 saveActionImpl(compensatingAction.getOwningNodeRef(), assoc.getChildRef(), compensatingAction); 646 } 647 } 648 } 649 650 656 private void saveActions(NodeRef compositeActionNodeRef, CompositeAction compositeAction) 657 { 658 660 Map <String , Action> idToAction = new HashMap <String , Action>(); 661 List <String > orderedIds = new ArrayList <String >(); 662 for (Action action : compositeAction.getActions()) 663 { 664 idToAction.put(action.getId(), action); 665 orderedIds.add(action.getId()); 666 } 667 668 List <ChildAssociationRef> actionRefs = this.nodeService.getChildAssocs(compositeActionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_ACTIONS); 669 for (ChildAssociationRef actionRef : actionRefs) 670 { 671 NodeRef actionNodeRef = actionRef.getChildRef(); 672 if (idToAction.containsKey(actionNodeRef.getId()) == false) 673 { 674 this.nodeService.removeChild(compositeActionNodeRef, actionNodeRef); 676 } 677 else 678 { 679 Action action = idToAction.get(actionNodeRef.getId()); 681 saveActionImpl(action.getOwningNodeRef(), actionNodeRef, action); 682 orderedIds.remove(actionNodeRef.getId()); 683 } 684 685 } 686 687 for (String actionId : orderedIds) 689 { 690 Action action = idToAction.get(actionId); 691 692 Map <QName, Serializable > props = new HashMap <QName, Serializable >(2); 693 props.put(ActionModel.PROP_DEFINITION_NAME, action.getActionDefinitionName()); 694 props.put(ContentModel.PROP_NODE_UUID, action.getId()); 695 696 NodeRef actionNodeRef = this.nodeService.createNode( 697 compositeActionNodeRef, 698 ActionModel.ASSOC_ACTIONS, 699 ActionModel.ASSOC_ACTIONS, 700 ActionModel.TYPE_ACTION, 701 props).getChildRef(); 702 703 saveActionImpl(action.getOwningNodeRef(), actionNodeRef, action); 704 } 705 } 706 707 713 private void saveConditions(NodeRef actionNodeRef, Action action) 714 { 715 717 Map <String , ActionCondition> idToCondition = new HashMap <String , ActionCondition>(); 718 List <String > orderedIds = new ArrayList <String >(); 719 for (ActionCondition actionCondition : action.getActionConditions()) 720 { 721 idToCondition.put(actionCondition.getId(), actionCondition); 722 orderedIds.add(actionCondition.getId()); 723 } 724 725 List <ChildAssociationRef> conditionRefs = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_CONDITIONS); 726 for (ChildAssociationRef conditionRef : conditionRefs) 727 { 728 NodeRef conditionNodeRef = conditionRef.getChildRef(); 729 if (idToCondition.containsKey(conditionNodeRef.getId()) == false) 730 { 731 this.nodeService.removeChild(actionNodeRef, conditionNodeRef); 733 } 734 else 735 { 736 saveConditionProperties(conditionNodeRef, idToCondition.get(conditionNodeRef.getId())); 737 738 saveParameters(conditionNodeRef, idToCondition.get(conditionNodeRef.getId())); 740 orderedIds.remove(conditionNodeRef.getId()); 741 } 742 743 } 744 745 for (String nextId : orderedIds) 747 { 748 ActionCondition actionCondition = idToCondition.get(nextId); 749 Map <QName, Serializable > props = new HashMap <QName, Serializable >(2); 750 props.put(ActionModel.PROP_DEFINITION_NAME, actionCondition.getActionConditionDefinitionName()); 751 props.put(ContentModel.PROP_NODE_UUID, actionCondition.getId()); 752 753 NodeRef conditionNodeRef = this.nodeService.createNode( 754 actionNodeRef, 755 ActionModel.ASSOC_CONDITIONS, 756 ActionModel.ASSOC_CONDITIONS, 757 ActionModel.TYPE_ACTION_CONDITION, 758 props).getChildRef(); 759 760 saveConditionProperties(conditionNodeRef, actionCondition); 761 saveParameters(conditionNodeRef, actionCondition); 762 } 763 } 764 765 771 private void saveConditionProperties(NodeRef conditionNodeRef, ActionCondition condition) 772 { 773 this.nodeService.setProperty(conditionNodeRef, ActionModel.PROP_CONDITION_INVERT, condition.getInvertCondition()); 774 775 } 776 777 783 private void saveParameters(NodeRef parameterizedNodeRef, ParameterizedItem item) 784 { 785 Map <String , Serializable > parameterMap = new HashMap <String , Serializable >(); 786 parameterMap.putAll(item.getParameterValues()); 787 788 List <ChildAssociationRef> parameters = this.nodeService.getChildAssocs(parameterizedNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_PARAMETERS); 789 for (ChildAssociationRef ref : parameters) 790 { 791 NodeRef paramNodeRef = ref.getChildRef(); 792 Map <QName, Serializable > nodeRefParameterMap = this.nodeService.getProperties(paramNodeRef); 793 String paramName = (String )nodeRefParameterMap.get(ActionModel.PROP_PARAMETER_NAME); 794 if (parameterMap.containsKey(paramName) == false) 795 { 796 this.nodeService.removeChild(parameterizedNodeRef, paramNodeRef); 798 } 799 else 800 { 801 nodeRefParameterMap.put(ActionModel.PROP_PARAMETER_VALUE, parameterMap.get(paramName)); 803 this.nodeService.setProperties(paramNodeRef, nodeRefParameterMap); 804 parameterMap.remove(paramName); 805 } 806 } 807 808 for (Map.Entry <String , Serializable > entry : parameterMap.entrySet()) 810 { 811 Map <QName, Serializable > nodeRefProperties = new HashMap <QName, Serializable >(2); 812 nodeRefProperties.put(ActionModel.PROP_PARAMETER_NAME, entry.getKey()); 813 nodeRefProperties.put(ActionModel.PROP_PARAMETER_VALUE, entry.getValue()); 814 815 this.nodeService.createNode( 816 parameterizedNodeRef, 817 ActionModel.ASSOC_PARAMETERS, 818 ActionModel.ASSOC_PARAMETERS, 819 ActionModel.TYPE_ACTION_PARAMETER, 820 nodeRefProperties); 821 } 822 } 823 824 827 public List <Action> getActions(NodeRef nodeRef) 828 { 829 List <Action> result = new ArrayList <Action>(); 830 831 if (this.nodeService.exists(nodeRef) == true && 832 this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true) 833 { 834 List <ChildAssociationRef> actions = this.nodeService.getChildAssocs( 835 getSavedActionFolderRef(nodeRef), 836 RegexQNamePattern.MATCH_ALL, ASSOC_NAME_ACTIONS); 837 for (ChildAssociationRef action : actions) 838 { 839 NodeRef actionNodeRef = action.getChildRef(); 840 result.add(createAction(nodeRef, actionNodeRef)); 841 } 842 } 843 844 return result; 845 } 846 847 853 private Action createAction(NodeRef owningNodeRef, NodeRef actionNodeRef) 854 { 855 Action result = null; 856 857 Map <QName, Serializable > properties = this.nodeService.getProperties(actionNodeRef); 858 859 QName actionType = this.nodeService.getType(actionNodeRef); 860 if (ActionModel.TYPE_COMPOSITE_ACTION.equals(actionType) == true) 861 { 862 result = new CompositeActionImpl(actionNodeRef.getId(), owningNodeRef); 864 populateCompositeAction(actionNodeRef, (CompositeAction)result); 865 } 866 else 867 { 868 result = new ActionImpl(actionNodeRef.getId(), (String )properties.get(ActionModel.PROP_DEFINITION_NAME), owningNodeRef); 870 populateAction(actionNodeRef, result); 871 } 872 873 return result; 874 } 875 876 882 private void populateAction(NodeRef actionNodeRef, Action action) 883 { 884 populateActionProperties(actionNodeRef, action); 886 887 populateParameters(actionNodeRef, action); 889 890 List <ChildAssociationRef> conditions = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_CONDITIONS); 892 for (ChildAssociationRef condition : conditions) 893 { 894 NodeRef conditionNodeRef = condition.getChildRef(); 895 action.addActionCondition(createActionCondition(conditionNodeRef)); 896 } 897 } 898 899 905 private void populateActionProperties(NodeRef actionNodeRef, Action action) 906 { 907 Map <QName, Serializable > props = this.nodeService.getProperties(actionNodeRef); 908 909 action.setTitle((String )props.get(ActionModel.PROP_ACTION_TITLE)); 910 action.setDescription((String )props.get(ActionModel.PROP_ACTION_DESCRIPTION)); 911 912 boolean value = false; 913 Boolean executeAsynchronously = (Boolean )props.get(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY); 914 if (executeAsynchronously != null) 915 { 916 value = executeAsynchronously.booleanValue(); 917 } 918 action.setExecuteAsynchronously(value); 919 920 ((ActionImpl)action).setCreator((String )props.get(ContentModel.PROP_CREATOR)); 921 ((ActionImpl)action).setCreatedDate((Date )props.get(ContentModel.PROP_CREATED)); 922 ((ActionImpl)action).setModifier((String )props.get(ContentModel.PROP_MODIFIER)); 923 ((ActionImpl)action).setModifiedDate((Date )props.get(ContentModel.PROP_MODIFIED)); 924 925 List <ChildAssociationRef> assocs = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_COMPENSATING_ACTION); 927 if (assocs.size() != 0) 928 { 929 Action compensatingAction = createAction(action.getOwningNodeRef(), assocs.get(0).getChildRef()); 930 action.setCompensatingAction(compensatingAction); 931 } 932 } 933 934 940 private void populateParameters(NodeRef parameterizedItemNodeRef, ParameterizedItem parameterizedItem) 941 { 942 List <ChildAssociationRef> parameters = this.nodeService.getChildAssocs(parameterizedItemNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_PARAMETERS); 943 for (ChildAssociationRef parameter : parameters) 944 { 945 NodeRef parameterNodeRef = parameter.getChildRef(); 946 Map <QName, Serializable > properties = this.nodeService.getProperties(parameterNodeRef); 947 parameterizedItem.setParameterValue( 948 (String )properties.get(ActionModel.PROP_PARAMETER_NAME), 949 properties.get(ActionModel.PROP_PARAMETER_VALUE)); 950 } 951 } 952 953 959 private ActionCondition createActionCondition(NodeRef conditionNodeRef) 960 { 961 Map <QName, Serializable > properties = this.nodeService.getProperties(conditionNodeRef); 962 ActionCondition condition = new ActionConditionImpl(conditionNodeRef.getId(), (String )properties.get(ActionModel.PROP_DEFINITION_NAME)); 963 964 boolean value = false; 965 Boolean invert = (Boolean )this.nodeService.getProperty(conditionNodeRef, ActionModel.PROP_CONDITION_INVERT); 966 if (invert != null) 967 { 968 value = invert.booleanValue(); 969 } 970 condition.setInvertCondition(value); 971 972 populateParameters(conditionNodeRef, condition); 973 return condition; 974 } 975 976 982 public void populateCompositeAction(NodeRef compositeNodeRef, CompositeAction compositeAction) 983 { 984 populateAction(compositeNodeRef, compositeAction); 985 986 List <ChildAssociationRef> actions = this.nodeService.getChildAssocs(compositeNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_ACTIONS); 987 for (ChildAssociationRef action : actions) 988 { 989 NodeRef actionNodeRef = action.getChildRef(); 990 compositeAction.addAction(createAction(compositeAction.getOwningNodeRef(), actionNodeRef)); 991 } 992 } 993 994 997 public Action getAction(NodeRef nodeRef, String actionId) 998 { 999 Action result = null; 1000 1001 if (this.nodeService.exists(nodeRef) == true && 1002 this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true) 1003 { 1004 NodeRef actionNodeRef = getActionNodeRefFromId(nodeRef, actionId); 1005 if (actionNodeRef != null) 1006 { 1007 result = createAction(nodeRef, actionNodeRef); 1008 } 1009 } 1010 1011 return result; 1012 } 1013 1014 1017 public void removeAction(NodeRef nodeRef, Action action) 1018 { 1019 if (this.nodeService.exists(nodeRef) == true && 1020 this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true) 1021 { 1022 NodeRef actionNodeRef = getActionNodeRefFromId(nodeRef, action.getId()); 1023 if (actionNodeRef != null) 1024 { 1025 this.nodeService.removeChild(getSavedActionFolderRef(nodeRef), actionNodeRef); 1026 } 1027 } 1028 } 1029 1030 1033 public void removeAllActions(NodeRef nodeRef) 1034 { 1035 if (this.nodeService.exists(nodeRef) == true && 1036 this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true) 1037 { 1038 List <ChildAssociationRef> actions = new ArrayList <ChildAssociationRef>(this.nodeService.getChildAssocs(getSavedActionFolderRef(nodeRef), RegexQNamePattern.MATCH_ALL, ASSOC_NAME_ACTIONS)); 1039 for (ChildAssociationRef action : actions) 1040 { 1041 this.nodeService.removeChild(getSavedActionFolderRef(nodeRef), action.getChildRef()); 1042 } 1043 } 1044 } 1045 1046 1053 @SuppressWarnings ("unchecked") 1054 private void addPostTransactionPendingAction( 1055 Action action, 1056 NodeRef actionedUponNodeRef, 1057 boolean checkConditions, 1058 Set <String > actionChain) 1059 { 1060 if (logger.isDebugEnabled() == true) 1061 { 1062 StringBuilder builder = new StringBuilder ("addPostTransactionPendingAction action chain = "); 1063 if (actionChain == null) 1064 { 1065 builder.append("null"); 1066 } 1067 else 1068 { 1069 for (String value : actionChain) 1070 { 1071 builder.append(value).append(" "); 1072 } 1073 } 1074 logger.debug(builder.toString()); 1075 logger.debug("Current action = " + action.getId()); 1076 } 1077 1078 if (actionChain == null || actionChain.contains(action.getId()) == false) 1080 { 1081 if (logger.isDebugEnabled() == true) 1082 { 1083 logger.debug("Doing addPostTransactionPendingAction"); 1084 } 1085 1086 if (logger.isDebugEnabled() == true) 1088 { 1089 logger.debug("The current user is: " + this.authenticationComponent.getCurrentUserName()); 1090 } 1091 ((ActionImpl)action).setRunAsUser(this.authenticationComponent.getCurrentUserName()); 1092 1093 AlfrescoTransactionSupport.bindListener(this.transactionListener); 1095 1096 List <PendingAction> pendingActions = (List <PendingAction>)AlfrescoTransactionSupport.getResource(POST_TRANSACTION_PENDING_ACTIONS); 1098 if (pendingActions == null) 1099 { 1100 pendingActions = new ArrayList <PendingAction>(); 1101 AlfrescoTransactionSupport.bindResource(POST_TRANSACTION_PENDING_ACTIONS, pendingActions); 1102 } 1103 1104 PendingAction pendingAction = new PendingAction(action, actionedUponNodeRef, checkConditions, actionChain); 1106 if (pendingActions.contains(pendingAction) == false) 1107 { 1108 pendingActions.add(pendingAction); 1109 } 1110 } 1111 } 1112 1113 1116 @SuppressWarnings ("unchecked") 1117 public List <PendingAction> getPostTransactionPendingActions() 1118 { 1119 return (List <PendingAction>)AlfrescoTransactionSupport.getResource(POST_TRANSACTION_PENDING_ACTIONS); 1120 } 1121 1122 1125 public class PendingAction 1126 { 1127 1130 private Action action; 1131 1132 1135 private NodeRef actionedUponNodeRef; 1136 1137 1140 private boolean checkConditions; 1141 1142 private Set <String > actionChain; 1143 1144 1151 public PendingAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions, Set <String > actionChain) 1152 { 1153 this.action = action; 1154 this.actionedUponNodeRef = actionedUponNodeRef; 1155 this.checkConditions = checkConditions; 1156 this.actionChain = actionChain; 1157 } 1158 1159 1164 public Action getAction() 1165 { 1166 return action; 1167 } 1168 1169 1174 public NodeRef getActionedUponNodeRef() 1175 { 1176 return actionedUponNodeRef; 1177 } 1178 1179 1184 public boolean getCheckConditions() 1185 { 1186 return this.checkConditions; 1187 } 1188 1189 public Set <String > getActionChain() 1190 { 1191 return this.actionChain; 1192 } 1193 1194 1197 @Override 1198 public int hashCode() 1199 { 1200 int hashCode = 37 * this.actionedUponNodeRef.hashCode(); 1201 hashCode += 37 * this.action.hashCode(); 1202 return hashCode; 1203 } 1204 1205 1208 @Override 1209 public boolean equals(Object obj) 1210 { 1211 if (this == obj) 1212 { 1213 return true; 1214 } 1215 if (obj instanceof PendingAction) 1216 { 1217 PendingAction that = (PendingAction) obj; 1218 return (this.action.equals(that.action) && this.actionedUponNodeRef.equals(that.actionedUponNodeRef)); 1219 } 1220 else 1221 { 1222 return false; 1223 } 1224 } 1225 } 1226} 1227 | Popular Tags |