diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml index 74618744d2..e183818fd4 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml @@ -268,5 +268,11 @@ ${spaces.store} + + + + true + + \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index da780f68fd..72d9d492a7 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -48,6 +48,7 @@ import org.alfresco.module.org_alfresco_module_rm.role.Role; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordServiceImpl; import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; @@ -180,6 +181,10 @@ public class RecordServiceImpl implements RecordService, /** File folder service */ private FileFolderService fileFolderService; + + /** Behaviour filter */ + @SuppressWarnings("unused") + private BehaviourFilter behaviourFilter; /** List of available record meta-data aspects */ private Set recordMetaDataAspects; @@ -311,6 +316,14 @@ public class RecordServiceImpl implements RecordService, { this.fileFolderService = fileFolderService; } + + /** + * @param behaviourFilter behaviour filter + */ + public void setBehaviourFilter(BehaviourFilter behaviourFilter) + { + this.behaviourFilter = behaviourFilter; + } /** * Init method @@ -522,61 +535,70 @@ public class RecordServiceImpl implements RecordService, @Override public Void doWork() throws Exception { - // get the new record container for the file plan - NodeRef newRecordContainer = filePlanService.getUnfiledContainer(filePlan); - if (newRecordContainer == null) + // disable delete rules + ruleService.disableRuleType("outbound"); + try { - throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); - } - - // get the documents readers - Long aclId = nodeService.getNodeAclId(nodeRef); - Set readers = permissionService.getReaders(aclId); - Set writers = permissionService.getWriters(aclId); - - // add the current owner to the list of extended writers - String owner = ownableService.getOwner(nodeRef); - - // remove the owner - ownableService.setOwner(nodeRef, OwnableService.NO_OWNER); - - // get the documents primary parent assoc - ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(nodeRef); - - // move the document into the file plan - nodeService.moveNode(nodeRef, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName()); - - // save the information about the originating details - Map aspectProperties = new HashMap(3); - aspectProperties.put(PROP_RECORD_ORIGINATING_LOCATION, (Serializable) parentAssoc.getParentRef()); - aspectProperties.put(PROP_RECORD_ORIGINATING_USER_ID, userId); - aspectProperties.put(PROP_RECORD_ORIGINATING_CREATION_DATE, new Date()); - nodeService.addAspect(nodeRef, ASPECT_RECORD_ORIGINATING_DETAILS, aspectProperties); - - // make the document a record - makeRecord(nodeRef); - - if (isLinked == true) - { - // turn off rules - ruleService.disableRules(); - try + // get the new record container for the file plan + NodeRef newRecordContainer = filePlanService.getUnfiledContainer(filePlan); + if (newRecordContainer == null) { - // maintain the original primary location - nodeService.addChild(parentAssoc.getParentRef(), nodeRef, parentAssoc.getTypeQName(), parentAssoc.getQName()); + throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); + } - // set the extended security - Set combinedWriters = new HashSet(writers); - combinedWriters.add(owner); - combinedWriters.add(AuthenticationUtil.getFullyAuthenticatedUser()); - - extendedSecurityService.addExtendedSecurity(nodeRef, readers, combinedWriters); - } - finally + // get the documents readers + Long aclId = nodeService.getNodeAclId(nodeRef); + Set readers = permissionService.getReaders(aclId); + Set writers = permissionService.getWriters(aclId); + + // add the current owner to the list of extended writers + String owner = ownableService.getOwner(nodeRef); + + // remove the owner + ownableService.setOwner(nodeRef, OwnableService.NO_OWNER); + + // get the documents primary parent assoc + ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(nodeRef); + + // move the document into the file plan + nodeService.moveNode(nodeRef, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName()); + + // save the information about the originating details + Map aspectProperties = new HashMap(3); + aspectProperties.put(PROP_RECORD_ORIGINATING_LOCATION, (Serializable) parentAssoc.getParentRef()); + aspectProperties.put(PROP_RECORD_ORIGINATING_USER_ID, userId); + aspectProperties.put(PROP_RECORD_ORIGINATING_CREATION_DATE, new Date()); + nodeService.addAspect(nodeRef, ASPECT_RECORD_ORIGINATING_DETAILS, aspectProperties); + + // make the document a record + makeRecord(nodeRef); + + if (isLinked == true) { - ruleService.enableRules(); + // turn off rules + ruleService.disableRules(); + try + { + // maintain the original primary location + nodeService.addChild(parentAssoc.getParentRef(), nodeRef, parentAssoc.getTypeQName(), parentAssoc.getQName()); + + // set the extended security + Set combinedWriters = new HashSet(writers); + combinedWriters.add(owner); + combinedWriters.add(AuthenticationUtil.getFullyAuthenticatedUser()); + + extendedSecurityService.addExtendedSecurity(nodeRef, readers, combinedWriters); + } + finally + { + ruleService.enableRules(); + } } } + finally + { + ruleService.enableRuleType("outbound"); + } return null; } @@ -638,6 +660,7 @@ public class RecordServiceImpl implements RecordService, */ private void makeRecord(NodeRef document) { + ruleService.disableRules(); try { // get the record id @@ -674,6 +697,10 @@ public class RecordServiceImpl implements RecordService, { throw new AlfrescoRuntimeException("Unable to make record, because rename failed.", e); } + finally + { + ruleService.enableRules(); + } } diff --git a/rm-server/source/java/org/alfresco/repo/rule/ruletrigger/ExtendedBeforeDeleteChildAssociationRuleTrigger.java b/rm-server/source/java/org/alfresco/repo/rule/ruletrigger/ExtendedBeforeDeleteChildAssociationRuleTrigger.java new file mode 100644 index 0000000000..7ebfd70775 --- /dev/null +++ b/rm-server/source/java/org/alfresco/repo/rule/ruletrigger/ExtendedBeforeDeleteChildAssociationRuleTrigger.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2005-2013 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.rule.ruletrigger; + +import java.util.Set; + +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.JavaBehaviour; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.transaction.TransactionalResourceHelper; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Prevent multiple triggering of outbound rules when moving records. + * + * @author Roy Wetherall + */ +public class ExtendedBeforeDeleteChildAssociationRuleTrigger + extends RuleTriggerAbstractBase + implements NodeServicePolicies.BeforeDeleteChildAssociationPolicy +{ + /** + * The logger + */ + private static Log logger = LogFactory.getLog(BeforeDeleteChildAssociationRuleTrigger.class); + + private static final String POLICY = "beforeDeleteChildAssociation"; + + private boolean isClassBehaviour = false; + + public void setIsClassBehaviour(boolean isClassBehaviour) + { + this.isClassBehaviour = isClassBehaviour; + } + + /** + * @see org.alfresco.repo.rule.ruletrigger.RuleTrigger#registerRuleTrigger() + */ + public void registerRuleTrigger() + { + if (isClassBehaviour == true) + { + this.policyComponent.bindClassBehaviour( + QName.createQName(NamespaceService.ALFRESCO_URI, POLICY), + this, + new JavaBehaviour(this, POLICY, NotificationFrequency.FIRST_EVENT)); + } + else + { + this.policyComponent.bindAssociationBehaviour( + QName.createQName(NamespaceService.ALFRESCO_URI, POLICY), + this, + new JavaBehaviour(this, POLICY, NotificationFrequency.FIRST_EVENT)); + } + } + + public void beforeDeleteChildAssociation(ChildAssociationRef childAssocRef) + { + // Break out early if rules are not enabled + if (!areRulesEnabled()) + { + return; + } + + NodeRef childNodeRef = childAssocRef.getChildRef(); + + // Avoid renamed nodes + Set renamedNodeRefSet = TransactionalResourceHelper.getSet(RULE_TRIGGER_RENAMED_NODES); + if (renamedNodeRefSet.contains(childNodeRef)) + { + return; + } + + if (logger.isDebugEnabled() == true) + { + logger.debug("Single child assoc trigger (policy = " + POLICY + ") fired for parent node " + childAssocRef.getParentRef() + " and child node " + childAssocRef.getChildRef()); + } + + triggerRules(childAssocRef.getParentRef(), childNodeRef); + } + +}