From 1f0aab425616c916b29b90028efd9405adc5d445 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 26 Nov 2013 03:59:43 +0000 Subject: [PATCH] RM-1098: Refactor RM model behavior into a more maintainable structure * moved all behaviours out of records management service * finally able to deprecate RecordsManagementService (relic of 1.0) * did a little repackaging to make things clear git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@58289 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org_alfresco_module_rm/log4j.properties | 14 +- .../rm-deprecated-context.xml | 74 +++++ .../rm-model-context.xml | 27 +- .../rm-service-context.xml | 75 +---- .../RecordsManagementService.java | 1 + .../RecordsManagementServiceImpl.java | 262 +----------------- .../model/{rma => }/BaseBehaviourBean.java | 3 +- .../rma/aspect/FilePlanComponentAspect.java | 169 +++++++++++ .../model/rma/{ => aspect}/RecordAspect.java | 3 +- .../RecordComponentIdentifierAspect.java | 75 +++++ .../type/DispositionActionDefinitionType.java | 99 +++++++ .../model/rma/{ => type}/FilePlanType.java | 3 +- .../rma/{ => type}/RecordCategoryType.java | 3 +- .../RecordsManagementContainerType.java | 3 +- .../AnnotatedBehaviourPostProcessor.java | 1 + 15 files changed, 462 insertions(+), 350 deletions(-) rename rm-server/source/{java => compatibility}/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java (96%) rename rm-server/source/{java => compatibility}/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java (57%) rename rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/{rma => }/BaseBehaviourBean.java (91%) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FilePlanComponentAspect.java rename rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/{ => aspect}/RecordAspect.java (95%) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/DispositionActionDefinitionType.java rename rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/{ => type}/FilePlanType.java (95%) rename rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/{ => type}/RecordCategoryType.java (95%) rename rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/{ => type}/RecordsManagementContainerType.java (95%) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties index 41e9ee8c9f..369d7ae1bd 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties @@ -10,15 +10,19 @@ log4j.logger.org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurit log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info # -# RM Permission Debug Information +# RM permission debug # #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter=debug #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMAfterInvocationProvider=debug #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.declarative=debug -#log4j.logger.org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImpl=debug -#log4j.logger.org.springframework.extensions.webscripts.ScriptDebugger=on +# +# RM Audit service debug +# #log4j.logger.org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService=debug -log4j.logger.org.alfresco.repo.policy.annotation.AnnotatedBehaviourPostProcessor=debug -log4j.logger.org.alfresco.module.org_alfresco_module_rm.behaviour.BaseBehaviourBean=debug \ No newline at end of file +# +# Behaviour debug +# +#log4j.logger.org.alfresco.repo.policy.annotation.AnnotatedBehaviourPostProcessor=debug +#log4j.logger.org.alfresco.module.org_alfresco_module_rm.behaviour.BaseBehaviourBean=debug \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml index eaf943c70f..d472ccb460 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml @@ -59,4 +59,78 @@ + + + + + + + + + + + org.alfresco.module.org_alfresco_module_rm.RecordsManagementService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml index c16b30db73..dfd2820d82 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml @@ -95,26 +95,41 @@ - + + + - + - + - - - + + + + + + + + + + + + + + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 3b4fb52f82..0b7dcb74e0 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -44,80 +44,7 @@ - - - - - - - - - - - org.alfresco.module.org_alfresco_module_rm.RecordsManagementService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java b/rm-server/source/compatibility/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java similarity index 96% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java rename to rm-server/source/compatibility/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java index c577ce8307..c4489f81e2 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java +++ b/rm-server/source/compatibility/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java @@ -39,6 +39,7 @@ import org.alfresco.service.namespace.QName; * Allows simple creation, manipulation and querying of records management components. * * @author Roy Wetherall + * @deprecated as of 2.2 */ public interface RecordsManagementService { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java b/rm-server/source/compatibility/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java similarity index 57% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java rename to rm-server/source/compatibility/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java index b6518affd9..d08a538d52 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java +++ b/rm-server/source/compatibility/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java @@ -20,14 +20,10 @@ package org.alfresco.module.org_alfresco_module_rm; import java.io.Serializable; import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; @@ -37,35 +33,21 @@ import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; import org.alfresco.module.org_alfresco_module_rm.transfer.TransferService; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; -import org.alfresco.repo.policy.Behaviour.NotificationFrequency; -import org.alfresco.repo.policy.JavaBehaviour; -import org.alfresco.repo.policy.PolicyComponent; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.alfresco.util.PropertyMap; -import org.springframework.extensions.surf.util.I18NUtil; /** * Records management service implementation. * * @author Roy Wetherall + * @deprecated as of 2.2 */ public class RecordsManagementServiceImpl extends ServiceBaseImpl implements RecordsManagementService, - RecordsManagementModel //, - //RecordsManagementPolicies.OnCreateReference, - //RecordsManagementPolicies.OnRemoveReference + RecordsManagementModel { - /** I18N */ - private final static String MSG_UPDATE_DISP_ACT_DEF = "rm.service.update-disposition-action-def"; - private final static String MSG_SET_ID = "rm.service.set-id"; - - /** Store that the RM roots are contained within */ + /** Store that the RM roots are contained within */ @SuppressWarnings("unused") @Deprecated private StoreRef defaultStoreRef = StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; @@ -73,15 +55,6 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl /** Service registry */ private RecordsManagementServiceRegistry serviceRegistry; - /** Policy component */ - private PolicyComponent policyComponent; - - ///** Well-known location of the scripts folder. */ - private NodeRef scriptsFolderNodeRef = new NodeRef("workspace", "SpacesStore", "rm_behavior_scripts"); - - /** Java behaviour */ - private JavaBehaviour onChangeToDispositionActionDefinition; - /** * Set the service registry service * @@ -94,16 +67,6 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl this.dictionaryService = serviceRegistry.getDictionaryService(); } - /** - * Set policy component - * - * @param policyComponent policy component - */ - public void setPolicyComponent(PolicyComponent policyComponent) - { - this.policyComponent = policyComponent; - } - /** * Sets the default RM store reference * @param defaultStoreRef store reference @@ -154,22 +117,6 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl return serviceRegistry.getDispositionService(); } - /** - * @return Script Service - */ - private ScriptService getScriptService() - { - return serviceRegistry.getScriptService(); - } - - /** - * @return Namespace service - */ - private NamespaceService getNamespaceService() - { - return serviceRegistry.getNamespaceService(); - } - /** * @return Transfer service */ @@ -178,209 +125,6 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl return serviceRegistry.getTransferService(); } - /** - * Init method. Registered behaviours. - */ - public void init() - { - // Register script execution behaviour on RM property update. - policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), - ASPECT_FILE_PLAN_COMPONENT, - new JavaBehaviour(this, "onChangeToAnyRmProperty", NotificationFrequency.TRANSACTION_COMMIT)); - - // Disposition behaviours - onChangeToDispositionActionDefinition = new JavaBehaviour(this, "onChangeToDispositionActionDefinition", NotificationFrequency.TRANSACTION_COMMIT); - this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), - TYPE_DISPOSITION_ACTION_DEFINITION, - onChangeToDispositionActionDefinition); - - // Identifier behaviours - policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), - ASPECT_RECORD_COMPONENT_ID, - new JavaBehaviour(this, "onIdentifierUpdate", NotificationFrequency.TRANSACTION_COMMIT)); - } - - /** - * Called after a DispositionActionDefinition property has been updated. - */ - public void onChangeToDispositionActionDefinition(NodeRef node, Map oldProps, Map newProps) - { - if (nodeService.exists(node) == true) - { - onChangeToDispositionActionDefinition.disable(); - try - { - // Determine the properties that have changed - Set changedProps = this.determineChangedProps(oldProps, newProps); - - if (nodeService.hasAspect(node, ASPECT_UNPUBLISHED_UPDATE) == false) - { - // Apply the unpublished aspect - Map props = new HashMap(); - props.put(PROP_UPDATE_TO, UPDATE_TO_DISPOSITION_ACTION_DEFINITION); - props.put(PROP_UPDATED_PROPERTIES, (Serializable)changedProps); - nodeService.addAspect(node, ASPECT_UNPUBLISHED_UPDATE, props); - } - else - { - Map props = nodeService.getProperties(node); - - // Check that there isn't a update currently being published - if ((Boolean)props.get(PROP_PUBLISH_IN_PROGRESS).equals(Boolean.TRUE) == true) - { - // Can not update the disposition schedule since there is an outstanding update being published - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UPDATE_DISP_ACT_DEF)); - } - - // Update the update information - props.put(PROP_UPDATE_TO, UPDATE_TO_DISPOSITION_ACTION_DEFINITION); - props.put(PROP_UPDATED_PROPERTIES, (Serializable)changedProps); - nodeService.setProperties(node, props); - } - } - finally - { - onChangeToDispositionActionDefinition.enable(); - } - } - } - - /** - * This method compares the oldProps map against the newProps map and returns - * a set of QNames of the properties that have changed. Changed here means one of - *
    - *
  • the property has been removed
  • - *
  • the property has had its value changed
  • - *
  • the property has been added
  • - *
- */ - private Set determineChangedProps(Map oldProps, Map newProps) - { - Set result = new HashSet(); - for (QName qn : oldProps.keySet()) - { - if (newProps.get(qn) == null || - newProps.get(qn).equals(oldProps.get(qn)) == false) - { - result.add(qn); - } - } - for (QName qn : newProps.keySet()) - { - if (oldProps.get(qn) == null) - { - result.add(qn); - } - } - - return result; - } - - /** - * Called after any Records Management property has been updated. - */ - public void onChangeToAnyRmProperty(final NodeRef node, final Map oldProps, final Map newProps) - { - AuthenticationUtil.runAs(new RunAsWork() - { - @Override - public Void doWork() throws Exception - { - if (nodeService.exists(node) == true) - { - RecordsManagementServiceImpl.this.lookupAndExecuteScripts(node, oldProps, newProps); - } - - return null; - } - }, AuthenticationUtil.getAdminUserName()); - } - - /** - * This method examines the old and new property sets and for those properties which - * have changed, looks for script resources corresponding to those properties. - * Those scripts are then called via the ScriptService. - * - * @param nodeWithChangedProperties the node whose properties have changed. - * @param oldProps the old properties and their values. - * @param newProps the new properties and their values. - * - * @see #lookupScripts(Map, Map) - */ - private void lookupAndExecuteScripts(NodeRef nodeWithChangedProperties, - Map oldProps, Map newProps) - { - List scriptRefs = lookupScripts(oldProps, newProps); - - Map objectModel = new HashMap(1); - objectModel.put("node", nodeWithChangedProperties); - objectModel.put("oldProperties", oldProps); - objectModel.put("newProperties", newProps); - - ScriptService scriptService = getScriptService(); - for (NodeRef scriptRef : scriptRefs) - { - scriptService.executeScript(scriptRef, null, objectModel); - } - } - - /** - * This method determines which properties have changed and for each such property - * looks for a script resource in a well-known location. - * - * @param oldProps the old properties and their values. - * @param newProps the new properties and their values. - * @return A list of nodeRefs corresponding to the Script resources. - * - * @see #determineChangedProps(Map, Map) - */ - private List lookupScripts(Map oldProps, Map newProps) - { - List result = new ArrayList(); - - Map changedProps = PropertyMap.getChangedProperties(oldProps, newProps); - for (QName propQName : changedProps.keySet()) - { - QName prefixedQName = propQName.getPrefixedQName(getNamespaceService()); - - String [] splitQName = QName.splitPrefixedQName(prefixedQName.toPrefixString()); - final String shortPrefix = splitQName[0]; - final String localName = splitQName[1]; - - // This is the filename pattern which is assumed. - // e.g. a script file cm_name.js would be called for changed to cm:name - String expectedScriptName = shortPrefix + "_" + localName + ".js"; - - NodeRef nextElement = nodeService.getChildByName(scriptsFolderNodeRef, ContentModel.ASSOC_CONTAINS, expectedScriptName); - if (nextElement != null) result.add(nextElement); - } - - return result; - } - - /** - * Property update behaviour implementation - * - * @param node - * @param oldProps - * @param newProps - */ - public void onIdentifierUpdate(NodeRef node, Map oldProps, Map newProps) - { - if (nodeService.exists(node) == true) - { - String newIdValue = (String)newProps.get(PROP_IDENTIFIER); - if (newIdValue != null) - { - String oldIdValue = (String)oldProps.get(PROP_IDENTIFIER); - if (oldIdValue != null && oldIdValue.equals(newIdValue) == false) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_SET_ID, node.toString())); - } - } - } - } - /** * @deprecated As of 2.1, see {@link FilePlanService#isFilePlanComponent(NodeRef)} */ diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/BaseBehaviourBean.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/BaseBehaviourBean.java similarity index 91% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/BaseBehaviourBean.java rename to rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/BaseBehaviourBean.java index dca196d4ff..b9f84b3442 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/BaseBehaviourBean.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/BaseBehaviourBean.java @@ -1,9 +1,8 @@ /** * */ -package org.alfresco.module.org_alfresco_module_rm.model.rma; +package org.alfresco.module.org_alfresco_module_rm.model; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.NodeRef; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FilePlanComponentAspect.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FilePlanComponentAspect.java new file mode 100644 index 0000000000..7557205bed --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FilePlanComponentAspect.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2005-2011 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.module.org_alfresco_module_rm.model.rma.aspect; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.ScriptService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.PropertyMap; + +/** + * rma:filePlanComponent behaviour bean + * + * @author Roy Wetherall + * @since 2.2 + */ +@BehaviourBean +( + defaultType = "rma:filePlanComponent" +) +public class FilePlanComponentAspect extends BaseBehaviourBean + implements NodeServicePolicies.OnUpdatePropertiesPolicy + +{ + /** Well-known location of the scripts folder. */ + private NodeRef scriptsFolderNodeRef = new NodeRef("workspace", "SpacesStore", "rm_behavior_scripts"); + + /** script service */ + private ScriptService scriptService; + + /** namespace service */ + private NamespaceService namespaceService; + + /** + * @param scriptService set script service + */ + public void setScriptService(ScriptService scriptService) + { + this.scriptService = scriptService; + } + + /** + * @param namespaceService namespace service + */ + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy#onUpdateProperties(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, java.util.Map) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + ) + public void onUpdateProperties(final NodeRef nodeRef, final Map before, final Map after) + { + AuthenticationUtil.runAs(new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + if (nodeService.exists(nodeRef) == true) + { + lookupAndExecuteScripts(nodeRef, before, after); + } + + return null; + } + }, AuthenticationUtil.getAdminUserName()); + } + + /** + * This method examines the old and new property sets and for those properties which + * have changed, looks for script resources corresponding to those properties. + * Those scripts are then called via the ScriptService. + * + * @param nodeWithChangedProperties the node whose properties have changed. + * @param oldProps the old properties and their values. + * @param newProps the new properties and their values. + * + * @see #lookupScripts(Map, Map) + */ + private void lookupAndExecuteScripts(NodeRef nodeWithChangedProperties, + Map oldProps, + Map newProps) + { + List scriptRefs = lookupScripts(oldProps, newProps); + + Map objectModel = new HashMap(1); + objectModel.put("node", nodeWithChangedProperties); + objectModel.put("oldProperties", oldProps); + objectModel.put("newProperties", newProps); +; + for (NodeRef scriptRef : scriptRefs) + { + scriptService.executeScript(scriptRef, null, objectModel); + } + } + + /** + * This method determines which properties have changed and for each such property + * looks for a script resource in a well-known location. + * + * @param oldProps the old properties and their values. + * @param newProps the new properties and their values. + * @return A list of nodeRefs corresponding to the Script resources. + * + * @see #determineChangedProps(Map, Map) + */ + private List lookupScripts(Map oldProps, Map newProps) + { + List result = new ArrayList(); + + Map changedProps = PropertyMap.getChangedProperties(oldProps, newProps); + for (QName propQName : changedProps.keySet()) + { + QName prefixedQName = propQName.getPrefixedQName(namespaceService); + + String [] splitQName = QName.splitPrefixedQName(prefixedQName.toPrefixString()); + final String shortPrefix = splitQName[0]; + final String localName = splitQName[1]; + + // This is the filename pattern which is assumed. + // e.g. a script file cm_name.js would be called for changed to cm:name + String expectedScriptName = shortPrefix + "_" + localName + ".js"; + + NodeRef nextElement = nodeService.getChildByName(scriptsFolderNodeRef, ContentModel.ASSOC_CONTAINS, expectedScriptName); + if (nextElement != null) result.add(nextElement); + } + + return result; + } + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordAspect.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java similarity index 95% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordAspect.java rename to rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java index 49ec89b950..eb4c32f17f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordAspect.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.model.rma; +package org.alfresco.module.org_alfresco_module_rm.model.rma.aspect; import java.util.HashMap; import java.util.Map; @@ -24,6 +24,7 @@ import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies; +import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; import org.alfresco.repo.node.NodeServicePolicies; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java new file mode 100644 index 0000000000..1c841a8d43 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2005-2011 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.module.org_alfresco_module_rm.model.rma.aspect; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.surf.util.I18NUtil; + +/** + * rma:recordComponentIdentifier behaviour bean + * + * @author Roy Wetherall + * @since 2.2 + */ +@BehaviourBean +( + defaultType = "rma:recordComponentIdentifier" +) +public class RecordComponentIdentifierAspect extends BaseBehaviourBean + implements NodeServicePolicies.OnUpdatePropertiesPolicy +{ + /** I18N */ + private final static String MSG_SET_ID = "rm.service.set-id"; + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy#onUpdateProperties(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, java.util.Map) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + ) + public void onUpdateProperties(NodeRef nodeRef, Map before, Map after) + { + if (nodeService.exists(nodeRef) == true) + { + String newIdValue = (String)after.get(PROP_IDENTIFIER); + if (newIdValue != null) + { + String oldIdValue = (String)before.get(PROP_IDENTIFIER); + if (oldIdValue != null && oldIdValue.equals(newIdValue) == false) + { + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_SET_ID, nodeRef.toString())); + } + } + } + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/DispositionActionDefinitionType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/DispositionActionDefinitionType.java new file mode 100644 index 0000000000..70cdac423c --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/DispositionActionDefinitionType.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2005-2011 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.module.org_alfresco_module_rm.model.rma.type; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.PropertyMap; +import org.springframework.extensions.surf.util.I18NUtil; + +/** + * rma:dispositionActionDefinition behaviour bean + * + * @author Roy Wetherall + * @since 2.2 + */ +@BehaviourBean +( + defaultType = "rma:dispositionActionDefinition" +) +public class DispositionActionDefinitionType extends BaseBehaviourBean + implements NodeServicePolicies.OnUpdatePropertiesPolicy +{ + /** I18N */ + private final static String MSG_UPDATE_DISP_ACT_DEF = "rm.service.update-disposition-action-def"; + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy#onUpdateProperties(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, java.util.Map) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + ) + public void onUpdateProperties(NodeRef nodeRef, Map before, Map after) + { + if (nodeService.exists(nodeRef) == true) + { + // Determine the properties that have changed + Set changedProps = new HashSet(PropertyMap.getChangedProperties(before, after).keySet()); + changedProps.addAll(PropertyMap.getAddedProperties(before, after).keySet()); + + if (nodeService.hasAspect(nodeRef, ASPECT_UNPUBLISHED_UPDATE) == false) + { + // Apply the unpublished aspect + Map props = new HashMap(); + props.put(PROP_UPDATE_TO, UPDATE_TO_DISPOSITION_ACTION_DEFINITION); + props.put(PROP_UPDATED_PROPERTIES, (Serializable)changedProps); + nodeService.addAspect(nodeRef, ASPECT_UNPUBLISHED_UPDATE, props); + } + else + { + Map props = nodeService.getProperties(nodeRef); + + // Check that there isn't a update currently being published + if ((Boolean)props.get(PROP_PUBLISH_IN_PROGRESS).equals(Boolean.TRUE) == true) + { + // Can not update the disposition schedule since there is an outstanding update being published + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UPDATE_DISP_ACT_DEF)); + } + + // Update the update information + props.put(PROP_UPDATE_TO, UPDATE_TO_DISPOSITION_ACTION_DEFINITION); + props.put(PROP_UPDATED_PROPERTIES, (Serializable)changedProps); + nodeService.setProperties(nodeRef, props); + } + } + + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/FilePlanType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/FilePlanType.java similarity index 95% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/FilePlanType.java rename to rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/FilePlanType.java index 64f379a3d9..3d1c655d5e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/FilePlanType.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/FilePlanType.java @@ -16,12 +16,13 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.model.rma; +package org.alfresco.module.org_alfresco_module_rm.model.rma.type; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; +import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordCategoryType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordCategoryType.java similarity index 95% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordCategoryType.java rename to rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordCategoryType.java index 433387207e..a2c4e3a01e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordCategoryType.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordCategoryType.java @@ -16,10 +16,11 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.model.rma; +package org.alfresco.module.org_alfresco_module_rm.model.rma.type; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService; import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService; import org.alfresco.repo.copy.CopyBehaviourCallback; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordsManagementContainerType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java similarity index 95% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordsManagementContainerType.java rename to rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java index d37400cf78..5b3da151b4 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/RecordsManagementContainerType.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java @@ -16,10 +16,11 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.model.rma; +package org.alfresco.module.org_alfresco_module_rm.model.rma.type; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; +import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; diff --git a/rm-server/source/java/org/alfresco/repo/policy/annotation/AnnotatedBehaviourPostProcessor.java b/rm-server/source/java/org/alfresco/repo/policy/annotation/AnnotatedBehaviourPostProcessor.java index 40760fcd18..84b0b56189 100644 --- a/rm-server/source/java/org/alfresco/repo/policy/annotation/AnnotatedBehaviourPostProcessor.java +++ b/rm-server/source/java/org/alfresco/repo/policy/annotation/AnnotatedBehaviourPostProcessor.java @@ -114,6 +114,7 @@ public class AnnotatedBehaviourPostProcessor implements BeanPostProcessor } /** + * Register behaviour with the policy. * * @param bean * @param beanName