From 253b1698f0aef6e5434401420fad68a3581694de Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 1 May 2014 16:04:55 +0000 Subject: [PATCH 1/9] Create V2.1.0.x branch from HEAD r56859 build 630, to host hotfixes git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@68558 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 From 5510969068fc0e2a4ea9cf24f6daaf710fa3de3e Mon Sep 17 00:00:00 2001 From: Samuel Langlois Date: Thu, 1 May 2014 16:18:05 +0000 Subject: [PATCH 2/9] Change base Alfresco version from 4.2.0-RC4 to 4.2.0 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@68559 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 454a46e927..afb6ace3a1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,7 +15,7 @@ alfrescoEnterpriseMavenPwd= # set to org.alfresco.enterprise when enterprise version required alfrescoGroupId=org.alfresco -alfrescoBaseVersion=4.2.0-RC4 +alfrescoBaseVersion=4.2.0 # indicates whether this is a local build or not localBuild=true From f644f97ebe6ebb2c177bf3056c3ca6757ff2ff5c Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Fri, 2 May 2014 03:31:42 +0000 Subject: [PATCH 3/9] Merge from HEAD to BRANCHES/V2.1.0.x * 61170 - RM-1413: DispositionLifecycleJobExecuter does not execute the disposition action git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@68568 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org_alfresco_module_rm/log4j.properties | 10 +- .../org_alfresco_module_rm/rm-job-context.xml | 19 +- .../job/DispositionLifecycleJobExecuter.java | 167 ++++++++++++------ 3 files changed, 142 insertions(+), 54 deletions(-) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties index b5bdc8f089..7039db6a8f 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties @@ -18,4 +18,12 @@ log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info #log4j.logger.org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImpl=debug #log4j.logger.org.springframework.extensions.webscripts.ScriptDebugger=on -#log4j.logger.org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService=debug \ No newline at end of file +# +# RM Audit service debug +# +#log4j.logger.org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService=debug + +# +# Job debug +# +#log4j.logger.org.alfresco.module.org_alfresco_module_rm.job=debug diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml index 21358a322b..aa9d4a9ac9 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-job-context.xml @@ -72,6 +72,15 @@ + + + + + cutoff + retain + + + @@ -85,8 +94,16 @@ + + - 0 0/15 * * * ? + + + + + + 0/30 * * * * ? + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java index 141be63303..0dc25b859c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java @@ -40,39 +40,111 @@ import org.apache.commons.logging.LogFactory; /** * The Disposition Lifecycle Job Finds all disposition action nodes which are - * for "retain" or "cutOff" actions Where asOf > now OR - * dispositionEventsEligible = true; - * + * for disposition actions specified Where asOf > now OR + * dispositionEventsEligible = true; + * * Runs the cut off or retain action for - * elligible records. - * + * eligible records. + * * @author mrogers + * @author Roy Wetherall */ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecuter { + /** logger */ private static Log logger = LogFactory.getLog(DispositionLifecycleJobExecuter.class); + + /** list of disposition actions to automatically execute */ + private List dispositionActions; + + /** query string */ + private String query; + /** records management action service */ private RecordsManagementActionService recordsManagementActionService; - + + /** node service */ private NodeService nodeService; - + + /** search service */ private SearchService searchService; + + /** + * List of disposition actions to automatically execute when eligible. + * + * @param dispositionActions disposition actions + */ + public void setDispositionActions(List dispositionActions) + { + this.dispositionActions = dispositionActions; + } + /** + * @param recordsManagementActionService records management action service + */ public void setRecordsManagementActionService(RecordsManagementActionService recordsManagementActionService) { this.recordsManagementActionService = recordsManagementActionService; } - + + /** + * @param nodeService node service + */ public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } - + + /** + * @param searchService search service + */ public void setSearchService(SearchService searchService) { this.searchService = searchService; } + /** + * Get the search query string. + * + * @return job query string + */ + private String getQuery() + { + if (query == null) + { + StringBuilder sb = new StringBuilder(); + + sb.append("+TYPE:\"rma:dispositionAction\" "); + sb.append("+(@rma\\:dispositionAction:("); + + boolean bFirst = true; + for (String dispositionAction : dispositionActions) + { + if (bFirst) + { + bFirst = false; + } + else + { + sb.append(" OR "); + } + + sb.append("\"").append(dispositionAction).append("\""); + } + + sb.append("))"); + sb.append("+ISNULL:\"rma:dispositionActionCompletedAt\" "); + sb.append("+( "); + sb.append("@rma\\:dispositionEventsEligible:true "); + sb.append("OR @rma\\:dispositionAsOf:[MIN TO NOW] "); + sb.append(") "); + + query = sb.toString(); + } + + return query; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJobExecuter#execute() */ @@ -81,75 +153,66 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute try { logger.debug("Job Starting"); - - StringBuilder sb = new StringBuilder(); - sb.append("+TYPE:\"rma:dispositionAction\" "); - sb.append("+(@rma\\:dispositionAction:(\"cutoff\" OR \"retain\"))"); - sb.append("+ISNULL:\"rma:dispositionActionCompletedAt\" "); - sb.append("+( "); - sb.append("@rma\\:dispositionEventsEligible:true "); - sb.append("OR @rma\\:dispositionAsOf:[MIN TO NOW] "); - sb.append(") "); - - String query = sb.toString(); - - ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, - SearchService.LANGUAGE_LUCENE, query); - List resultNodes = results.getNodeRefs(); - results.close(); - - - for (NodeRef node : resultNodes) + + if (dispositionActions != null && !dispositionActions.isEmpty()) { - final NodeRef currentNode = node; + // execute search + ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, getQuery()); + List resultNodes = results.getNodeRefs(); + results.close(); - RetryingTransactionCallback processTranCB = new RetryingTransactionCallback() + if (logger.isDebugEnabled()) { - public Boolean execute() throws Throwable + logger.debug("Processing " + resultNodes.size() + " nodes"); + } + + // process search results + for (NodeRef node : resultNodes) + { + final NodeRef currentNode = node; + + RetryingTransactionCallback processTranCB = new RetryingTransactionCallback() { - final String dispAction = (String) nodeService.getProperty(currentNode, - RecordsManagementModel.PROP_DISPOSITION_ACTION); - - // Run "retain" and "cutoff" actions. - - if (dispAction != null) + public Boolean execute() throws Throwable { - if (dispAction.equalsIgnoreCase("cutoff") || - dispAction.equalsIgnoreCase("retain")) + final String dispAction = (String) nodeService.getProperty(currentNode, RecordsManagementModel.PROP_DISPOSITION_ACTION); + + // Run disposition action + if (dispAction != null && dispositionActions.contains(dispAction)) { ChildAssociationRef parent = nodeService.getPrimaryParent(currentNode); if (parent.getTypeQName().equals(RecordsManagementModel.ASSOC_NEXT_DISPOSITION_ACTION)) { Map props = new HashMap(1); props.put(RMDispositionActionExecuterAbstractBase.PARAM_NO_ERROR_CHECK, Boolean.FALSE); + + // execute disposition action recordsManagementActionService.executeRecordsManagementAction(parent.getParentRef(), dispAction, props); + if (logger.isDebugEnabled()) { logger.debug("Processed action: " + dispAction + "on" + parent); } } - return null; } + + return Boolean.TRUE; } - return Boolean.TRUE; + }; + + // if exists + if (nodeService.exists(currentNode)) + { + retryingTransactionHelper.doInTransaction(processTranCB); } - }; - - /** - * Now do the work, one action in each transaction - */ - - if (nodeService.exists(currentNode) == false) - { - retryingTransactionHelper.doInTransaction(processTranCB); } } - + logger.debug("Job Finished"); } catch (AlfrescoRuntimeException exception) { - if (logger.isDebugEnabled() == true) + if (logger.isDebugEnabled()) { logger.debug(exception); } From a5a236db9661753c5ab883430a176499ae10e249 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Fri, 2 May 2014 03:45:06 +0000 Subject: [PATCH 4/9] Update module version to 2.1.0.1 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@68569 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- gradle.properties | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index afb6ace3a1..4aa7cc4c10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # build details groupid=alfresco packageName=rm -version=2.1.0 +version=2.1.0.1 build=dev # maven urls's 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 6f31dc07f2..79697c6903 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.1 +module.version=2.1.0.1 module.repo.version.min=4.2 \ No newline at end of file From 153cd48616732085bbb9ecb5047414980bffac2f Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 15 Jul 2014 00:48:34 +0000 Subject: [PATCH 5/9] Merge HEAD to BRANCHES/V2.1.0.x: * 74458 - RM Performance Improvements * general file plan browse rendering in around half the previously recorded times for around 500 records (need to scale up) * unessesary bottle neck removed from record detail page rendering (see RM-1461) * other general improvements * TODO .. hasFrozenChildren, getNextDisposition, TransferNodeIndicator, HeldBy .. all traverse up or down record/record folder hierarchy in ways that don't scale * fix to disposition lifecycle job that failed all when one failed .. this explains why the job appeared not to work on occasion git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@76475 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../rm-capabilities-condition-context.xml | 4 +- .../rm-service-context.xml | 4 +- .../RecordsManagementServiceImpl.java | 18 +- .../action/RMActionExecuterAbstractBase.java | 2 +- .../RecordsManagementAdminServiceImpl.java | 9 +- .../capability/RMSecurityCommon.java | 16 +- .../disposition/DispositionServiceImpl.java | 2 +- .../fileplan/FilePlanServiceImpl.java | 180 +------ .../freeze/FreezeServiceImpl.java | 2 +- .../job/DispositionLifecycleJobExecuter.java | 20 +- .../record/RecordServiceImpl.java | 39 +- .../util/ServiceBaseImpl.java | 493 +++++++++++++++--- 12 files changed, 447 insertions(+), 342 deletions(-) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml index 0085ecb34e..f05e10e3e8 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml @@ -8,8 +8,8 @@ - - + + 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 dc9a296198..98829ee9df 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 @@ -1130,9 +1130,7 @@ - - - + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java index 5e0178e2c5..518454f941 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java @@ -48,9 +48,6 @@ import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.ParameterCheck; import org.alfresco.util.PropertyMap; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.extensions.surf.util.I18NUtil; /** @@ -62,8 +59,7 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl implements RecordsManagementService, RecordsManagementModel, RecordsManagementPolicies.OnCreateReference, - RecordsManagementPolicies.OnRemoveReference, - ApplicationContextAware + RecordsManagementPolicies.OnRemoveReference { /** I18N */ private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container"; @@ -91,18 +87,6 @@ public class RecordsManagementServiceImpl extends ServiceBaseImpl /** Java behaviour */ private JavaBehaviour onChangeToDispositionActionDefinition; - /** Application context */ - private ApplicationContext applicationContext; - - /** - * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) - */ - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException - { - this.applicationContext = applicationContext; - } - /** * Set the service registry service * diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java index 0d6d1b7a6c..9212dc764c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java @@ -489,7 +489,7 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe NodeRef currentDispositionAction = null; if (this.nodeService.hasAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE) == true) { - List assocs = this.nodeService.getChildAssocs(nodeRef, ASSOC_NEXT_DISPOSITION_ACTION, RegexQNamePattern.MATCH_ALL); + List assocs = this.nodeService.getChildAssocs(nodeRef, ASSOC_NEXT_DISPOSITION_ACTION, ASSOC_NEXT_DISPOSITION_ACTION); if (assocs.size() > 0) { currentDispositionAction = assocs.get(0).getChildRef(); 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 afe04b98bc..b18894b196 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 @@ -55,10 +55,10 @@ import org.alfresco.repo.dictionary.M2Model; import org.alfresco.repo.dictionary.M2Namespace; import org.alfresco.repo.dictionary.M2Property; import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.ClassPolicyDelegate; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; -import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.dictionary.AspectDefinition; @@ -80,7 +80,6 @@ import org.alfresco.service.cmr.repository.NodeService; 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.util.GUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -1155,8 +1154,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public List getCustomReferencesFrom(NodeRef node) { - List retrievedAssocs = nodeService.getTargetAssocs(node, RegexQNamePattern.MATCH_ALL); - return retrievedAssocs; + return nodeService.getTargetAssocs(node, null); } /** @@ -1173,8 +1171,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public List getCustomReferencesTo(NodeRef node) { - List retrievedAssocs = nodeService.getSourceAssocs(node, RegexQNamePattern.MATCH_ALL); - return retrievedAssocs; + return nodeService.getSourceAssocs(node, null); } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java index fc90081c1d..51c70b7bfc 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java @@ -204,19 +204,6 @@ public class RMSecurityCommon return result; } - // Get the file plan for the node - NodeRef filePlan = filePlanService.getFilePlan(nodeRef); - - // Admin role - //if (permissionService.hasPermission(filePlan, RMPermissionModel.ROLE_ADMINISTRATOR) == AccessStatus.ALLOWED) - //{ - // if (logger.isDebugEnabled()) - // { - // logger.debug("\t\tAdmin user, access granted. (nodeRef=" + nodeRef.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); - // } - // return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_GRANTED); - // } - if (permissionService.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS) == AccessStatus.DENIED) { if (logger.isDebugEnabled()) @@ -226,6 +213,9 @@ public class RMSecurityCommon return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED); } + // Get the file plan for the node + NodeRef filePlan = filePlanService.getFilePlan(nodeRef); + if (permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS) == AccessStatus.DENIED) { if (logger.isDebugEnabled()) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index a3e8882f82..3366f2cf01 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -796,7 +796,7 @@ public class DispositionServiceImpl implements private NodeRef getNextDispositionActionNodeRef(NodeRef nodeRef) { NodeRef result = null; - List assocs = nodeService.getChildAssocs(nodeRef, ASSOC_NEXT_DISPOSITION_ACTION, RegexQNamePattern.MATCH_ALL); + List assocs = nodeService.getChildAssocs(nodeRef, ASSOC_NEXT_DISPOSITION_ACTION, ASSOC_NEXT_DISPOSITION_ACTION, 1, true); if (assocs.size() != 0) { result = assocs.get(0).getChildRef(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java index 28942f6497..d62a21da56 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java @@ -52,9 +52,6 @@ import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.Pair; import org.alfresco.util.ParameterCheck; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.extensions.surf.util.I18NUtil; /** @@ -65,8 +62,7 @@ import org.springframework.extensions.surf.util.I18NUtil; */ public class FilePlanServiceImpl extends ServiceBaseImpl implements FilePlanService, - RecordsManagementModel, - ApplicationContextAware + RecordsManagementModel { /** I18N */ private final static String MSG_DUP_ROOT = "rm.service.dup-root"; @@ -86,18 +82,6 @@ public class FilePlanServiceImpl extends ServiceBaseImpl /** RM site file plan container */ private static final String FILE_PLAN_CONTAINER = "documentLibrary"; - /** Application context */ - private ApplicationContext applicationContext; - - /** - * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) - */ - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException - { - this.applicationContext = applicationContext; - } - /** * NOTE: for some reason spring couldn't cope with the circular references between these two * beans so we need to grab this one manually. @@ -173,121 +157,6 @@ public class FilePlanServiceImpl extends ServiceBaseImpl return (RecordsManagementService)applicationContext.getBean("RecordsManagementService"); } - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isFilePlanComponent(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isFilePlanComponent(NodeRef nodeRef) - { - boolean result = false; - if (getInternalNodeService().exists(nodeRef) == true && - getInternalNodeService().hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT) == true) - { - result = true; - } - return result; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlanComponentKind(org.alfresco.service.cmr.repository.NodeRef) - */ - public FilePlanComponentKind getFilePlanComponentKind(NodeRef nodeRef) - { - FilePlanComponentKind result = null; - - if (isFilePlanComponent(nodeRef) == true) - { - result = FilePlanComponentKind.FILE_PLAN_COMPONENT; - - if (isFilePlan(nodeRef) == true) - { - result = FilePlanComponentKind.FILE_PLAN; - } - else if (isRecordCategory(nodeRef) == true) - { - result = FilePlanComponentKind.RECORD_CATEGORY; - } - else if (getRecordsManagementService().isRecordFolder(nodeRef) == true) - { - result = FilePlanComponentKind.RECORD_FOLDER; - } - else if (getRecordService().isRecord(nodeRef) == true) - { - result = FilePlanComponentKind.RECORD; - } - else if (getFreezeService().isHold(nodeRef) == true) - { - result = FilePlanComponentKind.HOLD; - } - else if (getRecordsManagementService().isTransfer(nodeRef) == true) - { - result = FilePlanComponentKind.TRANSFER; - } - else if (instanceOf(nodeRef, TYPE_DISPOSITION_SCHEDULE) == true || instanceOf(nodeRef, TYPE_DISPOSITION_ACTION_DEFINITION) == true) - { - result = FilePlanComponentKind.DISPOSITION_SCHEDULE; - } - else if (instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER) == true) - { - result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER; - } - } - - return result; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementService#getFilePlanComponentKindFromType(org.alfresco.service.namespace.QName) - */ - @Override - public FilePlanComponentKind getFilePlanComponentKindFromType(QName type) - { - FilePlanComponentKind result = null; - - if (ASPECT_FILE_PLAN_COMPONENT.equals(type) == true) - { - result = FilePlanComponentKind.FILE_PLAN_COMPONENT; - } - else if (dictionaryService.isSubClass(type, ASPECT_RECORD) == true) - { - result = FilePlanComponentKind.RECORD; - } - else if (dictionaryService.isSubClass(type, TYPE_FILE_PLAN) == true) - { - result = FilePlanComponentKind.FILE_PLAN; - } - else if (dictionaryService.isSubClass(type, TYPE_RECORD_CATEGORY) == true) - { - result = FilePlanComponentKind.RECORD_CATEGORY; - } - else if (dictionaryService.isSubClass(type, TYPE_RECORD_FOLDER) == true) - { - result = FilePlanComponentKind.RECORD_FOLDER; - } - else if (dictionaryService.isSubClass(type, TYPE_HOLD) == true) - { - result = FilePlanComponentKind.HOLD; - } - else if (dictionaryService.isSubClass(type, TYPE_TRANSFER) == true) - { - result = FilePlanComponentKind.TRANSFER; - } - else if (dictionaryService.isSubClass(type, TYPE_DISPOSITION_SCHEDULE) == true || - dictionaryService.isSubClass(type, TYPE_DISPOSITION_ACTION_DEFINITION) == true) - { - result = FilePlanComponentKind.DISPOSITION_SCHEDULE; - } - - return result; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isFilePlan(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isFilePlan(NodeRef nodeRef) - { - return instanceOf(nodeRef, TYPE_FILE_PLAN); - } - /** * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlans() */ @@ -325,36 +194,6 @@ public class FilePlanServiceImpl extends ServiceBaseImpl return results; } - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlan(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public NodeRef getFilePlan(NodeRef nodeRef) - { - NodeRef result = null; - if (nodeRef != null) - { - result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); - if (result == null) - { - if (instanceOf(nodeRef, TYPE_FILE_PLAN) == true) - { - result = nodeRef; - } - else - { - ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); - if (parentAssocRef != null) - { - result = getFilePlan(parentAssocRef.getParentRef()); - } - } - } - } - - return result; - } - /** * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlanBySiteId(java.lang.String) */ @@ -640,23 +479,6 @@ public class FilePlanServiceImpl extends ServiceBaseImpl } } - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isFilePlanContainer(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public boolean isFilePlanContainer(NodeRef nodeRef) - { - return instanceOf(nodeRef, TYPE_RECORDS_MANAGEMENT_CONTAINER); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isRecordCategory(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isRecordCategory(NodeRef nodeRef) - { - return instanceOf(nodeRef, TYPE_RECORD_CATEGORY); - } - /** * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#createRecordCategory(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, java.util.Map) */ diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java index 5c65630f02..3ab9bd3a60 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java @@ -164,7 +164,7 @@ public class FreezeServiceImpl extends ServiceBaseImpl public Void doWork() throws Exception { if (nodeService.exists(nodeRef) == true && - filePlanService.isFilePlanComponent(nodeRef) == true) + nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT) == true) { if (isFrozen(nodeRef) == true) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java index 0dc25b859c..37df9d68b5 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java @@ -186,12 +186,22 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute Map props = new HashMap(1); props.put(RMDispositionActionExecuterAbstractBase.PARAM_NO_ERROR_CHECK, Boolean.FALSE); - // execute disposition action - recordsManagementActionService.executeRecordsManagementAction(parent.getParentRef(), dispAction, props); - - if (logger.isDebugEnabled()) + try { - logger.debug("Processed action: " + dispAction + "on" + parent); + // execute disposition action + recordsManagementActionService.executeRecordsManagementAction(parent.getParentRef(), dispAction, props); + + if (logger.isDebugEnabled()) + { + logger.debug("Processed action: " + dispAction + "on" + parent); + } + } + catch (AlfrescoRuntimeException exception) + { + if (logger.isDebugEnabled()) + { + logger.debug(exception); + } } } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index 491c3248a7..3684f952ee 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -46,6 +46,7 @@ import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagement import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.role.Role; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; +import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordServiceImpl; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; @@ -84,9 +85,6 @@ import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; /** * Record service implementation. @@ -94,12 +92,12 @@ import org.springframework.context.ApplicationContextAware; * @author Roy Wetherall * @since 2.1 */ -public class RecordServiceImpl implements RecordService, +public class RecordServiceImpl extends ServiceBaseImpl + implements RecordService, RecordsManagementModel, RecordsManagementCustomModel, NodeServicePolicies.OnCreateChildAssociationPolicy, NodeServicePolicies.OnUpdatePropertiesPolicy, - ApplicationContextAware, NodeServicePolicies.OnAddAspectPolicy, NodeServicePolicies.OnRemoveAspectPolicy { @@ -142,9 +140,6 @@ public class RecordServiceImpl implements RecordService, NamespaceService.REPOSITORY_VIEW_1_0_URI }; - - /** Application context */ - private ApplicationContext applicationContext; /** Node service **/ private NodeService nodeService; @@ -209,12 +204,6 @@ public class RecordServiceImpl implements RecordService, "onDeleteDeclaredRecordLink", NotificationFrequency.FIRST_EVENT); - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException - { - this.applicationContext = applicationContext; - } - /** * @param nodeService node service */ @@ -624,28 +613,6 @@ public class RecordServiceImpl implements RecordService, return recordMetaDataAspects; } - /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isRecord(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public boolean isRecord(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - return nodeService.hasAspect(nodeRef, ASPECT_RECORD); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public boolean isDeclared(NodeRef record) - { - ParameterCheck.mandatory("record", record); - - return nodeService.hasAspect(record, ASPECT_DECLARED_RECORD); - } - /** * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) */ diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java index 609440e3dc..10187b259b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java @@ -18,13 +18,22 @@ */ package org.alfresco.module.org_alfresco_module_rm.util; +import java.util.Set; + +import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; +import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ParameterCheck; import org.alfresco.util.PropertyMap; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; /** * Helper base class for service implementations. @@ -32,83 +41,411 @@ import org.alfresco.util.PropertyMap; * @author Roy Wetherall * @since 2.1 */ -public class ServiceBaseImpl implements RecordsManagementModel +public class ServiceBaseImpl implements RecordsManagementModel, ApplicationContextAware { - /** Node service */ - protected NodeService nodeService; - - /** Dictionary service */ - protected DictionaryService dictionaryService; - - /** - * @param nodeService node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @param dictionaryService dictionary service - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * Utility method to safely and quickly determine if a node is a type (or sub-type) of the one specified. - * - * @param nodeRef node reference - * @param ofClassName class name to check - */ - protected boolean instanceOf(NodeRef nodeRef, QName ofClassName) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - ParameterCheck.mandatory("ofClassName", ofClassName); - boolean result = false; - if (nodeService.exists(nodeRef) == true && - (ofClassName.equals(nodeService.getType(nodeRef)) == true || - dictionaryService.isSubClass(nodeService.getType(nodeRef), ofClassName) == true)) - { - result = true; - } - return result; - } - - /** - * Utility method to get the next counter for a node. - *

- * If the node is not already countable, then rma:countable is added and 0 returned. - * - * @param nodeRef node reference - * @return int next counter value - */ - protected int getNextCount(NodeRef nodeRef) - { - int counter = 0; - if (nodeService.hasAspect(nodeRef, ASPECT_COUNTABLE) == false) - { - PropertyMap props = new PropertyMap(1); - props.put(PROP_COUNT, 1); - nodeService.addAspect(nodeRef, ASPECT_COUNTABLE, props); - counter = 1; - } - else - { - Integer value = (Integer)this.nodeService.getProperty(nodeRef, PROP_COUNT); - if (value != null) - { - counter = value.intValue() + 1; - } - else - { - counter = 1; - } - nodeService.setProperty(nodeRef, PROP_COUNT, counter); - - } - return counter; - } - + /** Node service */ + protected NodeService nodeService; + + /** Dictionary service */ + protected DictionaryService dictionaryService; + + /** Application context */ + protected ApplicationContext applicationContext; + + /** internal node service */ + private NodeService internalNodeService; + + /** + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) + { + this.applicationContext = applicationContext; + } + + /** + * @param nodeService node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param dictionaryService dictionary service + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * Helper to get internal node service. + *

+ * Used for performance reasons. + */ + private NodeService getInternalNodeService() + { + if (internalNodeService == null) + { + internalNodeService = (NodeService)applicationContext.getBean("dbNodeService"); + } + + return internalNodeService; + } + + /** + * Gets the file plan component kind from the given node reference + * + * @see FilePlanService#getFilePlanComponentKind(org.alfresco.service.cmr.repository.NodeRef) + */ + public FilePlanComponentKind getFilePlanComponentKind(NodeRef nodeRef) + { + FilePlanComponentKind result = null; + + if (isFilePlanComponent(nodeRef)) + { + result = FilePlanComponentKind.FILE_PLAN_COMPONENT; + + if (isFilePlan(nodeRef)) + { + result = FilePlanComponentKind.FILE_PLAN; + } + else if (isRecordCategory(nodeRef)) + { + result = FilePlanComponentKind.RECORD_CATEGORY; + } + else if (isRecordFolder(nodeRef)) + { + result = FilePlanComponentKind.RECORD_FOLDER; + } + else if (isRecord(nodeRef)) + { + result = FilePlanComponentKind.RECORD; + } + else if (isHold(nodeRef)) + { + result = FilePlanComponentKind.HOLD; + } + else if (isTransfer(nodeRef)) + { + result = FilePlanComponentKind.TRANSFER; + } + else if (instanceOf(nodeRef, TYPE_DISPOSITION_SCHEDULE) || instanceOf(nodeRef, TYPE_DISPOSITION_ACTION_DEFINITION)) + { + result = FilePlanComponentKind.DISPOSITION_SCHEDULE; + } + else if (instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER)) + { + result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER; + } + } + + return result; + } + + /** + * Gets the file plan component kind from the given type. + * + * @see FilePlanService#getFilePlanComponentKindFromType(QName) + */ + public FilePlanComponentKind getFilePlanComponentKindFromType(QName type) + { + FilePlanComponentKind result = null; + + if (ASPECT_FILE_PLAN_COMPONENT.equals(type)) + { + result = FilePlanComponentKind.FILE_PLAN_COMPONENT; + } + else if (instanceOf(type, ASPECT_RECORD)) + { + result = FilePlanComponentKind.RECORD; + } + else if (instanceOf(type, TYPE_FILE_PLAN)) + { + result = FilePlanComponentKind.FILE_PLAN; + } + else if (instanceOf(type, TYPE_RECORD_CATEGORY)) + { + result = FilePlanComponentKind.RECORD_CATEGORY; + } + else if (instanceOf(type, TYPE_RECORD_FOLDER)) + { + result = FilePlanComponentKind.RECORD_FOLDER; + } + else if (instanceOf(type, TYPE_HOLD)) + { + result = FilePlanComponentKind.HOLD; + } + else if (instanceOf(type, TYPE_TRANSFER)) + { + result = FilePlanComponentKind.TRANSFER; + } + else if (instanceOf(type, TYPE_DISPOSITION_SCHEDULE) || + instanceOf(type, TYPE_DISPOSITION_ACTION_DEFINITION)) + { + result = FilePlanComponentKind.DISPOSITION_SCHEDULE; + } + + return result; + } + + /** + * Indicates whether the given node is a file plan component or not. + *

+ * Exposed in the FilePlan service. + * + * @see FilePlanService#isFilePlanComponent(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isFilePlanComponent(NodeRef nodeRef) + { + boolean result = false; + if (getInternalNodeService().exists(nodeRef) && + getInternalNodeService().hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT)) + { + result = true; + } + return result; + } + + /** + * Indicates whether the given node is a file plan or not. + *

+ * Exposed in the FilePlan service. + * + * @see FilePlanService#isFilePlan(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isFilePlan(NodeRef nodeRef) + { + return instanceOf(nodeRef, TYPE_FILE_PLAN); + } + + /** + * Indicates whether the given node is a file plan container or not. + * + * @see FilePlanService#isFilePlanContainer(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isFilePlanContainer(NodeRef nodeRef) + { + return instanceOf(nodeRef, TYPE_RECORDS_MANAGEMENT_CONTAINER); + } + + /** + * Indicates whether the given node is a record category or not. + * + * @see FilePlanService#isRecordCategory(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isRecordCategory(NodeRef nodeRef) + { + return instanceOf(nodeRef, TYPE_RECORD_CATEGORY); + } + + /** + * Indicates whether the given node is a record folder or not. + *

+ * Exposed in the RecordFolder service. + * + * @param nodeRef node reference + * @return boolean true if record folder, false otherwise + */ + public boolean isRecordFolder(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + return instanceOf(nodeRef, TYPE_RECORD_FOLDER); + } + + /** + * Indicates whether the given node reference is a record or not. + * + * @param nodeRef node reference + * @return boolean true if node reference is a record, false otherwise + */ + public boolean isRecord(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + return getInternalNodeService().hasAspect(nodeRef, ASPECT_RECORD); + } + + /** + * Indicates whether the given node reference is a hold or not. + * + * @param nodeRef node reference + * @return boolean true if rma:hold or sub-type, false otherwise + */ + public boolean isHold(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + boolean isHold = false; + if (getInternalNodeService().exists(nodeRef) && + instanceOf(nodeRef, TYPE_HOLD)) + { + isHold = true; + } + return isHold; + } + + /** + * Indicates whether the given node reference is a transfer or not. + */ + public boolean isTransfer(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + return instanceOf(nodeRef, TYPE_TRANSFER); + } + + /** + * Indicates whether a record is complete or not. + * + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isDeclared(NodeRef record) + { + ParameterCheck.mandatory("record", record); + + return getInternalNodeService().hasAspect(record, ASPECT_DECLARED_RECORD); + } + + /** + * Gets the file plan that a given file plan component resides within. + * + * @param nodeRef node reference + * @return {@link NodeRef} file plan, null if none + */ + public NodeRef getFilePlan(final NodeRef nodeRef) + { + NodeRef result = null; + if (nodeRef != null) + { + result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); + if (result == null) + { + if (instanceOf(nodeRef, TYPE_FILE_PLAN)) + { + result = nodeRef; + } + else + { + ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); + if (parentAssocRef != null) + { + result = getFilePlan(parentAssocRef.getParentRef()); + } + } + } + } + + return result; + } + + /** + * Utility method to safely and quickly determine if a node is a type (or sub-type) of the one specified. + * + * @param nodeRef node reference + * @param ofClassName class name to check + */ + protected boolean instanceOf(NodeRef nodeRef, QName ofClassName) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + ParameterCheck.mandatory("ofClassName", ofClassName); + QName className = getInternalNodeService().getType(nodeRef); + return instanceOf(className, ofClassName); + } + + /** + * Utility method to quickly determine whether one class is equal to or sub of another. + * + * @param className class name + * @param ofClassName class name to check against + * @return boolean true if equal to or sub, false otherwise + */ + protected boolean instanceOf(QName className, QName ofClassName) + { + ParameterCheck.mandatory("className", className); + ParameterCheck.mandatory("ofClassName", ofClassName); + boolean result = false; + if (ofClassName.equals(className) || + dictionaryService.isSubClass(className, ofClassName)) + { + result = true; + } + return result; + } + + /** + * Utility method to get the next counter for a node. + *

+ * If the node is not already countable, then rma:countable is added and 0 returned. + * + * @param nodeRef node reference + * @return int next counter value + */ + protected int getNextCount(NodeRef nodeRef) + { + int counter = 0; + if (!nodeService.hasAspect(nodeRef, ASPECT_COUNTABLE)) + { + PropertyMap props = new PropertyMap(1); + props.put(PROP_COUNT, 1); + nodeService.addAspect(nodeRef, ASPECT_COUNTABLE, props); + counter = 1; + } + else + { + Integer value = (Integer)this.nodeService.getProperty(nodeRef, PROP_COUNT); + if (value != null) + { + counter = value.intValue() + 1; + } + else + { + counter = 1; + } + nodeService.setProperty(nodeRef, PROP_COUNT, counter); + + } + return counter; + } + + /** + * Helper method to get a set containing the node's type and all it's aspects + * + * @param nodeRef nodeRef + * @return Set set of qname's + */ + protected Set getTypeAndApsects(NodeRef nodeRef) + { + Set result = nodeService.getAspects(nodeRef); + result.add(nodeService.getType(nodeRef)); + return result; + } + + /** + * Helper method that executed work as system user. + *

+ * Useful when testing using mocks. + * + * @param runAsWork work to execute as system user + * @return + */ + public R runAsSystem(RunAsWork runAsWork) + { + return AuthenticationUtil.runAsSystem(runAsWork); + } + + /** + * Helper method that executed work as given user. + *

+ * Useful when testing using mocks. + * + * @param runAsWork work to execute as given user + * @return + */ + public R runAs(RunAsWork runAsWork, String uid) + { + return AuthenticationUtil.runAs(runAsWork, uid); + } } From f838c103e808f26772490d5528503738c2623a20 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 16 Jul 2014 02:00:27 +0000 Subject: [PATCH 6/9] Merge HEAD to BRANCHES/V2.1.0.x: 74932: RM-1461: CLONE - RM slower then standard repo/sites when rendering document details when folder contains 15k documents git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@76597 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../model/recordsModel.xml | 15 + .../action/RMActionExecuterAbstractBase.java | 1 - .../freeze/FreezeServiceImpl.java | 69 +- .../jscript/app/JSONConversionComponent.java | 17 + .../model/RecordsManagementModel.java | 5 + .../util/ServiceBaseImpl.java | 831 +++++++++--------- .../test/service/FreezeServiceImplTest.java | 4 - 7 files changed, 522 insertions(+), 420 deletions(-) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml index f1506022ac..c88df79c68 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml @@ -272,6 +272,7 @@ rma:recordComponentIdentifier rma:commonRecordDetails rma:filePlanComponent + rma:heldChildren @@ -1213,6 +1214,20 @@ + + + + Held children + + + d:int + true + true + 0 + + + + Countable aspect diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java index 9212dc764c..42f9cd3b14 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java @@ -57,7 +57,6 @@ import org.alfresco.service.cmr.repository.Period; import org.alfresco.service.cmr.security.OwnableService; 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.PropertyCheck; import org.springframework.beans.factory.BeanNameAware; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java index 3ab9bd3a60..efa05f7217 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java @@ -42,11 +42,13 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ParameterCheck; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -191,10 +193,10 @@ public class FreezeServiceImpl extends ServiceBaseImpl for (ChildAssociationRef assoc : assocs) { // we only care about primary children - if (assoc.isPrimary() == true) + if (assoc.isPrimary()) { NodeRef nodeRef = assoc.getChildRef(); - if (isFrozen(nodeRef) == true) + if (isFrozen(nodeRef)) { // never allowed to delete a node with a frozen child throw new AccessDeniedException("Can not delete node, because it contains a frozen child node."); @@ -531,21 +533,68 @@ public class FreezeServiceImpl extends ServiceBaseImpl * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean hasFrozenChildren(NodeRef nodeRef) + public boolean hasFrozenChildren(final NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); - List childAssocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, - RegexQNamePattern.MATCH_ALL); - if (childAssocs != null && !childAssocs.isEmpty()) - { - for (ChildAssociationRef childAssociationRef : childAssocs) + boolean result = false; + + // check that we are dealing with a record folder + if (isRecordFolder(nodeRef)) + { + int heldCount = 0; + + if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN)) { - if (isFrozen(childAssociationRef.getChildRef())) { return true; } + heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT); } + else + { + final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService"); + + heldCount = AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Integer doWork() + { + return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Integer execute() throws Throwable + { + int heldCount = 0; + + // NOTE: this process remains to 'patch' older systems to improve performance next time around + List childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, null); + if (childAssocs != null && !childAssocs.isEmpty()) + { + for (ChildAssociationRef childAssociationRef : childAssocs) + { + NodeRef record = childAssociationRef.getChildRef(); + if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record)) + { + heldCount ++; + } + } + } + + // add aspect and set count + Map props = new HashMap(1); + props.put(PROP_HELD_CHILDREN_COUNT, heldCount); + getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props); + + return heldCount; + } + }, + false, true); + } + }); + } + + // true if more than one child held + result = (heldCount > 0); } - return false; + return result; } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java index b2847f5364..fad81f2ae1 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java @@ -213,6 +213,23 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC rmNodeValues.put("actions", jsonActions); } } + + /** + * @see org.alfresco.repo.jscript.app.JSONConversionComponent#permissionsToJSON(org.alfresco.service.cmr.repository.NodeRef) + */ + protected JSONObject permissionsToJSON(final NodeRef nodeRef) + { + JSONObject permissionsJSON = null; + if (!filePlanService.isFilePlanComponent(nodeRef)) + { + permissionsJSON = super.permissionsToJSON(nodeRef); + } + else + { + permissionsJSON = new JSONObject(); + } + return permissionsJSON; + } /** * Gets the rm 'type' used as a UI convenience and compatibility flag. diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java index b6e560e244..ac7441c35f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java @@ -253,6 +253,11 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel public static final QName PROP_RECORD_REJECTION_DATE = QName.createQName(RM_URI, "recordRejectionDate"); public static final QName PROP_RECORD_REJECTION_REASON = QName.createQName(RM_URI, "recordRejectionReason"); + // Held children aspect + // @since 2.2 + QName ASPECT_HELD_CHILDREN = QName.createQName(RM_URI, "heldChildren"); + QName PROP_HELD_CHILDREN_COUNT = QName.createQName(RM_URI, "heldChildrenCount"); + // Countable aspect public static final QName ASPECT_COUNTABLE = QName.createQName(RM_URI, "countable"); public static final QName PROP_COUNT = QName.createQName(RM_URI, "count"); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java index 10187b259b..c4494ab4df 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.util; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; @@ -43,409 +45,428 @@ import org.springframework.context.ApplicationContextAware; */ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationContextAware { - /** Node service */ - protected NodeService nodeService; - - /** Dictionary service */ - protected DictionaryService dictionaryService; - - /** Application context */ - protected ApplicationContext applicationContext; - - /** internal node service */ - private NodeService internalNodeService; - - /** - * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) - */ - @Override - public void setApplicationContext(ApplicationContext applicationContext) - { - this.applicationContext = applicationContext; - } - - /** - * @param nodeService node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @param dictionaryService dictionary service - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * Helper to get internal node service. - *

- * Used for performance reasons. - */ - private NodeService getInternalNodeService() - { - if (internalNodeService == null) - { - internalNodeService = (NodeService)applicationContext.getBean("dbNodeService"); - } - - return internalNodeService; - } - - /** - * Gets the file plan component kind from the given node reference - * - * @see FilePlanService#getFilePlanComponentKind(org.alfresco.service.cmr.repository.NodeRef) - */ - public FilePlanComponentKind getFilePlanComponentKind(NodeRef nodeRef) - { - FilePlanComponentKind result = null; - - if (isFilePlanComponent(nodeRef)) - { - result = FilePlanComponentKind.FILE_PLAN_COMPONENT; - - if (isFilePlan(nodeRef)) - { - result = FilePlanComponentKind.FILE_PLAN; - } - else if (isRecordCategory(nodeRef)) - { - result = FilePlanComponentKind.RECORD_CATEGORY; - } - else if (isRecordFolder(nodeRef)) - { - result = FilePlanComponentKind.RECORD_FOLDER; - } - else if (isRecord(nodeRef)) - { - result = FilePlanComponentKind.RECORD; - } - else if (isHold(nodeRef)) - { - result = FilePlanComponentKind.HOLD; - } - else if (isTransfer(nodeRef)) - { - result = FilePlanComponentKind.TRANSFER; - } - else if (instanceOf(nodeRef, TYPE_DISPOSITION_SCHEDULE) || instanceOf(nodeRef, TYPE_DISPOSITION_ACTION_DEFINITION)) - { - result = FilePlanComponentKind.DISPOSITION_SCHEDULE; - } - else if (instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER)) - { - result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER; - } - } - - return result; - } - - /** - * Gets the file plan component kind from the given type. - * - * @see FilePlanService#getFilePlanComponentKindFromType(QName) - */ - public FilePlanComponentKind getFilePlanComponentKindFromType(QName type) - { - FilePlanComponentKind result = null; - - if (ASPECT_FILE_PLAN_COMPONENT.equals(type)) - { - result = FilePlanComponentKind.FILE_PLAN_COMPONENT; - } - else if (instanceOf(type, ASPECT_RECORD)) - { - result = FilePlanComponentKind.RECORD; - } - else if (instanceOf(type, TYPE_FILE_PLAN)) - { - result = FilePlanComponentKind.FILE_PLAN; - } - else if (instanceOf(type, TYPE_RECORD_CATEGORY)) - { - result = FilePlanComponentKind.RECORD_CATEGORY; - } - else if (instanceOf(type, TYPE_RECORD_FOLDER)) - { - result = FilePlanComponentKind.RECORD_FOLDER; - } - else if (instanceOf(type, TYPE_HOLD)) - { - result = FilePlanComponentKind.HOLD; - } - else if (instanceOf(type, TYPE_TRANSFER)) - { - result = FilePlanComponentKind.TRANSFER; - } - else if (instanceOf(type, TYPE_DISPOSITION_SCHEDULE) || - instanceOf(type, TYPE_DISPOSITION_ACTION_DEFINITION)) - { - result = FilePlanComponentKind.DISPOSITION_SCHEDULE; - } - - return result; - } - - /** - * Indicates whether the given node is a file plan component or not. - *

- * Exposed in the FilePlan service. - * - * @see FilePlanService#isFilePlanComponent(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isFilePlanComponent(NodeRef nodeRef) - { - boolean result = false; - if (getInternalNodeService().exists(nodeRef) && - getInternalNodeService().hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT)) - { - result = true; - } - return result; - } - - /** - * Indicates whether the given node is a file plan or not. - *

- * Exposed in the FilePlan service. - * - * @see FilePlanService#isFilePlan(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isFilePlan(NodeRef nodeRef) - { - return instanceOf(nodeRef, TYPE_FILE_PLAN); - } - - /** - * Indicates whether the given node is a file plan container or not. - * - * @see FilePlanService#isFilePlanContainer(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isFilePlanContainer(NodeRef nodeRef) - { - return instanceOf(nodeRef, TYPE_RECORDS_MANAGEMENT_CONTAINER); - } - - /** - * Indicates whether the given node is a record category or not. - * - * @see FilePlanService#isRecordCategory(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isRecordCategory(NodeRef nodeRef) - { - return instanceOf(nodeRef, TYPE_RECORD_CATEGORY); - } - - /** - * Indicates whether the given node is a record folder or not. - *

- * Exposed in the RecordFolder service. - * - * @param nodeRef node reference - * @return boolean true if record folder, false otherwise - */ - public boolean isRecordFolder(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - return instanceOf(nodeRef, TYPE_RECORD_FOLDER); - } - - /** - * Indicates whether the given node reference is a record or not. - * - * @param nodeRef node reference - * @return boolean true if node reference is a record, false otherwise - */ - public boolean isRecord(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - return getInternalNodeService().hasAspect(nodeRef, ASPECT_RECORD); - } - - /** - * Indicates whether the given node reference is a hold or not. - * - * @param nodeRef node reference - * @return boolean true if rma:hold or sub-type, false otherwise - */ - public boolean isHold(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - boolean isHold = false; - if (getInternalNodeService().exists(nodeRef) && - instanceOf(nodeRef, TYPE_HOLD)) - { - isHold = true; - } - return isHold; - } - - /** - * Indicates whether the given node reference is a transfer or not. - */ - public boolean isTransfer(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - return instanceOf(nodeRef, TYPE_TRANSFER); - } - - /** - * Indicates whether a record is complete or not. - * - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isDeclared(NodeRef record) - { - ParameterCheck.mandatory("record", record); - - return getInternalNodeService().hasAspect(record, ASPECT_DECLARED_RECORD); - } - - /** - * Gets the file plan that a given file plan component resides within. - * - * @param nodeRef node reference - * @return {@link NodeRef} file plan, null if none - */ - public NodeRef getFilePlan(final NodeRef nodeRef) - { - NodeRef result = null; - if (nodeRef != null) - { - result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); - if (result == null) - { - if (instanceOf(nodeRef, TYPE_FILE_PLAN)) - { - result = nodeRef; - } - else - { - ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); - if (parentAssocRef != null) - { - result = getFilePlan(parentAssocRef.getParentRef()); - } - } - } - } - - return result; - } - - /** - * Utility method to safely and quickly determine if a node is a type (or sub-type) of the one specified. - * - * @param nodeRef node reference - * @param ofClassName class name to check - */ - protected boolean instanceOf(NodeRef nodeRef, QName ofClassName) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - ParameterCheck.mandatory("ofClassName", ofClassName); - QName className = getInternalNodeService().getType(nodeRef); - return instanceOf(className, ofClassName); - } - - /** - * Utility method to quickly determine whether one class is equal to or sub of another. - * - * @param className class name - * @param ofClassName class name to check against - * @return boolean true if equal to or sub, false otherwise - */ - protected boolean instanceOf(QName className, QName ofClassName) - { - ParameterCheck.mandatory("className", className); - ParameterCheck.mandatory("ofClassName", ofClassName); - boolean result = false; - if (ofClassName.equals(className) || - dictionaryService.isSubClass(className, ofClassName)) - { - result = true; - } - return result; - } - - /** - * Utility method to get the next counter for a node. - *

- * If the node is not already countable, then rma:countable is added and 0 returned. - * - * @param nodeRef node reference - * @return int next counter value - */ - protected int getNextCount(NodeRef nodeRef) - { - int counter = 0; - if (!nodeService.hasAspect(nodeRef, ASPECT_COUNTABLE)) - { - PropertyMap props = new PropertyMap(1); - props.put(PROP_COUNT, 1); - nodeService.addAspect(nodeRef, ASPECT_COUNTABLE, props); - counter = 1; - } - else - { - Integer value = (Integer)this.nodeService.getProperty(nodeRef, PROP_COUNT); - if (value != null) - { - counter = value.intValue() + 1; - } - else - { - counter = 1; - } - nodeService.setProperty(nodeRef, PROP_COUNT, counter); - - } - return counter; - } - - /** - * Helper method to get a set containing the node's type and all it's aspects - * - * @param nodeRef nodeRef - * @return Set set of qname's - */ - protected Set getTypeAndApsects(NodeRef nodeRef) - { - Set result = nodeService.getAspects(nodeRef); - result.add(nodeService.getType(nodeRef)); - return result; - } - - /** - * Helper method that executed work as system user. - *

- * Useful when testing using mocks. - * - * @param runAsWork work to execute as system user - * @return - */ - public R runAsSystem(RunAsWork runAsWork) - { - return AuthenticationUtil.runAsSystem(runAsWork); - } - - /** - * Helper method that executed work as given user. - *

- * Useful when testing using mocks. - * - * @param runAsWork work to execute as given user - * @return - */ - public R runAs(RunAsWork runAsWork, String uid) - { - return AuthenticationUtil.runAs(runAsWork, uid); - } + /** Node service */ + protected NodeService nodeService; + + /** Dictionary service */ + protected DictionaryService dictionaryService; + + /** Application context */ + protected ApplicationContext applicationContext; + + /** internal node service */ + private NodeService internalNodeService; + + /** + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) + { + this.applicationContext = applicationContext; + } + + /** + * @param nodeService node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param dictionaryService dictionary service + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * Helper to get internal node service. + *

+ * Used for performance reasons. + */ + protected NodeService getInternalNodeService() + { + if (internalNodeService == null) + { + internalNodeService = (NodeService)applicationContext.getBean("dbNodeService"); + } + + return internalNodeService; + } + + /** + * Gets the file plan component kind from the given node reference + * + * @see FilePlanService#getFilePlanComponentKind(org.alfresco.service.cmr.repository.NodeRef) + */ + public FilePlanComponentKind getFilePlanComponentKind(NodeRef nodeRef) + { + FilePlanComponentKind result = null; + + if (isFilePlanComponent(nodeRef)) + { + result = FilePlanComponentKind.FILE_PLAN_COMPONENT; + + if (isFilePlan(nodeRef)) + { + result = FilePlanComponentKind.FILE_PLAN; + } + else if (isRecordCategory(nodeRef)) + { + result = FilePlanComponentKind.RECORD_CATEGORY; + } + else if (isRecordFolder(nodeRef)) + { + result = FilePlanComponentKind.RECORD_FOLDER; + } + else if (isRecord(nodeRef)) + { + result = FilePlanComponentKind.RECORD; + } + else if (isHold(nodeRef)) + { + result = FilePlanComponentKind.HOLD; + } + else if (isTransfer(nodeRef)) + { + result = FilePlanComponentKind.TRANSFER; + } + else if (instanceOf(nodeRef, TYPE_DISPOSITION_SCHEDULE) || instanceOf(nodeRef, TYPE_DISPOSITION_ACTION_DEFINITION)) + { + result = FilePlanComponentKind.DISPOSITION_SCHEDULE; + } + else if (instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER)) + { + result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER; + } + } + + return result; + } + + /** + * Gets the file plan component kind from the given type. + * + * @see FilePlanService#getFilePlanComponentKindFromType(QName) + */ + public FilePlanComponentKind getFilePlanComponentKindFromType(QName type) + { + FilePlanComponentKind result = null; + + if (ASPECT_FILE_PLAN_COMPONENT.equals(type)) + { + result = FilePlanComponentKind.FILE_PLAN_COMPONENT; + } + else if (instanceOf(type, ASPECT_RECORD)) + { + result = FilePlanComponentKind.RECORD; + } + else if (instanceOf(type, TYPE_FILE_PLAN)) + { + result = FilePlanComponentKind.FILE_PLAN; + } + else if (instanceOf(type, TYPE_RECORD_CATEGORY)) + { + result = FilePlanComponentKind.RECORD_CATEGORY; + } + else if (instanceOf(type, TYPE_RECORD_FOLDER)) + { + result = FilePlanComponentKind.RECORD_FOLDER; + } + else if (instanceOf(type, TYPE_HOLD)) + { + result = FilePlanComponentKind.HOLD; + } + else if (instanceOf(type, TYPE_TRANSFER)) + { + result = FilePlanComponentKind.TRANSFER; + } + else if (instanceOf(type, TYPE_DISPOSITION_SCHEDULE) || + instanceOf(type, TYPE_DISPOSITION_ACTION_DEFINITION)) + { + result = FilePlanComponentKind.DISPOSITION_SCHEDULE; + } + + return result; + } + + /** + * Indicates whether the given node is a file plan component or not. + *

+ * Exposed in the FilePlan service. + * + * @see FilePlanService#isFilePlanComponent(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isFilePlanComponent(NodeRef nodeRef) + { + boolean result = false; + if (getInternalNodeService().exists(nodeRef) && + getInternalNodeService().hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT)) + { + result = true; + } + return result; + } + + /** + * Indicates whether the given node is a file plan or not. + *

+ * Exposed in the FilePlan service. + * + * @see FilePlanService#isFilePlan(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isFilePlan(NodeRef nodeRef) + { + return instanceOf(nodeRef, TYPE_FILE_PLAN); + } + + /** + * Indicates whether the given node is a file plan container or not. + * + * @see FilePlanService#isFilePlanContainer(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isFilePlanContainer(NodeRef nodeRef) + { + return instanceOf(nodeRef, TYPE_RECORDS_MANAGEMENT_CONTAINER); + } + + /** + * Indicates whether the given node is a record category or not. + * + * @see FilePlanService#isRecordCategory(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isRecordCategory(NodeRef nodeRef) + { + return instanceOf(nodeRef, TYPE_RECORD_CATEGORY); + } + + /** + * Indicates whether the given node is a record folder or not. + *

+ * Exposed in the RecordFolder service. + * + * @param nodeRef node reference + * @return boolean true if record folder, false otherwise + */ + public boolean isRecordFolder(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + return instanceOf(nodeRef, TYPE_RECORD_FOLDER); + } + + /** + * Indicates whether the given node reference is a record or not. + * + * @param nodeRef node reference + * @return boolean true if node reference is a record, false otherwise + */ + public boolean isRecord(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + return getInternalNodeService().hasAspect(nodeRef, ASPECT_RECORD); + } + + /** + * Indicates whether the given node reference is a hold or not. + *

+ * Exposed publicly in the {@link HoldService} + * + * @param nodeRef node reference + * @return boolean true if rma:hold or sub-type, false otherwise + */ + public boolean isHold(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + boolean isHold = false; + if (getInternalNodeService().exists(nodeRef) && + instanceOf(nodeRef, TYPE_HOLD)) + { + isHold = true; + } + return isHold; + } + + /** + * Indicates whether the given node reference is a transfer or not. + * + * @see org.alfresco.module.org_alfresco_module_rm.transfer.TransferService#isTransfer(NodeRef) + */ + public boolean isTransfer(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + return instanceOf(nodeRef, TYPE_TRANSFER); + } + + /** + * Indicates whether a record is complete or not. + * + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isDeclared(NodeRef record) + { + ParameterCheck.mandatory("record", record); + + return getInternalNodeService().hasAspect(record, ASPECT_DECLARED_RECORD); + } + + /** + * Gets the file plan that a given file plan component resides within. + * + * @param nodeRef node reference + * @return {@link NodeRef} file plan, null if none + */ + public NodeRef getFilePlan(final NodeRef nodeRef) + { + NodeRef result = null; + if (nodeRef != null) + { + result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); + if (result == null || !instanceOf(result, TYPE_FILE_PLAN)) + { + if (instanceOf(nodeRef, TYPE_FILE_PLAN)) + { + result = nodeRef; + } + else + { + ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); + if (parentAssocRef != null) + { + result = getFilePlan(parentAssocRef.getParentRef()); + } + } + } + } + + return result; + } + + /** + * Utility method to safely and quickly determine if a node is a type (or sub-type) of the one specified. + * + * @param nodeRef node reference + * @param ofClassName class name to check + */ + protected boolean instanceOf(NodeRef nodeRef, QName ofClassName) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + ParameterCheck.mandatory("ofClassName", ofClassName); + QName className = getInternalNodeService().getType(nodeRef); + return instanceOf(className, ofClassName); + } + + private static Map instanceOfCache = new HashMap(); + + /** + * Utility method to quickly determine whether one class is equal to or sub of another. + * + * @param className class name + * @param ofClassName class name to check against + * @return boolean true if equal to or sub, false otherwise + */ + protected boolean instanceOf(QName className, QName ofClassName) + { + ParameterCheck.mandatory("className", className); + ParameterCheck.mandatory("ofClassName", ofClassName); + + boolean result = false; + + String key = className.toString() + "|" + ofClassName.toString(); + if (instanceOfCache.containsKey(key)) + { + result = instanceOfCache.get(key); + } + else + { + if (ofClassName.equals(className) || + dictionaryService.isSubClass(className, ofClassName)) + { + result = true; + } + + instanceOfCache.put(key, result); + } + + return result; + } + + /** + * Utility method to get the next counter for a node. + *

+ * If the node is not already countable, then rma:countable is added and 0 returned. + * + * @param nodeRef node reference + * @return int next counter value + */ + protected int getNextCount(NodeRef nodeRef) + { + int counter = 0; + if (!nodeService.hasAspect(nodeRef, ASPECT_COUNTABLE)) + { + PropertyMap props = new PropertyMap(1); + props.put(PROP_COUNT, 1); + nodeService.addAspect(nodeRef, ASPECT_COUNTABLE, props); + counter = 1; + } + else + { + Integer value = (Integer)this.nodeService.getProperty(nodeRef, PROP_COUNT); + if (value != null) + { + counter = value.intValue() + 1; + } + else + { + counter = 1; + } + nodeService.setProperty(nodeRef, PROP_COUNT, counter); + + } + return counter; + } + + /** + * Helper method to get a set containing the node's type and all it's aspects + * + * @param nodeRef nodeRef + * @return Set set of qname's + */ + protected Set getTypeAndApsects(NodeRef nodeRef) + { + Set result = nodeService.getAspects(nodeRef); + result.add(nodeService.getType(nodeRef)); + return result; + } + + /** + * Helper method that executed work as system user. + *

+ * Useful when testing using mocks. + * + * @param runAsWork work to execute as system user + * @return + */ + public R runAsSystem(RunAsWork runAsWork) + { + return AuthenticationUtil.runAsSystem(runAsWork); + } + + /** + * Helper method that executed work as given user. + *

+ * Useful when testing using mocks. + * + * @param runAsWork work to execute as given user + * @return + */ + public R runAs(RunAsWork runAsWork, String uid) + { + return AuthenticationUtil.runAs(runAsWork, uid); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java index 1f3733249a..f64f13b778 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java @@ -62,7 +62,6 @@ public class FreezeServiceImplTest extends BaseRMTestCase // Freeze a record freezeService.freeze("FreezeReason", recordOne); - assertTrue(freezeService.hasFrozenChildren(rmFolder)); // Check the hold exists Set holdAssocs = freezeService.getHolds(filePlan); @@ -192,7 +191,6 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertFalse(freezeService.isFrozen(recordTwo)); assertFalse(freezeService.isFrozen(recordThree)); assertFalse(freezeService.isFrozen(recordFour)); - assertFalse(freezeService.hasFrozenChildren(rmFolder)); // Test freezing nodes, adding them to an existing hold NodeRef hold = freezeService.freeze("AnotherFreezeReason", recordFour); @@ -201,7 +199,6 @@ public class FreezeServiceImplTest extends BaseRMTestCase nodes.add(recordTwo); nodes.add(recordThree); freezeService.freeze(hold, nodes); - assertTrue(freezeService.hasFrozenChildren(rmFolder)); // Check the hold holdAssocs = freezeService.getHolds(filePlan); @@ -216,7 +213,6 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertFalse(freezeService.isFrozen(recordTwo)); assertFalse(freezeService.isFrozen(recordThree)); assertFalse(freezeService.isFrozen(recordFour)); - assertFalse(freezeService.hasFrozenChildren(rmFolder)); return null; } From 1c280f0e0e171832d037929747fef4c87c691084 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 16 Jul 2014 02:10:46 +0000 Subject: [PATCH 7/9] Merged HEAD to BRANCHES/V2.1.0.x: 75102: RM Performance testing git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@76598 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../role/FilePlanRoleServiceImpl.java | 4 ++-- .../script/admin/RoleDeclarativeWebScript.java | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java index 908500eabd..54960043bc 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java @@ -663,7 +663,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, { String capabilityName = permission.getPermission(); Capability capability = capabilityService.getCapability(capabilityName); - if (capability != null) + if (capability != null && !capability.isPrivate()) { capabilities.add(capability); } @@ -860,7 +860,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, { throw new AlfrescoRuntimeException("Can not get authorities for role " + roleName + ", because it does not exist. (filePlan=" + filePlan.toString() + ")"); } - return authorityService.getContainedAuthorities(authorityType, role.getRoleGroupName(), false); + return authorityService.getContainedAuthorities(authorityType, role.getRoleGroupName(), true); } }, AuthenticationUtil.getSystemUserName()); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/admin/RoleDeclarativeWebScript.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/admin/RoleDeclarativeWebScript.java index 819615b5f5..f898cfa74f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/admin/RoleDeclarativeWebScript.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/admin/RoleDeclarativeWebScript.java @@ -29,6 +29,7 @@ import org.alfresco.module.org_alfresco_module_rm.role.Role; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; import org.apache.cxf.common.util.StringUtils; import org.springframework.extensions.webscripts.DeclarativeWebScript; import org.springframework.extensions.webscripts.WebScriptRequest; @@ -172,7 +173,11 @@ public class RoleDeclarativeWebScript extends DeclarativeWebScript for (String authority : authorities) { - String displayLabel = authorityService.getAuthorityDisplayName(authority); + String displayLabel = authority; + if (!AuthorityType.getAuthorityType(authority).equals(AuthorityType.USER)) + { + displayLabel = authorityService.getAuthorityDisplayName(authority); + } result.add(new AuthorityItem(authority, displayLabel)); } From 06c378b4317e552564a23839b2bc1a2184a89c3d Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 16 Jul 2014 02:18:28 +0000 Subject: [PATCH 8/9] Update module version to 2.1.0.2 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@76599 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- gradle.properties | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4aa7cc4c10..bb286aadbb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # build details groupid=alfresco packageName=rm -version=2.1.0.1 +version=2.1.0.2 build=dev # maven urls's 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 79697c6903..00c3401827 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.1.0.1 +module.version=2.1.0.2 module.repo.version.min=4.2 \ No newline at end of file From a0916c1bd0768aad75ea23ea02facc22a17a0caa Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 16 Jul 2014 04:45:57 +0000 Subject: [PATCH 9/9] Merged HEAD to BRANCHES/V2.1.0.x: 75186: RM Performance Improvements git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.1.0.x@76601 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../documentlibrary/rm-treenode.get.js | 2 +- .../AbstractCapabilityCondition.java | 37 +++++++++ .../declarative/CapabilityCondition.java | 17 ++++ .../condition/AtLeastOneCondition.java | 13 +++- .../condition/ClosedCapabilityCondition.java | 2 +- .../condition/CutoffCapabilityCondition.java | 2 +- .../DeclaredCapabilityCondition.java | 2 +- .../DestroyedCapabilityCondition.java | 2 +- .../condition/FailCapabilityCondition.java | 2 +- .../FileableCapabilityCondition.java | 2 +- .../condition/FillingCapabilityCondition.java | 2 +- .../condition/FrozenCapabilityCondition.java | 2 +- .../condition/FrozenOrHoldCondition.java | 2 +- .../HasAspectCapabilityCondition.java | 2 +- ...HasDispositionDateCapabilityCondition.java | 2 +- .../HasEventsCapabilityCondition.java | 2 +- .../IsClassifiedCapabilityCondition.java | 2 +- .../condition/IsPropertySetCondition.java | 2 +- .../condition/IsRecordCategoryCondition.java | 2 +- .../condition/IsRecordCondition.java | 2 +- .../condition/IsRecordFolderCondition.java | 2 +- .../IsScheduledCapabilityCondition.java | 2 +- ...sTransferAccessionCapabilityCondition.java | 2 +- .../LastDispositionActionCondition.java | 2 +- .../MayBeScheduledCapabilityCondition.java | 2 +- .../RecordFiledCapabilityCondition.java | 2 +- .../TransferredCapabilityCondition.java | 2 +- ...italRecordOrFolderCapabilityCondition.java | 2 +- .../ExtendedSecurityBaseDynamicAuthority.java | 26 +++++-- .../util/ServiceBaseImpl.java | 78 +++++++++++-------- .../test/issue/RM1039Test.java | 13 +++- 31 files changed, 166 insertions(+), 68 deletions(-) diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/rm-treenode.get.js b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/rm-treenode.get.js index e6cc916b1c..91305ea9b9 100644 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/rm-treenode.get.js +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/rm-treenode.get.js @@ -20,7 +20,7 @@ function getTreenode() "{http://www.alfresco.org/model/recordsmanagement/1.0}unfiledRecordContainer":true }, skipPermissionCheck = args["perms"] == "false", - evalChildFolders = args["children"] !== "false", + evalChildFolders = false, item, rmNode, capabilities, cap; // Use helper function to get the arguments diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java index 1f6eb5dc23..5374771f2f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java @@ -18,11 +18,16 @@ */ package org.alfresco.module.org_alfresco_module_rm.capability.declarative; +import java.util.Map; + import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.TransactionalResourceHelper; +import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.PermissionService; import org.springframework.beans.factory.BeanNameAware; @@ -36,6 +41,9 @@ public abstract class AbstractCapabilityCondition implements CapabilityCondition BeanNameAware, RecordsManagementModel { + /** transaction cache key */ + private static final String KEY_EVALUATE = "rm.transaction.evaluate"; + /** Capability condition name */ protected String name; @@ -104,6 +112,35 @@ public abstract class AbstractCapabilityCondition implements CapabilityCondition return name; } + /** + * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public boolean evaluate(NodeRef nodeRef) + { + boolean result = false; + + // check transaction cache + Map map = TransactionalResourceHelper.getMap(KEY_EVALUATE); + String key = getName() + "|" + nodeRef.toString() + "|" + AuthenticationUtil.getRunAsUser(); + if (map.containsKey(key)) + { + result = map.get(key); + } + else + { + result = evaluateImpl(nodeRef); + map.put(key, result); + } + + return result; + } + + /** + * Condition evaluate implementation + */ + public abstract boolean evaluateImpl(NodeRef nodeRef); + /** * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String) */ diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/CapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/CapabilityCondition.java index 08032bcd22..fd792140eb 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/CapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/CapabilityCondition.java @@ -20,9 +20,26 @@ package org.alfresco.module.org_alfresco_module_rm.capability.declarative; import org.alfresco.service.cmr.repository.NodeRef; +/** + * Capability condition. + * + * @author Roy Wetherall + * @since 2.0 + */ public interface CapabilityCondition { + /** + * Get capability condition name + * + * @return {@link String} capability condition name + */ String getName(); + /** + * Evaluates capability condition. + * + * @param nodeRef node reference + * @return boolean true if evaluate success, false otherwise + */ boolean evaluate(NodeRef nodeRef); } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java index 3f2d23d392..0a4e372740 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java @@ -44,10 +44,21 @@ public class AtLeastOneCondition extends AbstractCapabilityCondition } /** - * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) + * Don't use the transaction cache for the composite condition + * + * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override public boolean evaluate(NodeRef nodeRef) + { + return evaluateImpl(nodeRef); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/ClosedCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/ClosedCapabilityCondition.java index 80f81730c6..7e1bdfbedd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/ClosedCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/ClosedCapabilityCondition.java @@ -35,7 +35,7 @@ public class ClosedCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; if (rmService.isRecordFolder(nodeRef) == true) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/CutoffCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/CutoffCapabilityCondition.java index 37eb259e98..0c1ae1d402 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/CutoffCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/CutoffCapabilityCondition.java @@ -30,7 +30,7 @@ public class CutoffCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { return rmService.isCutoff(nodeRef); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DeclaredCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DeclaredCapabilityCondition.java index 6b3a9441ae..7d5a24d3ba 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DeclaredCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DeclaredCapabilityCondition.java @@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef; public class DeclaredCapabilityCondition extends AbstractCapabilityCondition { @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; if (FilePlanComponentKind.RECORD.equals(filePlanService.getFilePlanComponentKind(nodeRef)) == true) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DestroyedCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DestroyedCapabilityCondition.java index f91fa9a47c..f035ad8f89 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DestroyedCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/DestroyedCapabilityCondition.java @@ -29,7 +29,7 @@ import org.alfresco.service.cmr.repository.NodeRef; public class DestroyedCapabilityCondition extends AbstractCapabilityCondition { @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { return nodeService.hasAspect(nodeRef, ASPECT_GHOSTED); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FailCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FailCapabilityCondition.java index a93121a22c..71af26521b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FailCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FailCapabilityCondition.java @@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef; public class FailCapabilityCondition extends AbstractCapabilityCondition { @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { return false; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FileableCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FileableCapabilityCondition.java index 942d73c8eb..fced36abf9 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FileableCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FileableCapabilityCondition.java @@ -47,7 +47,7 @@ public class FileableCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { QName type = nodeService.getType(nodeRef); // TODO and not already a record? diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingCapabilityCondition.java index f199155f3e..253178f14e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingCapabilityCondition.java @@ -34,7 +34,7 @@ public class FillingCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java index 4dcf1c302f..d098095d37 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java @@ -34,7 +34,7 @@ private boolean checkChildren = false; } @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = freezeService.isFrozen(nodeRef); if (result == false && checkChildren == true) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenOrHoldCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenOrHoldCondition.java index bad4166a1b..516bdeba57 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenOrHoldCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenOrHoldCondition.java @@ -33,7 +33,7 @@ public class FrozenOrHoldCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { FilePlanComponentKind kind = filePlanService.getFilePlanComponentKind(nodeRef); return (freezeService.isFrozen(nodeRef) || diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasAspectCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasAspectCapabilityCondition.java index c31d91a3f4..7b445c7a1b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasAspectCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasAspectCapabilityCondition.java @@ -46,7 +46,7 @@ public class HasAspectCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; if (aspectName != null) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasDispositionDateCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasDispositionDateCapabilityCondition.java index d8fb70dcbc..e9bddb14e0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasDispositionDateCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasDispositionDateCapabilityCondition.java @@ -45,7 +45,7 @@ public class HasDispositionDateCapabilityCondition extends AbstractCapabilityCon * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasEventsCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasEventsCapabilityCondition.java index c2270ddced..428c1a2adf 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasEventsCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HasEventsCapabilityCondition.java @@ -45,7 +45,7 @@ public class HasEventsCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsClassifiedCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsClassifiedCapabilityCondition.java index dedf7946fa..278af947d0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsClassifiedCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsClassifiedCapabilityCondition.java @@ -46,7 +46,7 @@ public class IsClassifiedCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java index 20ced1a648..7ced7736d3 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java @@ -66,7 +66,7 @@ public class IsPropertySetCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCategoryCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCategoryCondition.java index dd637d0983..016d7e37b0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCategoryCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCategoryCondition.java @@ -34,7 +34,7 @@ public class IsRecordCategoryCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCondition.java index 72e2fb7815..ccd285a3dd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordCondition.java @@ -34,7 +34,7 @@ public class IsRecordCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordFolderCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordFolderCondition.java index cda0bbf8ea..737f2675d6 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordFolderCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsRecordFolderCondition.java @@ -34,7 +34,7 @@ public class IsRecordFolderCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsScheduledCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsScheduledCapabilityCondition.java index afea96f7eb..6dc65f183f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsScheduledCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsScheduledCapabilityCondition.java @@ -56,7 +56,7 @@ public class IsScheduledCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsTransferAccessionCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsTransferAccessionCapabilityCondition.java index ae9a5b68b3..2cddff0ce5 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsTransferAccessionCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsTransferAccessionCapabilityCondition.java @@ -31,7 +31,7 @@ public class IsTransferAccessionCapabilityCondition extends AbstractCapabilityCo * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/LastDispositionActionCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/LastDispositionActionCondition.java index bfcfea81f3..3b33f1a218 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/LastDispositionActionCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/LastDispositionActionCondition.java @@ -48,7 +48,7 @@ public class LastDispositionActionCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; DispositionAction dispositionAction = dispositionService.getLastCompletedDispostionAction(nodeRef); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MayBeScheduledCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MayBeScheduledCapabilityCondition.java index a3d5de7236..22ed4ec521 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MayBeScheduledCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MayBeScheduledCapabilityCondition.java @@ -57,7 +57,7 @@ public class MayBeScheduledCapabilityCondition extends AbstractCapabilityConditi * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/RecordFiledCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/RecordFiledCapabilityCondition.java index 2a0f002b2e..0a4fb2b10f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/RecordFiledCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/RecordFiledCapabilityCondition.java @@ -33,7 +33,7 @@ public class RecordFiledCapabilityCondition extends AbstractCapabilityCondition * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { return recordService.isFiled(nodeRef); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/TransferredCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/TransferredCapabilityCondition.java index 39cdc3ff24..b4aeb0a980 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/TransferredCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/TransferredCapabilityCondition.java @@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef; public class TransferredCapabilityCondition extends AbstractCapabilityCondition { @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { return nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_TRANSFERRED); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/VitalRecordOrFolderCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/VitalRecordOrFolderCapabilityCondition.java index 26d1342e50..d3c6b463a9 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/VitalRecordOrFolderCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/VitalRecordOrFolderCapabilityCondition.java @@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef; public class VitalRecordOrFolderCapabilityCondition extends AbstractCapabilityCondition { @Override - public boolean evaluate(NodeRef nodeRef) + public boolean evaluateImpl(NodeRef nodeRef) { boolean result = false; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java index d13facebea..2c439c3519 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java @@ -18,15 +18,16 @@ */ package org.alfresco.module.org_alfresco_module_rm.security; +import java.util.Map; import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.repo.security.permissions.PermissionReference; +import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthorityService; -import org.alfresco.service.cmr.security.AuthorityType; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -41,6 +42,9 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut RecordsManagementModel, ApplicationContextAware { + /** transaction cache key */ + private static final String KEY_HAS_AUTHORITY_CACHE = "rm.transaction.hasAuthority"; + /** Authority service */ private AuthorityService authorityService; @@ -133,14 +137,24 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut } else if (authority.startsWith("GROUP_") == true) { - // check group to see if the user is contained - Set contained = getAuthorityService().getContainedAuthorities(AuthorityType.USER, authority, false); - if (contained.isEmpty() == false && - contained.contains(userName) == true) + Map transactionCache = TransactionalResourceHelper.getMap(KEY_HAS_AUTHORITY_CACHE); + String key = authority + "|" + userName; + if (transactionCache.containsKey(key)) + { - result = true; + result = transactionCache.get(key); break; } + else + { + Set contained = getAuthorityService().getAuthoritiesForUser(userName); + if (contained.contains(authority)) + { + result = true; + transactionCache.put(key, result); + break; + } + } } else { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java index c4494ab4df..1dfe8d7010 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java @@ -27,6 +27,7 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; @@ -96,7 +97,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte return internalNodeService; } - + /** * Gets the file plan component kind from the given node reference * @@ -106,41 +107,54 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { FilePlanComponentKind result = null; - if (isFilePlanComponent(nodeRef)) + Map map = TransactionalResourceHelper.getMap("rm.transaction.filePlanComponentByNodeRef"); + if (map.containsKey(nodeRef)) { - result = FilePlanComponentKind.FILE_PLAN_COMPONENT; - - if (isFilePlan(nodeRef)) + result = map.get(nodeRef); + } + else + { + if (isFilePlanComponent(nodeRef)) { - result = FilePlanComponentKind.FILE_PLAN; + result = FilePlanComponentKind.FILE_PLAN_COMPONENT; + + if (isFilePlan(nodeRef)) + { + result = FilePlanComponentKind.FILE_PLAN; + } + else if (isRecordCategory(nodeRef)) + { + result = FilePlanComponentKind.RECORD_CATEGORY; + } + else if (isRecordFolder(nodeRef)) + { + result = FilePlanComponentKind.RECORD_FOLDER; + } + else if (isRecord(nodeRef)) + { + result = FilePlanComponentKind.RECORD; + } + else if (isHold(nodeRef)) + { + result = FilePlanComponentKind.HOLD; + } + else if (isTransfer(nodeRef)) + { + result = FilePlanComponentKind.TRANSFER; + } + else if (instanceOf(nodeRef, TYPE_DISPOSITION_SCHEDULE) || instanceOf(nodeRef, TYPE_DISPOSITION_ACTION_DEFINITION)) + { + result = FilePlanComponentKind.DISPOSITION_SCHEDULE; + } + else if (instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER)) + { + result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER; + } } - else if (isRecordCategory(nodeRef)) + + if (result != null) { - result = FilePlanComponentKind.RECORD_CATEGORY; - } - else if (isRecordFolder(nodeRef)) - { - result = FilePlanComponentKind.RECORD_FOLDER; - } - else if (isRecord(nodeRef)) - { - result = FilePlanComponentKind.RECORD; - } - else if (isHold(nodeRef)) - { - result = FilePlanComponentKind.HOLD; - } - else if (isTransfer(nodeRef)) - { - result = FilePlanComponentKind.TRANSFER; - } - else if (instanceOf(nodeRef, TYPE_DISPOSITION_SCHEDULE) || instanceOf(nodeRef, TYPE_DISPOSITION_ACTION_DEFINITION)) - { - result = FilePlanComponentKind.DISPOSITION_SCHEDULE; - } - else if (instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER)) - { - result = FilePlanComponentKind.UNFILED_RECORD_CONTAINER; + map.put(nodeRef, result); } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1039Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1039Test.java index d3d411ba9d..e00ccb47eb 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1039Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1039Test.java @@ -160,13 +160,18 @@ public class RM1039Test extends BaseRMTestCase // cutoff folder actionService.executeRecordsManagementAction(testFolder, CutOffAction.NAME); - - // take a look at the move capability - Capability moveCapability = capabilityService.getCapability("Move"); - assertEquals(AccessDecisionVoter.ACCESS_DENIED, moveCapability.evaluate(testFolder, destination)); return testFolder; } + + @Override + public void test(NodeRef result) throws Exception + { + // take a look at the move capability + Capability moveCapability = capabilityService.getCapability("Move"); + assertEquals(AccessDecisionVoter.ACCESS_DENIED, moveCapability.evaluate(result, destination)); + + } }); doTestInTransaction(new FailureTest()