From 75443d6ad5f433b0e5942da99bf191132069f31d Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Fri, 2 Nov 2012 10:37:51 +0000 Subject: [PATCH] Implemented a DeclareRecordAction so that a rule can be setup for a folder and a user can declare a record just uploading a file (in a collaboration site) into the folder. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/DEV/INPLACE@43332 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org_alfresco_module_rm/action-context.xml | 8 + .../messages/actions.properties | 18 +- .../action/dm/DeclareRecordAction.java | 256 ++++++++++++++++++ 3 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/DeclareRecordAction.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml index dfc411ea07..cbdd79e0ec 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml @@ -34,4 +34,12 @@ --> + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties index c55856199e..ce4c5321a9 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties @@ -34,4 +34,20 @@ rm.action.node-already-transfer=Node is already being transfered. rm.action.node-not-transfer=Node is not a transfer object. rm.action.undo-not-last=Can not undo cut off, because last disposition action was not cut off. rm.action.records_only_undeclared=Only records can be undeclared. -rm.action.event-not-undone=The event {0} can not be undone, because it is not defined on the disposition lifecycle. \ No newline at end of file +rm.action.event-not-undone=The event {0} can not be undone, because it is not defined on the disposition lifecycle. +# +# i18n for Rule Actions +# +# File record +file-record.title=File record +# FIXME!!! +#file-record.description=The rule is applied to all items that... +#file-record.destination-record-folder.display-label=File record +# Create record +create-record.title=Create record +# FIXME!!! +#create-record.description=The rule is applied to all items that... +# Declare record +declare-record.title=Declare record +# FIXME!!! +#declare-record.description=The rule is applied to all items that... \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/DeclareRecordAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/DeclareRecordAction.java new file mode 100644 index 0000000000..e63ac21907 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/DeclareRecordAction.java @@ -0,0 +1,256 @@ +package org.alfresco.module.org_alfresco_module_rm.action.dm; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ParameterDefinition; +import org.alfresco.service.cmr.dictionary.AspectDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.cmr.dictionary.TypeDefinition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.OwnableService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.extensions.surf.util.I18NUtil; + +public class DeclareRecordAction extends ActionExecuterAbstractBase implements RecordsManagementModel +{ + /** I18N */ + private static final String MSG_NO_DECLARE_MAND_PROP = "rm.action.no-declare-mand-prop"; + + /** Logger */ + private static Log logger = LogFactory.getLog(DeclareRecordAction.class); + + /** Record service */ + private RecordService recordService; + + /** Record management service */ + private RecordsManagementService recordsManagementService; + + /** Node service */ + private NodeService nodeService; + + /** Ownable service **/ + private OwnableService ownableService; + + /** Dictionary service */ + private DictionaryService dictionaryService; + + /** + * @param recordService record service + */ + public void setRecordService(RecordService recordService) + { + this.recordService = recordService; + } + + /** + * @param recordsManagementService records management service + */ + public void setRecordsManagementService( + RecordsManagementService recordsManagementService) + { + this.recordsManagementService = recordsManagementService; + } + + /** + * @param nodeService node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param ownableSerice ownable serice + */ + public void setOwnableService(OwnableService ownableService) + { + this.ownableService = ownableService; + } + + /** + * @param dictionaryService dictionary service + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + @Override + protected void executeImpl(Action action, final NodeRef actionedUponNodeRef) + { + // skip everything if the actioned upon node reference is already a record + if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_RECORD) == false) + { + // TODO we should use the file plan passed as a parameter + // grab the file plan + List filePlans = recordsManagementService.getFilePlans(); + if (filePlans.size() == 1) + { + // TODO parameterise the action with the file plan + final NodeRef filePlan = filePlans.get(0); + + // run record creation as system + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + // create record from existing document + recordService.createRecordFromDocument(filePlan, actionedUponNodeRef); + return null; + } + }); + + // DEMO CODE + if (nodeService.getProperty(actionedUponNodeRef, PROP_ORIGINATOR) == null) + { + nodeService.setProperty(actionedUponNodeRef, PROP_ORIGINATOR, "Michelle Smith"); + } + if (nodeService.getProperty(actionedUponNodeRef, PROP_ORIGINATING_ORGANIZATION) == null) + { + nodeService.setProperty(actionedUponNodeRef, PROP_ORIGINATING_ORGANIZATION, "Customer Service"); + } + if (nodeService.getProperty(actionedUponNodeRef, PROP_PUBLICATION_DATE) == null) + { + nodeService.setProperty(actionedUponNodeRef, PROP_PUBLICATION_DATE, new Date()); + } + + if (recordService.isDeclared(actionedUponNodeRef) == false) + { + List missingProperties = new ArrayList(5); + // Aspect not already defined - check mandatory properties then add + if (mandatoryPropertiesSet(actionedUponNodeRef, missingProperties) == true) + { + // Add the declared aspect + Map declaredProps = new HashMap(2); + declaredProps.put(PROP_DECLARED_AT, new Date()); + declaredProps.put(PROP_DECLARED_BY, AuthenticationUtil.getRunAsUser()); + nodeService.addAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD, declaredProps); + + // remove all owner related rights + ownableService.setOwner(actionedUponNodeRef, OwnableService.NO_OWNER); + } + else + { + throw new AlfrescoRuntimeException(buildMissingPropertiesErrorString(missingProperties)); + } + } + } + else + { + throw new AlfrescoRuntimeException("Unable to find file plan."); + } + } + } + + private String buildMissingPropertiesErrorString(List missingProperties) + { + StringBuilder builder = new StringBuilder(255); + builder.append(I18NUtil.getMessage(MSG_NO_DECLARE_MAND_PROP)); + builder.append(" "); + for (String missingProperty : missingProperties) + { + builder.append(missingProperty) + .append(", "); + } + return builder.toString(); + } + + /** + * Helper method to check whether all the mandatory properties of the node have been set + * + * @param nodeRef + * node reference + * @return boolean true if all mandatory properties are set, false otherwise + */ + private boolean mandatoryPropertiesSet(NodeRef nodeRef, List missingProperties) + { + boolean result = true; + + Map nodeRefProps = nodeService.getProperties(nodeRef); + + QName nodeRefType = nodeService.getType(nodeRef); + + TypeDefinition typeDef = dictionaryService.getType(nodeRefType); + for (PropertyDefinition propDef : typeDef.getProperties().values()) + { + if (propDef.isMandatory() == true) + { + if (nodeRefProps.get(propDef.getName()) == null) + { + logMissingProperty(propDef, missingProperties); + + result = false; + break; + } + } + } + + if (result != false) + { + Set aspects = this.nodeService.getAspects(nodeRef); + for (QName aspect : aspects) + { + AspectDefinition aspectDef = dictionaryService.getAspect(aspect); + for (PropertyDefinition propDef : aspectDef.getProperties().values()) + { + if (propDef.isMandatory() == true) + { + if (nodeRefProps.get(propDef.getName()) == null) + { + logMissingProperty(propDef, missingProperties); + + result = false; + break; + } + } + } + } + } + + return result; + } + + /** + * Log information about missing properties. + * + * @param propDef property definition + * @param missingProperties missing properties + */ + private void logMissingProperty(PropertyDefinition propDef, List missingProperties) + { + if (logger.isWarnEnabled()) + { + StringBuilder msg = new StringBuilder(); + msg.append("Mandatory property missing: ").append(propDef.getName()); + logger.warn(msg.toString()); + } + missingProperties.add(propDef.getName().toString()); + } + + @Override + protected void addParameterDefinitions(List paramList) + { + // TODO eventually we will need to pass in the file plan as a parameter + // TODO .. or the RM site + } + +} \ No newline at end of file