From 382a14adce28d3489436dc38c1dfc6ac7110da22 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Thu, 24 Mar 2016 18:30:52 +1100 Subject: [PATCH 01/33] Update release version to 2.2.1.5 --- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index 058f832baf..b2574838d3 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.2.1.4 +module.version=2.2.1.5 module.repo.version.min=4.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index afc57ed519..d25d5d2c59 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.2.1.4 + 2.2.1.5 4.0.0 alfresco-rm-server From a40aa2af338e73d98e2cf765e7b0ff2418fbe143 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 29 Mar 2016 13:09:56 +1100 Subject: [PATCH 02/33] RM-3114: Prevent access to custom map before it is ready - remove public init method from AdministrationService - make admin service impl ordered listener, always goes last - protect execution of service behaviours until custom map init'ed --- .gitignore | 1 + .../org_alfresco_module_rm/module-context.xml | 1 - .../rm-service-context.xml | 1 - .../admin/RecordsManagementAdminService.java | 5 - .../RecordsManagementAdminServiceImpl.java | 323 ++++++++++-------- .../bootstrap/RecordsManagementBootstrap.java | 12 +- 6 files changed, 185 insertions(+), 158 deletions(-) diff --git a/.gitignore b/.gitignore index 24be3fc3c1..4a0930f9db 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ test-output /rm-server/alfresco-solr.zip /rm-server/solr /rm-server/shared +/rm-server/alf_data # /rm-server/config/ /rm-server/config/alfresco-global.properties diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml index 1b1674c29f..4368604dde 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml @@ -168,7 +168,6 @@ - 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 4057ea3e2d..54cd8dda2e 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 @@ -813,7 +813,6 @@ , + Ordered { /** Logger */ private static Log logger = LogFactory.getLog(RecordsManagementAdminServiceImpl.class); @@ -162,6 +167,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin /** List of types that can be customisable */ private List pendingCustomisableTypes; private Map customisableTypes; + + /** indicates whether the custom map has been initialised or not */ + private boolean isCustomMapInit = false; /** * @param dictionaryService the dictionary service @@ -223,15 +231,39 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin onCreateReferenceDelegate = policyComponent.registerClassPolicy(OnCreateReference.class); beforeRemoveReferenceDelegate = policyComponent.registerClassPolicy(BeforeRemoveReference.class); onRemoveReferenceDelegate = policyComponent.registerClassPolicy(OnRemoveReference.class); + } + + /** + * Indicate that this application content listener must be executed with the highest + * precedence. + * + * @see Ordered#getOrder() + */ + @Override + public int getOrder() + { + return Ordered.LOWEST_PRECEDENCE; + } + + /** + * Load the custom properties map + * + * @see ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + @Override + public void onApplicationEvent(ContextRefreshedEvent event) + { + // initialise custom properties + initCustomMap(); } /** - * Invoke before create reference policy - * - * @param fromNodeRef - * @param toNodeRef - * @param reference - */ + * Invoke before create reference policy + * + * @param fromNodeRef + * @param toNodeRef + * @param reference + */ protected void invokeBeforeCreateReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) { // get qnames to invoke against @@ -301,22 +333,25 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onAddAspect(final NodeRef nodeRef, final QName aspectTypeQName) { - AuthenticationUtil.runAs(new RunAsWork() + if (isCustomMapInit) { - @Override - public Void doWork() + AuthenticationUtil.runAs(new RunAsWork() { - if (nodeService.exists(nodeRef) && - dictionaryService.getAllModels().contains(RM_CUSTOM_MODEL) && - isCustomisable(aspectTypeQName)) + @Override + public Void doWork() { - QName customPropertyAspect = getCustomAspect(aspectTypeQName); - nodeService.addAspect(nodeRef, customPropertyAspect, null); + if (nodeService.exists(nodeRef) && + dictionaryService.getAllModels().contains(RM_CUSTOM_MODEL) && + isCustomisable(aspectTypeQName)) + { + QName customPropertyAspect = getCustomAspect(aspectTypeQName); + nodeService.addAspect(nodeRef, customPropertyAspect, null); + } + + return null; } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); + }, AuthenticationUtil.getSystemUserName()); + } } /** @@ -331,21 +366,24 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onRemoveAspect(final NodeRef nodeRef, final QName aspectTypeQName) { - AuthenticationUtil.runAs(new RunAsWork() + if (isCustomMapInit) { - @Override - public Void doWork() + AuthenticationUtil.runAs(new RunAsWork() { - if (nodeService.exists(nodeRef) && - isCustomisable(aspectTypeQName)) + @Override + public Void doWork() { - QName customPropertyAspect = getCustomAspect(aspectTypeQName); - nodeService.removeAspect(nodeRef, customPropertyAspect); + if (nodeService.exists(nodeRef) && + isCustomisable(aspectTypeQName)) + { + QName customPropertyAspect = getCustomAspect(aspectTypeQName); + nodeService.removeAspect(nodeRef, customPropertyAspect); + } + + return null; } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); + }, AuthenticationUtil.getSystemUserName()); + } } /** @@ -362,47 +400,41 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onCreateNode(final ChildAssociationRef childAssocRef) { - AuthenticationUtil.runAs(new RunAsWork() - { - @Override - public Void doWork() + if (isCustomMapInit) + { + AuthenticationUtil.runAs(new RunAsWork() { - if (dictionaryService.getAllModels().contains(RecordsManagementCustomModel.RM_CUSTOM_MODEL)) + @Override + public Void doWork() { - NodeRef nodeRef = childAssocRef.getChildRef(); - QName type = nodeService.getType(nodeRef); - while (type != null && !ContentModel.TYPE_CMOBJECT.equals(type)) + if (dictionaryService.getAllModels().contains(RecordsManagementCustomModel.RM_CUSTOM_MODEL)) { - if (isCustomisable(type)) + NodeRef nodeRef = childAssocRef.getChildRef(); + QName type = nodeService.getType(nodeRef); + while (type != null && !ContentModel.TYPE_CMOBJECT.equals(type)) { - QName customPropertyAspect = getCustomAspect(type); - nodeService.addAspect(nodeRef, customPropertyAspect, null); - } - - TypeDefinition def = dictionaryService.getType(type); - if (def != null) - { - type = def.getParentName(); - } - else - { - type = null; + if (isCustomisable(type)) + { + QName customPropertyAspect = getCustomAspect(type); + nodeService.addAspect(nodeRef, customPropertyAspect, null); + } + + TypeDefinition def = dictionaryService.getType(type); + if (def != null) + { + type = def.getParentName(); + } + else + { + type = null; + } } } + + return null; } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementAdminService#initialiseCustomModel() - */ - public void initialiseCustomModel() - { - // Initialise the map - getCustomisableMap(); + }, AuthenticationUtil.getSystemUserName()); + } } /** @@ -483,6 +515,92 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin return result; } + + /** + * Initialise custom type map + */ + private void initCustomMap() + { + customisableTypes = new HashMap(7); + Collection aspects = dictionaryService.getAspects(RM_CUSTOM_MODEL); + for (QName aspect : aspects) + { + AspectDefinition aspectDef = dictionaryService.getAspect(aspect); + String name = aspectDef.getName().getLocalName(); + if (name.endsWith("Properties")) + { + QName type = null; + String prefixString = aspectDef.getDescription(dictionaryService); + if (prefixString == null) + { + // Backward compatibility from previous RM V1.0 custom models + if (CompatibilityModel.NAME_CUSTOM_RECORD_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.ASPECT_RECORD; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_FOLDER_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.TYPE_RECORD_FOLDER; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_CATEGORY_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.TYPE_RECORD_CATEGORY; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_SERIES_PROPERTIES.equals(name) && + // Only add the deprecated record series type as customisable if + // a v1.0 installation has added custom properties + aspectDef.getProperties().size() != 0) + { + type = CompatibilityModel.TYPE_RECORD_SERIES; + } + } + else + { + type = QName.createQName(prefixString, namespaceService); + } + + // Add the customisable type to the map + if (type != null) + { + customisableTypes.put(type, aspect); + + // Remove customisable type from the pending list + if (pendingCustomisableTypes != null && pendingCustomisableTypes.contains(type)) + { + pendingCustomisableTypes.remove(type); + } + } + } + } + + // Deal with any pending types left over + if (pendingCustomisableTypes != null && pendingCustomisableTypes.size() != 0) + { + NodeRef modelRef = getCustomModelRef(RecordsManagementModel.RM_CUSTOM_URI); + M2Model model = readCustomContentModel(modelRef); + try + { + for (QName customisableType : pendingCustomisableTypes) + { + QName customAspect = getCustomAspectImpl(customisableType); + + // Create the new aspect to hold the custom properties + M2Aspect aspect = model.createAspect(customAspect.toPrefixString(namespaceService)); + aspect.setDescription(customisableType.toPrefixString(namespaceService)); + + // Make a record of the customisable type + customisableTypes.put(customisableType, customAspect); + } + } + finally + { + writeCustomContentModel(modelRef, model); + } + } + + // indicate map is initialised + isCustomMapInit = true; + } /** * Gets a map containing all the customisable types @@ -493,82 +611,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin { if (customisableTypes == null) { - customisableTypes = new HashMap(7); - Collection aspects = dictionaryService.getAspects(RM_CUSTOM_MODEL); - for (QName aspect : aspects) - { - AspectDefinition aspectDef = dictionaryService.getAspect(aspect); - String name = aspectDef.getName().getLocalName(); - if (name.endsWith("Properties")) - { - QName type = null; - String prefixString = aspectDef.getDescription(dictionaryService); - if (prefixString == null) - { - // Backward compatibility from previous RM V1.0 custom models - if (CompatibilityModel.NAME_CUSTOM_RECORD_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.ASPECT_RECORD; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_FOLDER_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.TYPE_RECORD_FOLDER; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_CATEGORY_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.TYPE_RECORD_CATEGORY; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_SERIES_PROPERTIES.equals(name) && - // Only add the deprecated record series type as customisable if - // a v1.0 installation has added custom properties - aspectDef.getProperties().size() != 0) - { - type = CompatibilityModel.TYPE_RECORD_SERIES; - } - } - else - { - type = QName.createQName(prefixString, namespaceService); - } - - // Add the customisable type to the map - if (type != null) - { - customisableTypes.put(type, aspect); - - // Remove customisable type from the pending list - if (pendingCustomisableTypes != null && pendingCustomisableTypes.contains(type)) - { - pendingCustomisableTypes.remove(type); - } - } - } - } - - // Deal with any pending types left over - if (pendingCustomisableTypes != null && pendingCustomisableTypes.size() != 0) - { - NodeRef modelRef = getCustomModelRef(RecordsManagementModel.RM_CUSTOM_URI); - M2Model model = readCustomContentModel(modelRef); - try - { - for (QName customisableType : pendingCustomisableTypes) - { - QName customAspect = getCustomAspectImpl(customisableType); - - // Create the new aspect to hold the custom properties - M2Aspect aspect = model.createAspect(customAspect.toPrefixString(namespaceService)); - aspect.setDescription(customisableType.toPrefixString(namespaceService)); - - // Make a record of the customisable type - customisableTypes.put(customisableType, customAspect); - } - } - finally - { - writeCustomContentModel(modelRef, model); - } - } + throw AlfrescoRuntimeException.create("Customisable map has not been initialised correctly."); } return customisableTypes; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java index 295059ead3..f681b9ef3a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java @@ -18,7 +18,6 @@ */ package org.alfresco.module.org_alfresco_module_rm.bootstrap; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.action.impl.SplitEmailAction; import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigService; import org.alfresco.module.org_alfresco_module_rm.email.CustomEmailMappingService; @@ -40,8 +39,7 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean private TransactionService transactionService; private RMCaveatConfigService caveatConfigService; private CustomEmailMappingService customEmailMappingService; - private RecordsManagementAdminService adminService; - + public void setTransactionService(TransactionService transactionService) { this.transactionService = transactionService; @@ -57,11 +55,6 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean this.customEmailMappingService = customEmailMappingService; } - public void setRecordsManagementAdminService(RecordsManagementAdminService adminService) - { - this.adminService = adminService; - } - public CustomEmailMappingService getCustomEmailMappingService() { return customEmailMappingService; @@ -82,9 +75,6 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean // initialise caveat config caveatConfigService.init(); - // Initialise the custom model - adminService.initialiseCustomModel(); - // Initialise the SplitEmailAction SplitEmailAction action = (SplitEmailAction)getApplicationContext().getBean("splitEmail"); action.bootstrap(); From bd39de53a1a12217a3c2996ef1ecd9d1ea16722e Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 30 Mar 2016 09:32:28 +1100 Subject: [PATCH 03/33] RM-3114 - Integration tests --- .../rm-service-context.xml | 1 + .../RecordsManagementAdminServiceImpl.java | 35 ++++- .../integration/issue/IssueTestSuite.java | 4 +- .../integration/issue/rm3314/RM3314Test.java | 52 +++++++ .../issue/rm3314/RM3314TestListener.java | 134 ++++++++++++++++++ rm-server/test/resources/test-context.xml | 17 +++ 6 files changed, 240 insertions(+), 3 deletions(-) create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java 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 54cd8dda2e..cc67b45a97 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 @@ -770,6 +770,7 @@ + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java index 79837871e2..66e1f803a0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java @@ -63,6 +63,7 @@ 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.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.Constraint; @@ -83,6 +84,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.GUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -157,6 +159,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin /** Policy component */ private PolicyComponent policyComponent; + + /** Transaction service */ + private TransactionService transactionService; /** Policy delegates */ private ClassPolicyDelegate beforeCreateReferenceDelegate; @@ -220,6 +225,14 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin { this.dictonaryRepositoryBootstrap = dictonaryRepositoryBootstrap; } + + /** + * @param transactionService transaction service + */ + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } /** * Initialisation method @@ -253,8 +266,26 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin @Override public void onApplicationEvent(ContextRefreshedEvent event) { - // initialise custom properties - initCustomMap(); + transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + // initialise custom properties + initCustomMap(); + + return null; + } + }); + } + + /** + * Helper method to indicate whether the custom map is initialised or not. + * + * @return boolean true if initialised, false otherwise + */ + public boolean isCustomMapInit() + { + return isCustomMapInit; } /** diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java index 8c52e12ea1..2b86c45bf6 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java @@ -18,6 +18,7 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; +import org.alfresco.module.org_alfresco_module_rm.test.integration.issue.rm3314.RM3314Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @@ -44,7 +45,8 @@ import org.junit.runners.Suite.SuiteClasses; RM1039Test.class, RM1799Test.class, //RM2190Test.class, - RM2192Test.class + RM2192Test.class, + RM3314Test.class }) public class IssueTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java new file mode 100644 index 0000000000..89911e5fab --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2014 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.test.integration.issue.rm3314; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; + +/** + * Test for https://issues.alfresco.com/jira/browse/RM-3114 + * + * @author Roy Wetherall + * @since 2.2.1.5 + */ +public class RM3314Test extends BaseRMTestCase +{ + public static Map callback = new HashMap(2); + + /** + * Given that the custom model hasn't been initialised + * When an aspect is added + * Then nothing happens + * + * Given that the custom model has been initialised + * When an aspect is added + * Then something happens + */ + public void testListenersExecutedInTheCorrectOrder() + { + assertFalse(callback.isEmpty()); + assertFalse(callback.get("test.rm3314.1")); + assertTrue(callback.get("test.rm3314.2")); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java new file mode 100644 index 0000000000..d162d0fe95 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2005-2014 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.test.integration.issue.rm3314; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl; +import org.alfresco.repo.model.Repository; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.Ordered; +import org.springframework.jdbc.BadSqlGrammarException; + +/** + * Simple bean used to test RM-3314 + * + * @author rwetherall + * @since 2.2.1.5 + */ +public class RM3314TestListener implements ApplicationListener, + Ordered, + BeanNameAware +{ + private RecordsManagementAdminServiceImpl recordsManagementAdminService; + private NodeService nodeService; + private FileFolderService fileFolderService; + private Repository repository; + + private String name; + private int order = Ordered.LOWEST_PRECEDENCE; + + public void setRecordsManagementAdminService(RecordsManagementAdminServiceImpl recordsManagementAdminService) + { + this.recordsManagementAdminService = recordsManagementAdminService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setFileFolderService(FileFolderService fileFolderService) + { + this.fileFolderService = fileFolderService; + } + + public void setRepository(Repository repository) + { + this.repository = repository; + } + + @Override + public void setBeanName(String name) + { + this.name = name; + } + + public void setOrder(int order) + { + this.order = order; + } + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) + { + // call back to show whether the custom map is initialised or not + RM3314Test.callback.put(name, recordsManagementAdminService.isCustomMapInit()); + + // Do some work on a node to show that reguardless of whether the custom map is + // init or not, things still work. + // Note: using public services to ensure new transaction for each service call + AuthenticationUtil.runAsSystem(new RunAsWork() + { + public Void doWork() throws Exception + { + try + { + // create node + NodeRef folder = fileFolderService.create( + repository.getCompanyHome(), + name, + ContentModel.TYPE_FOLDER).getNodeRef(); + try + { + // add aspect + nodeService.addAspect(folder, ContentModel.ASPECT_CLASSIFIABLE, null); + + // remove aspect + nodeService.removeAspect(folder, ContentModel.ASPECT_CLASSIFIABLE); + } + finally + { + // delete node + nodeService.deleteNode(folder); + } + } + catch (BadSqlGrammarException e) + { + // ignore and carry on + } + + return null; + } + }); + } + + @Override + public int getOrder() + { + return order; + } +} diff --git a/rm-server/test/resources/test-context.xml b/rm-server/test/resources/test-context.xml index a5396c0b50..d0f608937c 100644 --- a/rm-server/test/resources/test-context.xml +++ b/rm-server/test/resources/test-context.xml @@ -240,4 +240,21 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From 57e5d1d237d2619d30dc9aaebe24fa0783c7ec98 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 12 Apr 2016 09:21:45 -0400 Subject: [PATCH 04/33] RM-3114 - review comments --- .../admin/RecordsManagementAdminServiceImpl.java | 4 ++-- .../test/integration/issue/rm3314/RM3314Test.java | 11 ++++++++++- rm-server/test/resources/test-context.xml | 4 ++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java index 66e1f803a0..cc3f7d043b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java @@ -247,8 +247,8 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } /** - * Indicate that this application content listener must be executed with the highest - * precedence. + * Indicate that this application content listener must be executed with the lowest + * precedence. (ie last) * * @see Ordered#getOrder() */ diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java index 89911e5fab..7bc0a982bf 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2014 Alfresco Software Limited. + * Copyright (C) 2005-2016 Alfresco Software Limited. * * This file is part of Alfresco * @@ -32,6 +32,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; */ public class RM3314Test extends BaseRMTestCase { + /** registry to record callback from test beans "test.rm3114.1" and "test.rm3114.2" */ public static Map callback = new HashMap(2); /** @@ -45,6 +46,14 @@ public class RM3314Test extends BaseRMTestCase */ public void testListenersExecutedInTheCorrectOrder() { + /** + * The related test beans will call back into the callback map showing + * whether at the end of their execution whether the custom model has been + * initialised or not. Given the order in which these test beans are executed + * on spring context load, we would expect that .1 executes with the custom + * map unloaded, and the .2 with it loaded. + */ + assertFalse(callback.isEmpty()); assertFalse(callback.get("test.rm3314.1")); assertTrue(callback.get("test.rm3314.2")); diff --git a/rm-server/test/resources/test-context.xml b/rm-server/test/resources/test-context.xml index d0f608937c..6112260cb4 100644 --- a/rm-server/test/resources/test-context.xml +++ b/rm-server/test/resources/test-context.xml @@ -242,6 +242,8 @@ + @@ -250,6 +252,8 @@ + From 675b96ea73918cc7511aa5d0f32e7039226b1d93 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 12 Apr 2016 09:26:01 -0400 Subject: [PATCH 05/33] RM-3114 - update version in POMs --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b7ca9eae6f..a8a346f0db 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.2.1.4 + 2.2.1.5 Alfresco Records Management http://www.alfresco.org/ From 8fcf835c6eac699a5939b480b0bc895c6fc8e2eb Mon Sep 17 00:00:00 2001 From: David Webster Date: Mon, 25 Apr 2016 09:39:44 +0100 Subject: [PATCH 06/33] Version bump to 2.4.0.1-SNAPSHOT for hot fix branch --- pom.xml | 2 +- rm-automation/pom.xml | 2 +- rm-community/pom.xml | 2 +- rm-community/rm-community-repo/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 293caa8b57..5103d758ef 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm pom - 2.4.1-SNAPSHOT + 2.4.0.1-SNAPSHOT Alfresco Records Management diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index 0001b8d226..b794a5e350 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.4.1-SNAPSHOT + 2.4.0.1-SNAPSHOT diff --git a/rm-community/pom.xml b/rm-community/pom.xml index 1653aa3cd3..75623a5acc 100644 --- a/rm-community/pom.xml +++ b/rm-community/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.4.1-SNAPSHOT + 2.4.0.1-SNAPSHOT diff --git a/rm-community/rm-community-repo/pom.xml b/rm-community/rm-community-repo/pom.xml index 8558f5cefd..1d6437cf4d 100644 --- a/rm-community/rm-community-repo/pom.xml +++ b/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm-community - 2.4.1-SNAPSHOT + 2.4.0.1-SNAPSHOT From 56190f0cb11840ae1d773fbd53ced19111ea7535 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu Date: Mon, 25 Apr 2016 11:55:53 +0300 Subject: [PATCH 07/33] RM-3300 - on versioning, document can be declared as record if adding record and version aspect is run as System --- .../version/RecordableVersionServiceImpl.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java index 845c1d3117..b92d66db22 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java @@ -393,7 +393,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl final NodeRef record = recordService.createRecordFromCopy(filePlan, nodeRef); // apply version record aspect to record - PropertyMap versionRecordProps = new PropertyMap(3); + final PropertyMap versionRecordProps = new PropertyMap(3); versionRecordProps.put(PROP_VERSIONED_NODEREF, nodeRef); versionRecordProps.put(RecordableVersionModel.PROP_VERSION_LABEL, standardVersionProperties.get( @@ -403,7 +403,15 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl standardVersionProperties.get( QName.createQName(Version2Model.NAMESPACE_URI, Version2Model.PROP_VERSION_DESCRIPTION))); - nodeService.addAspect(record, ASPECT_VERSION_RECORD, versionRecordProps); + authenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + nodeService.addAspect(record, ASPECT_VERSION_RECORD, versionRecordProps); + return null; + } + }); // wire record up to previous record linkToPreviousVersionRecord(nodeRef, record); From 1c7e75c1b33f5134675c75eacf20225ed4e2356c Mon Sep 17 00:00:00 2001 From: Roxana Lucanu Date: Tue, 26 Apr 2016 18:06:11 +0300 Subject: [PATCH 08/33] RM-3060 - making cut Off action available for record linked to folder with the same disposition schedule --- .../disposition/DispositionServiceImpl.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index 95f0aae459..04455015dd 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -889,6 +889,13 @@ public class DispositionServiceImpl extends ServiceBaseImpl // Get the current action String currentADId = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION_ID); currentDispositionActionDefinition = di.getDispositionActionDefinition(currentADId); + // When the record has multiple disposition schedules the current disposition action may not be found by id + // In this case it will be searched by name + if(currentDispositionActionDefinition == null) + { + String currentADName = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION); + currentDispositionActionDefinition = di.getDispositionActionDefinitionByName(currentADName); + } // Get the next disposition action int index = currentDispositionActionDefinition.getIndex(); From 8372b82d42de906d888940271b02983cb553e5ee Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Tue, 10 May 2016 15:09:57 +0300 Subject: [PATCH 09/33] Update version to 2.3.0.4 --- pom.xml | 2 +- rm-automation/pom.xml | 2 +- rm-server/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 5c3cc82443..0acec60abe 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.3.0.4-SNAPSHOT + 2.3.0.4 Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index d4cd98b4f6..84ee9d8c12 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -3,7 +3,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.4-SNAPSHOT + 2.3.0.4 4.0.0 alfresco-rm-automation diff --git a/rm-server/pom.xml b/rm-server/pom.xml index d97aebcbab..7bc9743488 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.4-SNAPSHOT + 2.3.0.4 4.0.0 alfresco-rm-server From e901666d3fc32beb1145b9dc47c805966204790a Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Tue, 10 May 2016 15:17:33 +0300 Subject: [PATCH 10/33] Update version to 2.3.0.5-SNAPSHOT --- pom.xml | 2 +- rm-automation/pom.xml | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0acec60abe..664c2b527e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.3.0.4 + 2.3.0.5-SNAPSHOT Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index 84ee9d8c12..ac1b30c5d4 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -3,7 +3,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.4 + 2.3.0.5-SNAPSHOT 4.0.0 alfresco-rm-automation diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index 66e12dcdfc..9bb4904d05 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.3.0.4 +module.version=2.3.0.5 module.repo.version.min=4.2.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index 7bc9743488..7e4877e37b 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.4 + 2.3.0.5-SNAPSHOT 4.0.0 alfresco-rm-server From 84d63650c18d4bfb978c59a21969bde8e529a231 Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Tue, 10 May 2016 15:18:33 +0300 Subject: [PATCH 11/33] Revert "Update version to 2.3.0.5-SNAPSHOT" This reverts commit e901666d3fc32beb1145b9dc47c805966204790a. --- pom.xml | 2 +- rm-automation/pom.xml | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 664c2b527e..0acec60abe 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.3.0.5-SNAPSHOT + 2.3.0.4 Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index ac1b30c5d4..84ee9d8c12 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -3,7 +3,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.5-SNAPSHOT + 2.3.0.4 4.0.0 alfresco-rm-automation diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index 9bb4904d05..66e12dcdfc 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.3.0.5 +module.version=2.3.0.4 module.repo.version.min=4.2.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index 7e4877e37b..7bc9743488 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.5-SNAPSHOT + 2.3.0.4 4.0.0 alfresco-rm-server From 9f00a4c8211850eae04570f5f868d3e3c95ff5cb Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Tue, 10 May 2016 15:17:33 +0300 Subject: [PATCH 12/33] Update version to 2.3.0.5-SNAPSHOT --- pom.xml | 2 +- rm-automation/pom.xml | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0acec60abe..664c2b527e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.3.0.4 + 2.3.0.5-SNAPSHOT Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index 84ee9d8c12..ac1b30c5d4 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -3,7 +3,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.4 + 2.3.0.5-SNAPSHOT 4.0.0 alfresco-rm-automation diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index 66e12dcdfc..9bb4904d05 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.3.0.4 +module.version=2.3.0.5 module.repo.version.min=4.2.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index 7bc9743488..7e4877e37b 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.4 + 2.3.0.5-SNAPSHOT 4.0.0 alfresco-rm-server From fe79f0362f9e5bf82c0893f55352632ddaae4064 Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Tue, 10 May 2016 15:09:57 +0300 Subject: [PATCH 13/33] Update version to 2.3.0.5 --- pom.xml | 2 +- rm-automation/pom.xml | 2 +- rm-server/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 664c2b527e..4e6170ff58 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.3.0.5-SNAPSHOT + 2.3.0.5 Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index ac1b30c5d4..b41d1323b3 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -3,7 +3,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.5-SNAPSHOT + 2.3.0.5 4.0.0 alfresco-rm-automation diff --git a/rm-server/pom.xml b/rm-server/pom.xml index 7e4877e37b..ebe284c4dc 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.5-SNAPSHOT + 2.3.0.5 4.0.0 alfresco-rm-server From a9d32dd8f092d65d84a14aeded22366f6df8f7a9 Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Tue, 10 May 2016 19:54:29 +0300 Subject: [PATCH 14/33] Update version to 2.3.0.6-SNAPSHOT --- pom.xml | 2 +- rm-automation/pom.xml | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 4e6170ff58..227f21c7ad 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.3.0.5 + 2.3.0.6-SNAPSHOT Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index b41d1323b3..ae3e5aa022 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -3,7 +3,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.5 + 2.3.0.6-SNAPSHOT 4.0.0 alfresco-rm-automation diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index 9bb4904d05..6ba5887b4e 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.3.0.5 +module.version=2.3.0.6 module.repo.version.min=4.2.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index ebe284c4dc..67736697db 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.3.0.5 + 2.3.0.6-SNAPSHOT 4.0.0 alfresco-rm-server From 22d7efe18fee9ed0fa51e178680be116244f4de2 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu Date: Mon, 16 May 2016 17:25:39 +0300 Subject: [PATCH 15/33] Updated version to 2.2.1.6-SNAPSHOT --- pom.xml | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a8a346f0db..39fdb13a41 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.2.1.5 + 2.2.1.6-SNAPSHOT Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index b2574838d3..427022be0f 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.2.1.5 +module.version=2.2.1.6 module.repo.version.min=4.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index d25d5d2c59..f836866d99 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.2.1.5 + 2.2.1.6-SNAPSHOT 4.0.0 alfresco-rm-server From 51c7b1b59cb47bb4dd61a32ebf8defc1d698fd87 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu Date: Tue, 17 May 2016 12:13:42 +0300 Subject: [PATCH 16/33] Added unit test --- .../version/RecordableVersionServiceImpl.java | 1 + .../DeclareVersionAsRecordActionTest.java | 115 ++++++++++++++++++ .../test/util/BaseRMTestCase.java | 6 + 3 files changed, 122 insertions(+) create mode 100644 rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java index b92d66db22..4ebfc07cf8 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java @@ -403,6 +403,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl standardVersionProperties.get( QName.createQName(Version2Model.NAMESPACE_URI, Version2Model.PROP_VERSION_DESCRIPTION))); + // run as system as we can't be sure if the user has add aspect rights authenticationUtil.runAsSystem(new RunAsWork() { @Override diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java new file mode 100644 index 0000000000..07e921fe65 --- /dev/null +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java @@ -0,0 +1,115 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * 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 . + * #L% + */ +package org.alfresco.module.org_alfresco_module_rm.test.legacy.action; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction; +import org.alfresco.module.org_alfresco_module_rm.action.dm.DeclareAsVersionRecordAction; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl; +import org.alfresco.repo.version.VersionModel; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.Rule; +import org.alfresco.service.cmr.rule.RuleService; +import org.alfresco.service.cmr.rule.RuleType; +import org.alfresco.service.cmr.version.Version; +import org.alfresco.service.cmr.version.VersionType; + +public class DeclareVersionAsRecordActionTest extends BaseRMTestCase +{ + private RuleService ruleService; + private NodeRef ruleFile; + protected static final String DESCRIPTION = "description"; + + @Override + protected void initServices() + { + super.initServices(); + + ruleService = (RuleService)applicationContext.getBean("RuleService"); + } + + @Override + protected boolean isCollaborationSiteTest() + { + return true; + } + + @Override + protected boolean isRecordTest() + { + return true; + } + + /** + * Given a node set to auto-declare documents as records for minor and major versions + * When I try to upload a minor or major version + * Then the version record aspect is added + */ + public void testAutoDeclareVersionAsRecord() + { + doTestInTransaction(new Test() + { + public Void run() + { + // create the file + ruleFile = fileFolderService.create(documentLibrary, "mytestfile", ContentModel.TYPE_CONTENT).getNodeRef(); + + Action action = actionService.createAction(DeclareAsVersionRecordAction.NAME); + action.setParameterValue(CreateRecordAction.PARAM_FILE_PLAN, filePlan); + + Rule rule = new Rule(); + rule.setRuleType(RuleType.INBOUND); + rule.setTitle("my rule"); + rule.setAction(action); + rule.setExecuteAsynchronously(true); + ruleService.saveRule(ruleFile, rule); + + return null; + } + + public void test(Void result) throws Exception + { + // setup version properties + final Map versionProperties = new HashMap(4); + versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION); + versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR); + versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true); + versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan); + + versionService.createVersion(ruleFile, versionProperties); + + }; + }, dmContributor); + } + +} diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index ed71716105..4365d3339b 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -271,6 +271,8 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase /** collaboration site users */ protected String dmConsumer; protected NodeRef dmConsumerNodeRef; + protected String dmContributor; + protected NodeRef dmContributorNodeRef; protected String dmCollaborator; protected NodeRef dmCollaboratorNodeRef; @@ -772,6 +774,10 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase dmConsumer = GUID.generate(); dmConsumerNodeRef = createPerson(dmConsumer); siteService.setMembership(collabSiteId, dmConsumer, SiteModel.SITE_CONSUMER); + + dmContributor = GUID.generate(); + dmContributorNodeRef = createPerson(dmContributor); + siteService.setMembership(collabSiteId, dmContributor, SiteModel.SITE_CONTRIBUTOR); dmCollaborator = GUID.generate(); dmCollaboratorNodeRef = createPerson(dmCollaborator); From b5154530c5e910288bdc1c761f1e480d1d5d82a1 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Tue, 31 May 2016 14:50:27 +0300 Subject: [PATCH 17/33] Added integration test. --- .../UpdateNextDispositionActionTest.java | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java new file mode 100644 index 0000000000..b9d4900133 --- /dev/null +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java @@ -0,0 +1,147 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * 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 . + * #L% + */ +package org.alfresco.module.org_alfresco_module_rm.test.integration.disposition; + +import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.DEFAULT_DISPOSITION_INSTRUCTIONS; +import static org.alfresco.util.GUID.generate; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.GUID; + +/** +* Update next disposition step integration tests. +* +* @author Roxana Lucanu +* @since 2.4.1 +*/ + +public class UpdateNextDispositionActionTest extends BaseRMTestCase +{ + + /** + * Given a record with multiple dispositions + * When updating the next step + * Then the action is available + *

+ * relates to https://issues.alfresco.com/jira/browse/RM-3060 + */ + public void testUpdateNextDispositionAction_RM3060() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + NodeRef record; + + @Override + public void given() + { + // create first category + NodeRef category1 = filePlanService.createRecordCategory(filePlan, generate()); + // create disposition schedule for category1 + DispositionSchedule ds1 = utils.createDispositionSchedule(category1, DEFAULT_DISPOSITION_INSTRUCTIONS, + "ds1", true, false, false); + + // create the properties for CUTOFF action + Map adCutOff = new HashMap(3); + adCutOff.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); + adCutOff.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, "CutOffDesc"); + adCutOff.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); + + dispositionService.addDispositionActionDefinition(ds1, adCutOff); + + // create the properties for TRANSFER action + Map adTransfer = new HashMap(3); + adTransfer.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, TransferAction.NAME); + adTransfer.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, "TransferDesc"); + List eventsList = new ArrayList(1); + eventsList.add("study_complete"); + adTransfer.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable)eventsList); + + dispositionService.addDispositionActionDefinition(ds1, adTransfer); + + // create the properties for DESTROY action + Map adDestroy = new HashMap(3); + adDestroy.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, DestroyAction.NAME); + adDestroy.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, "DestroyDesc"); + adDestroy.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD, "week|1"); + + dispositionService.addDispositionActionDefinition(ds1, adDestroy); + + // create folder1 > record inside category1 + NodeRef firstFolder = recordFolderService.createRecordFolder(category1, GUID.generate()); + record = utils.createRecord(firstFolder, GUID.generate(), "title"); + + // create second category + NodeRef category2 = filePlanService.createRecordCategory(filePlan, generate()); + // create disposition schedule for category2 + DispositionSchedule ds2 = utils.createDispositionSchedule(category2, DEFAULT_DISPOSITION_INSTRUCTIONS, + "ds2", true, false, true); + // add disposition actions + dispositionService.addDispositionActionDefinition(ds2, adCutOff); + dispositionService.addDispositionActionDefinition(ds2, adTransfer); + dispositionService.addDispositionActionDefinition(ds2, adDestroy); + + // create folder2 inside category2 + NodeRef folder2 = recordFolderService.createRecordFolder(category2, GUID.generate()); + + // link the record to folder2 + recordService.link(record, folder2); + + // complete record + utils.completeRecord(record); + } + + @Override + public void when() + { + // complete event + rmActionService.executeRecordsManagementAction(record, CutOffAction.NAME, null); + } + + @Override + public void then() + { + // ensure the record folder is cut off + assertTrue(dispositionService.isDisposableItemCutoff(record)); + } + }); + + } +} From 841c21df80856992bf6b87c8507f3727612fa0be Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Wed, 1 Jun 2016 17:41:36 +0300 Subject: [PATCH 18/33] Changed test class and commented initial fix. --- .../disposition/DispositionServiceImpl.java | 10 +- .../UpdateNextDispositionActionTest.java | 108 ++++++++---------- 2 files changed, 54 insertions(+), 64 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index 04455015dd..76d476b8f4 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -891,11 +891,11 @@ public class DispositionServiceImpl extends ServiceBaseImpl currentDispositionActionDefinition = di.getDispositionActionDefinition(currentADId); // When the record has multiple disposition schedules the current disposition action may not be found by id // In this case it will be searched by name - if(currentDispositionActionDefinition == null) - { - String currentADName = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION); - currentDispositionActionDefinition = di.getDispositionActionDefinitionByName(currentADName); - } +// if(currentDispositionActionDefinition == null) +// { +// String currentADName = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION); +// currentDispositionActionDefinition = di.getDispositionActionDefinitionByName(currentADName); +// } // Get the next disposition action int index = currentDispositionActionDefinition.getIndex(); diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java index b9d4900133..edd76ccdbf 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java @@ -26,25 +26,22 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.integration.disposition; +import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.DEFAULT_DISPOSITION_DESCRIPTION; import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.DEFAULT_DISPOSITION_INSTRUCTIONS; +import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.PERIOD_IMMEDIATELY; import static org.alfresco.util.GUID.generate; import java.io.Serializable; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; -import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.GUID; /** * Update next disposition step integration tests. @@ -52,10 +49,8 @@ import org.springframework.extensions.webscripts.GUID; * @author Roxana Lucanu * @since 2.4.1 */ - public class UpdateNextDispositionActionTest extends BaseRMTestCase { - /** * Given a record with multiple dispositions * When updating the next step @@ -68,59 +63,36 @@ public class UpdateNextDispositionActionTest extends BaseRMTestCase doBehaviourDrivenTest(new BehaviourDrivenTest() { NodeRef record; + NodeRef folder2; @Override public void given() { - // create first category + // create category1 NodeRef category1 = filePlanService.createRecordCategory(filePlan, generate()); + // create disposition schedule for category1 - DispositionSchedule ds1 = utils.createDispositionSchedule(category1, DEFAULT_DISPOSITION_INSTRUCTIONS, - "ds1", true, false, false); + createDispositionSchedule(category1); - // create the properties for CUTOFF action - Map adCutOff = new HashMap(3); - adCutOff.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); - adCutOff.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, "CutOffDesc"); - adCutOff.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); - - dispositionService.addDispositionActionDefinition(ds1, adCutOff); - - // create the properties for TRANSFER action - Map adTransfer = new HashMap(3); - adTransfer.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, TransferAction.NAME); - adTransfer.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, "TransferDesc"); - List eventsList = new ArrayList(1); - eventsList.add("study_complete"); - adTransfer.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable)eventsList); - - dispositionService.addDispositionActionDefinition(ds1, adTransfer); - - // create the properties for DESTROY action - Map adDestroy = new HashMap(3); - adDestroy.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, DestroyAction.NAME); - adDestroy.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, "DestroyDesc"); - adDestroy.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD, "week|1"); - - dispositionService.addDispositionActionDefinition(ds1, adDestroy); - - // create folder1 > record inside category1 - NodeRef firstFolder = recordFolderService.createRecordFolder(category1, GUID.generate()); - record = utils.createRecord(firstFolder, GUID.generate(), "title"); - - // create second category + // create category2 NodeRef category2 = filePlanService.createRecordCategory(filePlan, generate()); + // create disposition schedule for category2 - DispositionSchedule ds2 = utils.createDispositionSchedule(category2, DEFAULT_DISPOSITION_INSTRUCTIONS, - "ds2", true, false, true); - // add disposition actions - dispositionService.addDispositionActionDefinition(ds2, adCutOff); - dispositionService.addDispositionActionDefinition(ds2, adTransfer); - dispositionService.addDispositionActionDefinition(ds2, adDestroy); + createDispositionSchedule(category2); // create folder2 inside category2 - NodeRef folder2 = recordFolderService.createRecordFolder(category2, GUID.generate()); + folder2 = recordFolderService.createRecordFolder(category2, generate()); + // create folder1 inside category1 + NodeRef folder1 = recordFolderService.createRecordFolder(category1, generate()); + + // create record inside folder1 + record = utils.createRecord(folder1, generate(), generate()); + } + + @Override + public void when() + { // link the record to folder2 recordService.link(record, folder2); @@ -129,19 +101,37 @@ public class UpdateNextDispositionActionTest extends BaseRMTestCase } @Override - public void when() + public void then() throws Exception { - // complete event + // cut off rmActionService.executeRecordsManagementAction(record, CutOffAction.NAME, null); } - - @Override - public void then() - { - // ensure the record folder is cut off - assertTrue(dispositionService.isDisposableItemCutoff(record)); - } }); - } -} + + private void createDispositionSchedule(NodeRef category) + { + DispositionSchedule ds = utils.createDispositionSchedule(category, DEFAULT_DISPOSITION_INSTRUCTIONS, DEFAULT_DISPOSITION_DESCRIPTION, true, false, false); + + // create the properties for CUTOFF action and add it to the disposition action definition + Map cutOff = new HashMap(3); + cutOff.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); + cutOff.put(PROP_DISPOSITION_DESCRIPTION, generate()); + cutOff.put(PROP_DISPOSITION_PERIOD, PERIOD_IMMEDIATELY); + dispositionService.addDispositionActionDefinition(ds, cutOff); + + // create the properties for TRANSFER action and add it to the disposition action definition + Map transfer = new HashMap(3); + transfer.put(PROP_DISPOSITION_ACTION_NAME, TransferAction.NAME); + transfer.put(PROP_DISPOSITION_DESCRIPTION, generate()); + transfer.put(PROP_DISPOSITION_PERIOD, PERIOD_IMMEDIATELY); + dispositionService.addDispositionActionDefinition(ds, transfer); + + // create the properties for DESTROY action and add it to the disposition action definition + Map destroy = new HashMap(3); + destroy.put(PROP_DISPOSITION_ACTION_NAME, DestroyAction.NAME); + destroy.put(PROP_DISPOSITION_DESCRIPTION, generate()); + destroy.put(PROP_DISPOSITION_PERIOD, PERIOD_IMMEDIATELY); + dispositionService.addDispositionActionDefinition(ds, destroy); + } +} \ No newline at end of file From 8d8f5fb5c3b1a694542509c1512ca60f16f7e97f Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Fri, 3 Jun 2016 11:10:18 +0300 Subject: [PATCH 19/33] Added check to allow creating only records inside a record folder. --- .../model/rma/type/RecordFolderType.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java index 6c3aaafc87..668bf2aa73 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java @@ -31,6 +31,7 @@ import java.io.Serializable; import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.model.behaviour.AbstractDisposableItem; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; @@ -211,12 +212,18 @@ public class RecordFolderType extends AbstractDisposableItem public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean bNew) { NodeRef nodeRef = childAssocRef.getChildRef(); - if (nodeService.exists(nodeRef) && instanceOf(nodeRef, TYPE_RECORD_FOLDER)) + + if (nodeService.exists(nodeRef)) { + // only records can be added in a record folder + if (!instanceOf(nodeRef, ContentModel.TYPE_CONTENT)) + { + throw new AlfrescoRuntimeException("Operation failed, because you can only place content into a record folder."); + } // ensure nothing is being added to a closed record folder NodeRef recordFolder = childAssocRef.getParentRef(); Boolean isClosed = (Boolean) nodeService.getProperty(recordFolder, PROP_IS_CLOSED); - if (isClosed != null && Boolean.TRUE.equals(isClosed)) + if (isClosed != null && isClosed) { throw new AlfrescoRuntimeException("You can't add new items to a closed record folder."); } From b372ff09009e1cec081e21603548d5ccbf320b8c Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Mon, 6 Jun 2016 10:25:46 +0300 Subject: [PATCH 20/33] Moved check for content to be done on commit. --- .../model/rma/type/RecordFolderType.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java index 668bf2aa73..7d2aff1e47 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java @@ -215,11 +215,6 @@ public class RecordFolderType extends AbstractDisposableItem if (nodeService.exists(nodeRef)) { - // only records can be added in a record folder - if (!instanceOf(nodeRef, ContentModel.TYPE_CONTENT)) - { - throw new AlfrescoRuntimeException("Operation failed, because you can only place content into a record folder."); - } // ensure nothing is being added to a closed record folder NodeRef recordFolder = childAssocRef.getParentRef(); Boolean isClosed = (Boolean) nodeService.getProperty(recordFolder, PROP_IS_CLOSED); @@ -245,6 +240,12 @@ public class RecordFolderType extends AbstractDisposableItem { final NodeRef recordFolder = childAssocRef.getChildRef(); + // only records can be added in a record folder or hidden folders(is the case of e-mail attachments) + if (!instanceOf(recordFolder, ContentModel.TYPE_CONTENT) && !nodeService.hasAspect(recordFolder, ContentModel.ASPECT_HIDDEN)) + { + throw new AlfrescoRuntimeException("Operation failed, because you can only place content into a record folder."); + } + behaviourFilter.disableBehaviour(); try { From 36b6916a8886f4f0b0421fcc36140245033b63b4 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Thu, 9 Jun 2016 13:53:07 +1000 Subject: [PATCH 21/33] Changes to integration to better reflect the scenario to be tested --- .../EditDispositionActionAsOfDateAction.java | 3 ++ .../UpdateNextDispositionActionTest.java | 33 ++++++++++++------- .../test/util/CommonRMTestUtils.java | 1 + 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java index d7ff27e995..071b3a2da2 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java @@ -47,6 +47,9 @@ public class EditDispositionActionAsOfDateAction extends RMActionExecuterAbstrac private static final String MSG_VALID_DATE_DISP_ASOF = "rm.action.valid-date-disp-asof"; private static final String MSG_DISP_ASOF_LIFECYCLE_APPLIED = "rm.action.disp-asof-lifecycle-applied"; + /** Action name */ + public static final String NAME = "editDispositionActionAsOfDate"; + /** Action parameters */ public static final String PARAM_AS_OF_DATE = "asOfDate"; diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java index edd76ccdbf..9e63033e32 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java @@ -28,15 +28,19 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.disposition; import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.DEFAULT_DISPOSITION_DESCRIPTION; import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.DEFAULT_DISPOSITION_INSTRUCTIONS; -import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.PERIOD_IMMEDIATELY; +import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.DEFAULT_EVENT_NAME; +import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils.PERIOD_ONE_WEEK; import static org.alfresco.util.GUID.generate; import java.io.Serializable; +import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.EditDispositionActionAsOfDateAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; @@ -88,23 +92,30 @@ public class UpdateNextDispositionActionTest extends BaseRMTestCase // create record inside folder1 record = utils.createRecord(folder1, generate(), generate()); - } - - @Override - public void when() - { + // link the record to folder2 recordService.link(record, folder2); // complete record utils.completeRecord(record); + + // set the disposition as of date to now on the record + rmActionService.executeRecordsManagementAction(record, + EditDispositionActionAsOfDateAction.NAME, + Collections.singletonMap(EditDispositionActionAsOfDateAction.PARAM_AS_OF_DATE, new Date())); + } + + @Override + public void when() + { + // cut off + rmActionService.executeRecordsManagementAction(record, CutOffAction.NAME, null); } @Override public void then() throws Exception { - // cut off - rmActionService.executeRecordsManagementAction(record, CutOffAction.NAME, null); + assertTrue(nodeService.hasAspect(record, ASPECT_CUT_OFF)); } }); } @@ -117,21 +128,21 @@ public class UpdateNextDispositionActionTest extends BaseRMTestCase Map cutOff = new HashMap(3); cutOff.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); cutOff.put(PROP_DISPOSITION_DESCRIPTION, generate()); - cutOff.put(PROP_DISPOSITION_PERIOD, PERIOD_IMMEDIATELY); + cutOff.put(PROP_DISPOSITION_PERIOD, PERIOD_ONE_WEEK); dispositionService.addDispositionActionDefinition(ds, cutOff); // create the properties for TRANSFER action and add it to the disposition action definition Map transfer = new HashMap(3); transfer.put(PROP_DISPOSITION_ACTION_NAME, TransferAction.NAME); transfer.put(PROP_DISPOSITION_DESCRIPTION, generate()); - transfer.put(PROP_DISPOSITION_PERIOD, PERIOD_IMMEDIATELY); + transfer.put(PROP_DISPOSITION_EVENT, (Serializable)Collections.singletonList(DEFAULT_EVENT_NAME)); dispositionService.addDispositionActionDefinition(ds, transfer); // create the properties for DESTROY action and add it to the disposition action definition Map destroy = new HashMap(3); destroy.put(PROP_DISPOSITION_ACTION_NAME, DestroyAction.NAME); destroy.put(PROP_DISPOSITION_DESCRIPTION, generate()); - destroy.put(PROP_DISPOSITION_PERIOD, PERIOD_IMMEDIATELY); + destroy.put(PROP_DISPOSITION_PERIOD, PERIOD_ONE_WEEK); dispositionService.addDispositionActionDefinition(ds, destroy); } } \ No newline at end of file diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java index 8f4ddd7969..1938535988 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java @@ -86,6 +86,7 @@ public class CommonRMTestUtils implements RecordsManagementModel public static final String DEFAULT_EVENT_NAME = "case_closed"; public static final String PERIOD_NONE = "none|0"; public static final String PERIOD_IMMEDIATELY = "immediately|0"; + public static final String PERIOD_ONE_WEEK = "week|1"; /** * Constructor From 5c8cc6fef25bd8b37724ee09a7fbfc210f9db2f7 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Wed, 15 Jun 2016 12:01:47 +0300 Subject: [PATCH 22/33] Changed to BehaviourDrivenTest to be more obvious the steps and what is checked. --- .../DeclareVersionAsRecordActionTest.java | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java index 07e921fe65..05d81a1268 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/DeclareVersionAsRecordActionTest.java @@ -34,6 +34,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction; import org.alfresco.module.org_alfresco_module_rm.action.dm.DeclareAsVersionRecordAction; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl; import org.alfresco.repo.version.VersionModel; import org.alfresco.service.cmr.action.Action; @@ -50,11 +51,11 @@ public class DeclareVersionAsRecordActionTest extends BaseRMTestCase private NodeRef ruleFile; protected static final String DESCRIPTION = "description"; + @Override protected void initServices() { super.initServices(); - ruleService = (RuleService)applicationContext.getBean("RuleService"); } @@ -70,16 +71,21 @@ public class DeclareVersionAsRecordActionTest extends BaseRMTestCase return true; } + /** * Given a node set to auto-declare documents as records for minor and major versions * When I try to upload a minor or major version * Then the version record aspect is added */ - public void testAutoDeclareVersionAsRecord() + public void testUpdateNextDispositionAction_RM3060() throws Exception { - doTestInTransaction(new Test() + doBehaviourDrivenTest(new BehaviourDrivenTest(dmContributor) { - public Void run() + Map versionProperties = new HashMap(4); + Version recordedVersion; + + @Override + public void given() { // create the file ruleFile = fileFolderService.create(documentLibrary, "mytestfile", ContentModel.TYPE_CONTENT).getNodeRef(); @@ -94,22 +100,27 @@ public class DeclareVersionAsRecordActionTest extends BaseRMTestCase rule.setExecuteAsynchronously(true); ruleService.saveRule(ruleFile, rule); - return null; - } - - public void test(Void result) throws Exception - { // setup version properties - final Map versionProperties = new HashMap(4); versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION); versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR); versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true); versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan); + } - versionService.createVersion(ruleFile, versionProperties); + @Override + public void when() + { + recordedVersion = versionService.createVersion(ruleFile, versionProperties); + } - }; - }, dmContributor); + @Override + public void then() throws Exception + { + NodeRef recordedVersionNodeRef= (NodeRef)recordedVersion.getVersionProperties().get(RecordableVersionModel.PROP_RECORD_NODE_REF.getLocalName()); + assertNotNull("Recorded version shouldn't be null.", recordedVersionNodeRef); + assertTrue(nodeService.hasAspect(recordedVersionNodeRef, RecordableVersionModel.ASPECT_VERSION_RECORD)); + } + }); } } From 69a20b7adf15f17ed39b89c5c4a9846a432da781 Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Wed, 15 Jun 2016 15:42:11 +0300 Subject: [PATCH 23/33] RM-3293 RM Audit History does not log Cutoff --- .../alfresco-global.properties | 2 + .../org_alfresco_module_rm/rm-job-context.xml | 3 +- .../job/RecordsManagementJob.java | 58 +++++++++++-------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties index 221a3f5fc1..62a73628b5 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties @@ -17,6 +17,8 @@ imap.server.attachments.extraction.enabled=false # audit.enabled=true audit.rm.enabled=true +audit.rm.runasadmin=false +#audit.filter.alfresco-access.transaction.user=~null;.* # # Extended permission service cache sizing diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml index c975a79827..15f556cd54 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml @@ -59,6 +59,7 @@ + @@ -94,7 +95,7 @@ - + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java index 409a0f0d32..e885782798 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java @@ -42,12 +42,12 @@ import org.apache.commons.logging.LogFactory; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; +import org.springframework.scheduling.quartz.QuartzJobBean; /** * Base records management job implementation. *

- * Delegates job execution and ensures locking - * is enforced. + * Delegates job execution and ensures locking is enforced. * * @author Roy Wetherall */ @@ -55,6 +55,9 @@ public class RecordsManagementJob implements Job { private static Log logger = LogFactory.getLog(RecordsManagementJob.class); + /** indicates whether the audit history should be run as admin or not */ + private boolean runAsAdmin = false; + private static final long DEFAULT_TIME = 30000L; private JobLockService jobLockService; @@ -67,17 +70,17 @@ public class RecordsManagementJob implements Job { return QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, jobName); } - + private class LockCallback implements JobLockRefreshCallback { final AtomicBoolean running = new AtomicBoolean(true); - + @Override public boolean isActive() { return running.get(); } - + @Override public void lockReleased() { @@ -85,11 +88,10 @@ public class RecordsManagementJob implements Job } } - /** - * Attempts to get the lock. If the lock couldn't be taken, then null is returned. + * Attempts to get the lock. If the lock couldn't be taken, then null is returned. * - * @return Returns the lock token or null + * @return Returns the lock token or null */ private String getLock() { @@ -107,27 +109,21 @@ public class RecordsManagementJob implements Job public void execute(JobExecutionContext context) throws JobExecutionException { // get the job lock service - jobLockService = (JobLockService)context.getJobDetail().getJobDataMap().get("jobLockService"); - if (jobLockService == null) - { - throw new AlfrescoRuntimeException("Job lock service has not been specified."); - } + jobLockService = (JobLockService) context.getJobDetail().getJobDataMap().get("jobLockService"); + if (jobLockService == null) { throw new AlfrescoRuntimeException("Job lock service has not been specified."); } // get the job executer - jobExecuter = (RecordsManagementJobExecuter)context.getJobDetail().getJobDataMap().get("jobExecuter"); - if (jobExecuter == null) - { - throw new AlfrescoRuntimeException("Job executer has not been specified."); - } + jobExecuter = (RecordsManagementJobExecuter) context.getJobDetail().getJobDataMap().get("jobExecuter"); + if (jobExecuter == null) { throw new AlfrescoRuntimeException("Job executer has not been specified."); } // get the job name - jobName = (String)context.getJobDetail().getJobDataMap().get("jobName"); - if (jobName == null) - { - throw new AlfrescoRuntimeException("Job name has not been specified."); - } + jobName = (String) context.getJobDetail().getJobDataMap().get("jobName"); + if (jobName == null) { throw new AlfrescoRuntimeException("Job name has not been specified."); } + + setRunAsAdmin(Boolean.parseBoolean((String) context.getJobDetail().getJobDataMap().get("runAsAdmin"))); final LockCallback lockCallback = new LockCallback(); + AuthenticationUtil.runAs(new RunAsWork() { public Void doWork() @@ -154,7 +150,8 @@ public class RecordsManagementJob implements Job // Ignore if (logger.isDebugEnabled()) { - logger.debug("Lock release failed: " + getLockQName() + ": " + lockToken + "(" + e.getMessage() + ")"); + logger.debug("Lock release failed: " + getLockQName() + ": " + lockToken + "(" + + e.getMessage() + ")"); } } } @@ -163,6 +160,17 @@ public class RecordsManagementJob implements Job // return return null; } - }, AuthenticationUtil.getSystemUserName()); + }, this.runAsAdmin ? AuthenticationUtil.getAdminUserName() : AuthenticationUtil.getSystemUserName()); } + + public boolean isRunAsAdmin() + { + return runAsAdmin; + } + + public void setRunAsAdmin(boolean runAsAdmin) + { + this.runAsAdmin = runAsAdmin; + } + } From 28551bb78ac0e2b63818b9bb606b8d2e91216004 Mon Sep 17 00:00:00 2001 From: Roxana Dina Date: Thu, 16 Jun 2016 14:00:28 +0300 Subject: [PATCH 24/33] rm-3265 Add new capability condition to deal with displaying the "Move" action. --- .../rm-capabilities-condition-context.xml | 7 ++- .../rm-capabilities-recordfolder-context.xml | 3 +- .../MoveActionCapabilityCondition.java | 46 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MoveActionCapabilityCondition.java diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml index 408cbbf617..ac731e66d5 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml @@ -60,6 +60,11 @@ class="org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.TransferredCapabilityCondition"> + + + @@ -218,7 +223,7 @@ - + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml index dbb0c48acb..4d5bbfc16d 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml @@ -129,8 +129,7 @@ - - + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MoveActionCapabilityCondition.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MoveActionCapabilityCondition.java new file mode 100644 index 0000000000..a41afc66e8 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MoveActionCapabilityCondition.java @@ -0,0 +1,46 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * 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 . + * #L% + */ +package org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition; + +import org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * @author Roxana Dina + * + */ +public class MoveActionCapabilityCondition extends AbstractCapabilityCondition +{ + + @Override + public boolean evaluateImpl(NodeRef nodeRef) + { + if (nodeService.hasAspect(nodeRef, ASPECT_GHOSTED) && dispositionService.isDisposableItemCutoff(nodeRef)) + return true; + return !dispositionService.isDisposableItemCutoff(nodeRef); + } +} From b1db2fcd047eafeff3b596928afa27c83d1f675d Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Thu, 16 Jun 2016 15:50:35 +0300 Subject: [PATCH 25/33] Changed the test a bit and uncommented intial fix, as we agree it's an workaround for the moment. --- .../disposition/DispositionServiceImpl.java | 10 +++++----- .../UpdateNextDispositionActionTest.java | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index 76d476b8f4..04455015dd 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -891,11 +891,11 @@ public class DispositionServiceImpl extends ServiceBaseImpl currentDispositionActionDefinition = di.getDispositionActionDefinition(currentADId); // When the record has multiple disposition schedules the current disposition action may not be found by id // In this case it will be searched by name -// if(currentDispositionActionDefinition == null) -// { -// String currentADName = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION); -// currentDispositionActionDefinition = di.getDispositionActionDefinitionByName(currentADName); -// } + if(currentDispositionActionDefinition == null) + { + String currentADName = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION); + currentDispositionActionDefinition = di.getDispositionActionDefinitionByName(currentADName); + } // Get the next disposition action int index = currentDispositionActionDefinition.getIndex(); diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java index 9e63033e32..462198f5a7 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java @@ -92,24 +92,24 @@ public class UpdateNextDispositionActionTest extends BaseRMTestCase // create record inside folder1 record = utils.createRecord(folder1, generate(), generate()); - + + } + @Override + public void when() throws Exception + { // link the record to folder2 recordService.link(record, folder2); // complete record utils.completeRecord(record); - + // set the disposition as of date to now on the record rmActionService.executeRecordsManagementAction(record, - EditDispositionActionAsOfDateAction.NAME, - Collections.singletonMap(EditDispositionActionAsOfDateAction.PARAM_AS_OF_DATE, new Date())); - } + EditDispositionActionAsOfDateAction.NAME, + Collections.singletonMap(EditDispositionActionAsOfDateAction.PARAM_AS_OF_DATE, new Date())); - @Override - public void when() - { // cut off - rmActionService.executeRecordsManagementAction(record, CutOffAction.NAME, null); + rmActionService.executeRecordsManagementAction(record, CutOffAction.NAME, null); } @Override From db390cfb8c5451dc5c2844807d1a9e9421c74f9b Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Fri, 17 Jun 2016 12:05:19 +0300 Subject: [PATCH 26/33] Created a property for AlfrescoRuntimeException instead ot the message. --- .../messages/action-service.properties | 3 ++- .../model/rma/type/RecordFolderType.java | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties index 5c6a7d4daf..dbb53e0559 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties @@ -36,4 +36,5 @@ rm.action.records_only_undeclared=Only records can be completed. rm.action.event-not-undone=The event {0} can't be undone, because it's not defined on the disposition lifecycle. rm.action.node-not-record-category=The disposition schedule could not be created, because the actioned upon node ({0}) was not a record category. rm.action.parameter-not-supplied=The parameter ''{0}'' has not been supplied. -rm.action.delete-not-hold-type=The hold couldn't be deleted, because the node isn't of type {0}. (actionedUponNodeRef={1}) \ No newline at end of file +rm.action.delete-not-hold-type=The hold couldn't be deleted, because the node isn't of type {0}. (actionedUponNodeRef={1}) +rm.action.record-folder-create=Operation failed, because you can't place a record folder into another record folder. diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java index 7d2aff1e47..5974c922a6 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java @@ -50,6 +50,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.apache.commons.lang.ArrayUtils; +import org.springframework.extensions.surf.util.I18NUtil; /** * rma:recordFolder behaviour bean @@ -74,6 +75,9 @@ public class RecordFolderType extends AbstractDisposableItem /** vital record service */ protected VitalRecordService vitalRecordService; + /** I18N */ + private static final String MSG_CANNOT_CREATE_RECORD_FOLDER = "rm.action.record-folder-create"; + /** * @param recordService record service */ @@ -243,7 +247,7 @@ public class RecordFolderType extends AbstractDisposableItem // only records can be added in a record folder or hidden folders(is the case of e-mail attachments) if (!instanceOf(recordFolder, ContentModel.TYPE_CONTENT) && !nodeService.hasAspect(recordFolder, ContentModel.ASPECT_HIDDEN)) { - throw new AlfrescoRuntimeException("Operation failed, because you can only place content into a record folder."); + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CANNOT_CREATE_RECORD_FOLDER)); } behaviourFilter.disableBehaviour(); From 3d8f609c4cf726cfd2d02bcb4542aa76781dc128 Mon Sep 17 00:00:00 2001 From: Roxana Dina Date: Fri, 17 Jun 2016 16:32:43 +0300 Subject: [PATCH 27/33] Change capability condition name. Add comments and version number. --- .../capability/rm-capabilities-condition-context.xml | 4 ++-- .../capability/rm-capabilities-recordfolder-context.xml | 2 +- ...lityCondition.java => MovableCapabilityCondition.java} | 8 +++++++- 3 files changed, 10 insertions(+), 4 deletions(-) rename rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/{MoveActionCapabilityCondition.java => MovableCapabilityCondition.java} (83%) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml index ac731e66d5..d5509295c4 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml @@ -60,9 +60,9 @@ class="org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.TransferredCapabilityCondition"> - + class="org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.MovableCapabilityCondition"> - + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MoveActionCapabilityCondition.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableCapabilityCondition.java similarity index 83% rename from rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MoveActionCapabilityCondition.java rename to rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableCapabilityCondition.java index a41afc66e8..99aebc7f29 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MoveActionCapabilityCondition.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableCapabilityCondition.java @@ -30,12 +30,18 @@ import org.alfresco.module.org_alfresco_module_rm.capability.declarative.Abstrac import org.alfresco.service.cmr.repository.NodeRef; /** + * Movable capability condition. + * * @author Roxana Dina + * @since 2.4.1 * */ -public class MoveActionCapabilityCondition extends AbstractCapabilityCondition +public class MovableCapabilityCondition extends AbstractCapabilityCondition { + /** + * A record folder should not be moved when it is cut off, but it should be possible to move it when it is destroyed. + */ @Override public boolean evaluateImpl(NodeRef nodeRef) { From f3663bcd584dffab702001a72074bebd5cf02f66 Mon Sep 17 00:00:00 2001 From: Roxana Dina Date: Wed, 22 Jun 2016 20:27:26 +0300 Subject: [PATCH 28/33] RM-3265 Add test for the Move action on a destroyed record folder. --- .../recordfolder/MoveRecordFolderTest.java | 224 +++++++++++------- 1 file changed, 142 insertions(+), 82 deletions(-) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java index 0d35057d2f..b359887c37 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java @@ -34,6 +34,7 @@ import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.impl.CompleteEventAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction; import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; @@ -48,31 +49,31 @@ import net.sf.acegisecurity.vote.AccessDecisionVoter; /** * Move record folder tests. - * + * * @author Roy Wetherall * @since 2.2 */ public class MoveRecordFolderTest extends BaseRMTestCase -{ +{ @Override protected boolean isRecordTest() { return true; } - + /** - * Given two categories, both with cut off immediately schedules, when the record is move - * then all the parts of the record should be correct based on the new schedule. - * + * Given two categories, both with cut off immediately schedules, when the record is move then all the parts of the + * record should be correct based on the new schedule. + * * @see https://issues.alfresco.com/jira/browse/RM-1345 */ public void testMoveRecordFolderBeforeCutOffFolderLevelDisposition() throws Exception { doBehaviourDrivenTest(new BehaviourDrivenTest(null, false) - { - NodeRef recordFolder; + { + NodeRef recordFolder; NodeRef destinationRecordCategory; - + public void given() { doTestInTransaction(new VoidTest() @@ -82,43 +83,44 @@ public class MoveRecordFolderTest extends BaseRMTestCase NodeRef rcOne = createRecordCategory(false); destinationRecordCategory = createRecordCategory(false); recordFolder = recordFolderService.createRecordFolder(rcOne, GUID.generate()); - + // check for the lifecycle aspect assertTrue(nodeService.hasAspect(recordFolder, ASPECT_DISPOSITION_LIFECYCLE)); - + // check the disposition action details DispositionAction dispositionAction = dispositionService.getNextDispositionAction(recordFolder); assertNotNull(dispositionAction); assertNotNull(CutOffAction.NAME, dispositionAction.getName()); assertNotNull(dispositionAction.getAsOfDate()); assertTrue(dispositionService.isNextDispositionActionEligible(recordFolder)); - } + } }); - + doTestInTransaction(new VoidTest() { public void runImpl() throws Exception { // check the search aspect properties assertTrue(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH)); - assertEquals(CutOffAction.NAME, nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_NAME)); + assertEquals(CutOffAction.NAME, + nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_NAME)); assertNotNull(nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_AS_OF)); - } + } }); } - + public void when() throws Exception - { + { doTestInTransaction(new VoidTest() { public void runImpl() throws Exception { // move record folder - fileFolderService.move(recordFolder, destinationRecordCategory, GUID.generate()); - } - }); + fileFolderService.move(recordFolder, destinationRecordCategory, GUID.generate()); + } + }); } - + public void then() { doTestInTransaction(new VoidTest() @@ -127,34 +129,35 @@ public class MoveRecordFolderTest extends BaseRMTestCase { // check for the lifecycle aspect assertTrue(nodeService.hasAspect(recordFolder, ASPECT_DISPOSITION_LIFECYCLE)); - + // check the disposition action details DispositionAction dispositionAction = dispositionService.getNextDispositionAction(recordFolder); assertNotNull(dispositionAction); assertNotNull(CutOffAction.NAME, dispositionAction.getName()); assertNotNull(dispositionAction.getAsOfDate()); assertTrue(dispositionService.isNextDispositionActionEligible(recordFolder)); - - // check the search aspect properties - assertTrue(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH)); - assertEquals(CutOffAction.NAME, nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_NAME)); - assertNotNull(nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_AS_OF)); + + // check the search aspect properties + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH)); + assertEquals(CutOffAction.NAME, + nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_NAME)); + assertNotNull(nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_AS_OF)); } - }); + }); } - }); + }); } - + /** * */ public void testMoveRecordFolderBeforeCutOffIntoAFolderWithNoDisposition() throws Exception { doBehaviourDrivenTest(new BehaviourDrivenTest(null, false) - { - NodeRef recordFolder; + { + NodeRef recordFolder; NodeRef destinationRecordCategory; - + public void given() { doTestInTransaction(new VoidTest() @@ -164,43 +167,44 @@ public class MoveRecordFolderTest extends BaseRMTestCase NodeRef rcOne = createRecordCategory(false); destinationRecordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); recordFolder = recordFolderService.createRecordFolder(rcOne, GUID.generate()); - + // check for the lifecycle aspect assertTrue(nodeService.hasAspect(recordFolder, ASPECT_DISPOSITION_LIFECYCLE)); - + // check the disposition action details DispositionAction dispositionAction = dispositionService.getNextDispositionAction(recordFolder); assertNotNull(dispositionAction); assertNotNull(CutOffAction.NAME, dispositionAction.getName()); assertNotNull(dispositionAction.getAsOfDate()); assertTrue(dispositionService.isNextDispositionActionEligible(recordFolder)); - } + } }); - + doTestInTransaction(new VoidTest() { public void runImpl() throws Exception { // check the search aspect properties assertTrue(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH)); - assertEquals(CutOffAction.NAME, nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_NAME)); + assertEquals(CutOffAction.NAME, + nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_NAME)); assertNotNull(nodeService.getProperty(recordFolder, PROP_RS_DISPOSITION_ACTION_AS_OF)); - } + } }); } - + public void when() throws Exception - { + { doTestInTransaction(new VoidTest() { public void runImpl() throws Exception { // move record folder - fileFolderService.move(recordFolder, destinationRecordCategory, GUID.generate()); - } - }); + fileFolderService.move(recordFolder, destinationRecordCategory, GUID.generate()); + } + }); } - + public void then() { doTestInTransaction(new VoidTest() @@ -209,29 +213,29 @@ public class MoveRecordFolderTest extends BaseRMTestCase { // check for the lifecycle aspect assertFalse(nodeService.hasAspect(recordFolder, ASPECT_DISPOSITION_LIFECYCLE)); - + // check the disposition action details assertNull(dispositionService.getNextDispositionAction(recordFolder)); - - // check the search aspect properties - assertFalse(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH)); + + // check the search aspect properties + assertFalse(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH)); } - }); + }); } - }); + }); } - + /** - * + * */ public void testMoveRecordFolderWithRecordsBeforeCutOffRecordLevelDisposition() throws Exception { doBehaviourDrivenTest(new BehaviourDrivenTest(null, false) - { - NodeRef record; + { + NodeRef record; NodeRef recordFolder; NodeRef destinationRecordCategory; - + public void given() { doTestInTransaction(new VoidTest() @@ -242,11 +246,11 @@ public class MoveRecordFolderTest extends BaseRMTestCase destinationRecordCategory = createRecordCategory(true); recordFolder = recordFolderService.createRecordFolder(rcOne, GUID.generate()); record = utils.createRecord(recordFolder, GUID.generate()); - + // check for the lifecycle aspect assertFalse(nodeService.hasAspect(recordFolder, ASPECT_DISPOSITION_LIFECYCLE)); assertTrue(nodeService.hasAspect(record, ASPECT_DISPOSITION_LIFECYCLE)); - + // check the disposition action details assertNull(dispositionService.getNextDispositionAction(recordFolder)); DispositionAction dispositionAction = dispositionService.getNextDispositionAction(record); @@ -254,33 +258,34 @@ public class MoveRecordFolderTest extends BaseRMTestCase assertNotNull(CutOffAction.NAME, dispositionAction.getName()); assertNotNull(dispositionAction.getAsOfDate()); assertTrue(dispositionService.isNextDispositionActionEligible(record)); - } + } }); - + doTestInTransaction(new VoidTest() { public void runImpl() throws Exception { // check the search aspect properties assertTrue(nodeService.hasAspect(record, ASPECT_RM_SEARCH)); - assertEquals(CutOffAction.NAME, nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_NAME)); + assertEquals(CutOffAction.NAME, + nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_NAME)); assertNotNull(nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_AS_OF)); - } + } }); } - + public void when() throws Exception - { + { doTestInTransaction(new VoidTest() { public void runImpl() throws Exception { // move record folder - fileFolderService.move(recordFolder, destinationRecordCategory, GUID.generate()); - } - }); + fileFolderService.move(recordFolder, destinationRecordCategory, GUID.generate()); + } + }); } - + public void then() { doTestInTransaction(new VoidTest() @@ -290,7 +295,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase // check for the lifecycle aspect assertFalse(nodeService.hasAspect(recordFolder, ASPECT_DISPOSITION_LIFECYCLE)); assertTrue(nodeService.hasAspect(record, ASPECT_DISPOSITION_LIFECYCLE)); - + // check the disposition action details assertNull(dispositionService.getNextDispositionAction(recordFolder)); DispositionAction dispositionAction = dispositionService.getNextDispositionAction(record); @@ -298,20 +303,21 @@ public class MoveRecordFolderTest extends BaseRMTestCase assertNotNull(CutOffAction.NAME, dispositionAction.getName()); assertNotNull(dispositionAction.getAsOfDate()); assertTrue(dispositionService.isNextDispositionActionEligible(record)); - - // check the search aspect properties - assertTrue(nodeService.hasAspect(record, ASPECT_RM_SEARCH)); - assertEquals(CutOffAction.NAME, nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_NAME)); - assertNotNull(nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_AS_OF)); + + // check the search aspect properties + assertTrue(nodeService.hasAspect(record, ASPECT_RM_SEARCH)); + assertEquals(CutOffAction.NAME, + nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_NAME)); + assertNotNull(nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_AS_OF)); } - }); + }); } - }); + }); } /** * Try and move a folder from no disposition schedule to a disposition schedule - * + * * @see https://issues.alfresco.com/jira/browse/RM-1039 */ public void testMoveRecordFolderFromNoDisToDis() throws Exception @@ -333,7 +339,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase { assertNotNull(result); assertNull(dispositionService.getDispositionSchedule(result)); - assertFalse(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); + assertFalse(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(result, FILING)); } }); @@ -394,7 +400,6 @@ public class MoveRecordFolderTest extends BaseRMTestCase }); } - // try and move a cutoff folder public void testMoveCutoffRecordFolder() throws Exception { @@ -426,7 +431,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase return testFolder; } - + @Override public void test(NodeRef testFolder) throws Exception { @@ -446,11 +451,66 @@ public class MoveRecordFolderTest extends BaseRMTestCase }); } - + // try and move a destroyed folder + public void testMoveDestroyedRecordFolder() throws Exception + { + final NodeRef destination = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record category (no disposition schedule) + return filePlanService.createRecordCategory(filePlan, "Caitlin Reed"); + } + }); + + final NodeRef testFolder = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create folder + NodeRef testFolder = recordFolderService.createRecordFolder(rmContainer, "Peter Edward Francis"); + + // complete event + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + rmActionService.executeRecordsManagementAction(testFolder, CompleteEventAction.NAME, params); + + // cutoff & destroy folder + rmActionService.executeRecordsManagementAction(testFolder, CutOffAction.NAME); + rmActionService.executeRecordsManagementAction(testFolder, DestroyAction.NAME); + + return testFolder; + } + + }); + + doTestInTransaction(new Test() + { + @Override + public NodeRef run() throws Exception + { + Capability moveCapability = capabilityService.getCapability("MoveRecordFolder"); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, moveCapability.evaluate(testFolder, destination)); + + return fileFolderService.move(testFolder, destination, null).getNodeRef(); + } + + @Override + public void test(NodeRef result) throws Exception + { + assertNotNull(result); + } + }); + + } + private NodeRef createRecordCategory(boolean recordLevel) { NodeRef rc = filePlanService.createRecordCategory(filePlan, GUID.generate()); - DispositionSchedule dis = utils.createBasicDispositionSchedule(rc, GUID.generate(), GUID.generate(), recordLevel, false); + DispositionSchedule dis = utils.createBasicDispositionSchedule(rc, GUID.generate(), GUID.generate(), + recordLevel, false); Map adParams = new HashMap(3); adParams.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); adParams.put(PROP_DISPOSITION_DESCRIPTION, GUID.generate()); From bf83f34716cdf54245ccda7de8de6e1f99fcc319 Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Thu, 23 Jun 2016 12:10:06 +0300 Subject: [PATCH 29/33] RM-3293 RM Audit History does not log --- .../alfresco-global.properties | 5 +- .../org_alfresco_module_rm/rm-job-context.xml | 38 +++++++------- .../job/DispositionLifecycleJobExecuter.java | 42 ++++++++++----- .../job/RecordsManagementJob.java | 51 +++++++++++++++---- 4 files changed, 91 insertions(+), 45 deletions(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties index 62a73628b5..8391868971 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties @@ -17,7 +17,8 @@ imap.server.attachments.extraction.enabled=false # audit.enabled=true audit.rm.enabled=true -audit.rm.runasadmin=false +#audit.rm.runas=admin + #audit.filter.alfresco-access.transaction.user=~null;.* # @@ -48,7 +49,7 @@ rm.autocompletesuggestion.nodeParameterSuggester.aspectsAndTypes=rma:record,cm:c # # Global RM disposition lifecycle trigger cron job expression # -rm.dispositionlifecycletrigger.cronexpression=0 0/5 * * * ? +rm.dispositionlifecycletrigger.cronexpression=0 0/2 * * * ? # # Records contributors group diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml index 15f556cd54..44bd92fe34 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml @@ -51,24 +51,25 @@ - - - - org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJob - - - - - - - - - - - - - - + + + + + org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJob + + + + + + + + + + + + + + + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java index 2043244909..aadbbf6f19 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java @@ -43,16 +43,13 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.cmr.security.AuthenticationService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * The Disposition Lifecycle Job Finds all disposition action nodes which are - * for disposition actions specified Where asOf > now OR - * dispositionEventsEligible = true; - * - * Runs the cut off or retain action for - * eligible records. + * The Disposition Lifecycle Job Finds all disposition action nodes which are for disposition actions specified Where + * asOf > now OR dispositionEventsEligible = true; Runs the cut off or retain action for eligible records. * * @author mrogers * @author Roy Wetherall @@ -77,10 +74,13 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute /** search service */ private SearchService searchService; + /** authenticationService service */ + private AuthenticationService authenticationService; + /** * List of disposition actions to automatically execute when eligible. * - * @param dispositionActions disposition actions + * @param dispositionActions disposition actions */ public void setDispositionActions(List dispositionActions) { @@ -88,7 +88,7 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute } /** - * @param recordsManagementActionService records management action service + * @param recordsManagementActionService records management action service */ public void setRecordsManagementActionService(RecordsManagementActionService recordsManagementActionService) { @@ -96,7 +96,7 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute } /** - * @param nodeService node service + * @param nodeService node service */ public void setNodeService(NodeService nodeService) { @@ -114,7 +114,7 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute /** * Get the search query string. * - * @return job query string + * @return job query string */ protected String getQuery() { @@ -165,7 +165,8 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute if (dispositionActions != null && !dispositionActions.isEmpty()) { // execute search - ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_FTS_ALFRESCO, getQuery()); + ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, + SearchService.LANGUAGE_FTS_ALFRESCO, getQuery()); List resultNodes = results.getNodeRefs(); results.close(); @@ -183,7 +184,8 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute { public Boolean execute() { - final String dispAction = (String) nodeService.getProperty(currentNode, RecordsManagementModel.PROP_DISPOSITION_ACTION); + final String dispAction = (String) nodeService.getProperty(currentNode, + RecordsManagementModel.PROP_DISPOSITION_ACTION); // Run disposition action if (dispAction != null && dispositionActions.contains(dispAction)) @@ -192,12 +194,14 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute if (parent.getTypeQName().equals(RecordsManagementModel.ASSOC_NEXT_DISPOSITION_ACTION)) { Map props = new HashMap(1); - props.put(RMDispositionActionExecuterAbstractBase.PARAM_NO_ERROR_CHECK, Boolean.FALSE); + props.put(RMDispositionActionExecuterAbstractBase.PARAM_NO_ERROR_CHECK, + Boolean.FALSE); try { // execute disposition action - recordsManagementActionService.executeRecordsManagementAction(parent.getParentRef(), dispAction, props); + recordsManagementActionService.executeRecordsManagementAction( + parent.getParentRef(), dispAction, props); if (logger.isDebugEnabled()) { @@ -236,4 +240,14 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute } } } + + public AuthenticationService getAuthenticationService() + { + return authenticationService; + } + + public void setAuthenticationService(AuthenticationService authenticationService) + { + this.authenticationService = authenticationService; + } } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java index e885782798..a1dc0c3a65 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java @@ -42,7 +42,6 @@ import org.apache.commons.logging.LogFactory; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; -import org.springframework.scheduling.quartz.QuartzJobBean; /** * Base records management job implementation. @@ -55,14 +54,14 @@ public class RecordsManagementJob implements Job { private static Log logger = LogFactory.getLog(RecordsManagementJob.class); - /** indicates whether the audit history should be run as admin or not */ - private boolean runAsAdmin = false; + /** which user should be used to log audit */ + private String runAuditAs = AuthenticationUtil.getSystemUserName(); private static final long DEFAULT_TIME = 30000L; private JobLockService jobLockService; - private RecordsManagementJobExecuter jobExecuter; + private RecordsManagementJobExecuter jobExecuter = null; private String jobName; @@ -105,9 +104,12 @@ public class RecordsManagementJob implements Job } } - @Override + /** + * @see org.quartz.Job#execute(org.quartz.JobExecutionContext) + */ public void execute(JobExecutionContext context) throws JobExecutionException { + // get the job lock service jobLockService = (JobLockService) context.getJobDetail().getJobDataMap().get("jobLockService"); if (jobLockService == null) { throw new AlfrescoRuntimeException("Job lock service has not been specified."); } @@ -118,9 +120,35 @@ public class RecordsManagementJob implements Job // get the job name jobName = (String) context.getJobDetail().getJobDataMap().get("jobName"); + if (jobName == null) { throw new AlfrescoRuntimeException("Job name has not been specified."); } - setRunAsAdmin(Boolean.parseBoolean((String) context.getJobDetail().getJobDataMap().get("runAsAdmin"))); + if (jobName.compareTo("dispositionLifecycle") == 0) + { + //RM-3293 - set user for audit + if (jobExecuter instanceof DispositionLifecycleJobExecuter) + { + String auditUser = (String) context.getJobDetail().getJobDataMap().get("runAuditAs"); + if (((DispositionLifecycleJobExecuter) jobExecuter).getAuthenticationService() + .authenticationExists(auditUser)) + { + + setRunAuditAs(auditUser); + } + else + { + setRunAuditAs(AuthenticationUtil.getSystemUserName()); + } + + } + + if (logger.isDebugEnabled()) + { + logger.debug("DispositionLifecycleJobExecuter() logged audit history with user: " + getRunAuditAs()); + + } + + } final LockCallback lockCallback = new LockCallback(); @@ -160,17 +188,18 @@ public class RecordsManagementJob implements Job // return return null; } - }, this.runAsAdmin ? AuthenticationUtil.getAdminUserName() : AuthenticationUtil.getSystemUserName()); + }, getRunAuditAs()); } - public boolean isRunAsAdmin() + public String getRunAuditAs() { - return runAsAdmin; + return runAuditAs; } - public void setRunAsAdmin(boolean runAsAdmin) + public void setRunAuditAs(String runAuditAs) { - this.runAsAdmin = runAsAdmin; + + this.runAuditAs = runAuditAs; } } From b626bfd888eddce898b1923947b90b530b5f8733 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Fri, 24 Jun 2016 12:08:41 +0300 Subject: [PATCH 30/33] Run the code as system, as some users may not have the rights to add the aspect. --- .../model/rma/aspect/RecordAspect.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java index 16bf1078d1..41cfd0440b 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java @@ -159,8 +159,17 @@ public class RecordAspect extends AbstractDisposableItem // Deal with versioned records if (reference.equals(CUSTOM_REF_VERSIONS)) { - // Apply the versioned aspect to the from node - nodeService.addAspect(fromNodeRef, ASPECT_VERSIONED_RECORD, null); + // run as system, to apply the versioned aspect to the from node + // as we can't be sure if the user has add aspect rights + authenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + nodeService.addAspect(fromNodeRef, ASPECT_VERSIONED_RECORD, null); + return null; + } + }); } // Execute script if for the reference event From 5f8225360a1f322d2522171edc04aa7a54da41b3 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu-Ghetu Date: Fri, 24 Jun 2016 17:43:52 +0300 Subject: [PATCH 31/33] no message --- .../org_alfresco_module_rm/model/rma/aspect/RecordAspect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java index 41cfd0440b..2d266a39ea 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java @@ -154,7 +154,7 @@ public class RecordAspect extends AbstractDisposableItem kind = BehaviourKind.CLASS, notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT ) - public void onCreateReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) + public void onCreateReference(final NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) { // Deal with versioned records if (reference.equals(CUSTOM_REF_VERSIONS)) From 006f46dc7466f1404afd55f8f723060fa1c9b81d Mon Sep 17 00:00:00 2001 From: Mihai Cozma Date: Tue, 28 Jun 2016 11:28:01 +0300 Subject: [PATCH 32/33] Revert dispositionlifecycletrigger to 0 0/5 * * * ? --- .../module/org_alfresco_module_rm/alfresco-global.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties index 8391868971..505f28255b 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties @@ -49,7 +49,7 @@ rm.autocompletesuggestion.nodeParameterSuggester.aspectsAndTypes=rma:record,cm:c # # Global RM disposition lifecycle trigger cron job expression # -rm.dispositionlifecycletrigger.cronexpression=0 0/2 * * * ? +rm.dispositionlifecycletrigger.cronexpression=0 0/5 * * * ? # # Records contributors group From 9ff616467e29fbb47ed1bb6d4d978a07c9d13784 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 29 Jun 2016 14:34:39 +1000 Subject: [PATCH 33/33] Missing license headers --- .../integration/issue/rm3314/RM3314Test.java | 20 +++++++++++++------ .../issue/rm3314/RM3314TestListener.java | 20 +++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java index 7bc0a982bf..c4068d010a 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java @@ -1,20 +1,28 @@ /* - * Copyright (C) 2005-2016 Alfresco Software Limited. - * - * This file is part of Alfresco - * + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - * 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 . + * #L% */ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue.rm3314; diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java index d162d0fe95..dc71f608ae 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java @@ -1,20 +1,28 @@ /* - * Copyright (C) 2005-2014 Alfresco Software Limited. - * - * This file is part of Alfresco - * + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - * 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 . + * #L% */ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue.rm3314;