diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml index 24c2b8c2a3..5a23b9d351 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml @@ -699,7 +699,7 @@ - + @@ -717,6 +717,7 @@ + @@ -744,7 +745,7 @@ - + @@ -762,6 +763,7 @@ + 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 2ec6028dbe..fde1d70b91 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 @@ -3,9 +3,9 @@ - + - + @@ -26,12 +26,12 @@ - + - - - - + + + + @@ -259,7 +259,12 @@ - + + + + + + @@ -367,74 +372,74 @@ - + @@ -495,8 +500,8 @@ - @@ -555,10 +560,10 @@ - + - @@ -610,7 +615,7 @@ @@ -690,7 +695,7 @@ org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService.assignRoleToAuthority=RM_CAP.0.rma:filePlanComponent.CreateModifyDestroyUsersAndGroups org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService.unassignRoleFromAuthority=RM_CAP.0.rma:filePlanComponent.CreateModifyDestroyUsersAndGroups org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService.getAllRolesContainerGroup=RM_ALLOW - org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService.*=RM_DENY + org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService.*=RM_DENY ]]> @@ -732,7 +737,7 @@ @@ -744,10 +749,10 @@ class="org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityServiceImpl" init-method="init"> - - - - + + + + @@ -790,7 +795,7 @@ @@ -936,12 +941,12 @@ - - rma:recordCategory - rma:recordFolder - rma:record - rma:nonElectronicDocument - + + rma:recordCategory + rma:recordFolder + rma:record + rma:nonElectronicDocument + @@ -1320,7 +1325,7 @@ - + @@ -1348,7 +1353,7 @@ @@ -1433,15 +1438,15 @@ - - - - + + + + - + @@ -1470,12 +1475,12 @@ - - + + - + - + 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 4372e67654..b0384f3e5a 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 @@ -19,7 +19,6 @@ package org.alfresco.module.org_alfresco_module_rm.action; import java.io.Serializable; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -29,8 +28,6 @@ import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.event.EventCompletionDetails; import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent; @@ -49,15 +46,12 @@ import org.alfresco.service.cmr.action.ActionDefinition; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; -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; @@ -475,127 +469,6 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe return null; } - /** - * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementService#updateNextDispositionAction(org.alfresco.service.cmr.repository.NodeRef) - */ - public void updateNextDispositionAction(NodeRef nodeRef) - { - // Get this disposition instructions for the node - DispositionSchedule di = dispositionService.getDispositionSchedule(nodeRef); - if (di != null) - { - // Get the current action node - 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); - if (assocs.size() > 0) - { - currentDispositionAction = assocs.get(0).getChildRef(); - } - } - - if (currentDispositionAction != null) - { - // Move it to the history association - this.nodeService.moveNode(currentDispositionAction, nodeRef, ASSOC_DISPOSITION_ACTION_HISTORY, ASSOC_DISPOSITION_ACTION_HISTORY); - } - - List dispositionActionDefinitions = di.getDispositionActionDefinitions(); - DispositionActionDefinition currentDispositionActionDefinition = null; - DispositionActionDefinition nextDispositionActionDefinition = null; - - if (currentDispositionAction == null) - { - if (dispositionActionDefinitions.isEmpty() == false) - { - // The next disposition action is the first action - nextDispositionActionDefinition = dispositionActionDefinitions.get(0); - } - } - else - { - // Get the current action - String currentADId = (String)this.nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION_ID); - currentDispositionActionDefinition = di.getDispositionActionDefinition(currentADId); - - // Get the next disposition action - int index = currentDispositionActionDefinition.getIndex(); - index++; - if (index < dispositionActionDefinitions.size()) - { - nextDispositionActionDefinition = dispositionActionDefinitions.get(index); - } - } - - if (nextDispositionActionDefinition != null) - { - if (this.nodeService.hasAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE) == false) - { - // Add the disposition life cycle aspect - this.nodeService.addAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE, null); - } - - // Create the properties - Map props = new HashMap(10); - - // Calculate the asOf date - Date asOfDate = null; - Period period = nextDispositionActionDefinition.getPeriod(); - if (period != null) - { - Date contextDate = null; - - // Get the period properties value - QName periodProperty = nextDispositionActionDefinition.getPeriodProperty(); - if (periodProperty != null && - RecordsManagementModel.PROP_DISPOSITION_AS_OF.equals(periodProperty) == false) - { - // doesn't matter if the period property isn't set ... the asOfDate will get updated later - // when the value of the period property is set - contextDate = (Date)this.nodeService.getProperty(nodeRef, periodProperty); - } - else - { - // for now use 'NOW' as the default context date - // TODO set the default period property ... cut off date or last disposition date depending on context - contextDate = new Date(); - } - - // Calculate the as of date - if (contextDate != null) - { - asOfDate = period.getNextDate(contextDate); - } - } - - // Set the property values - props.put(PROP_DISPOSITION_ACTION_ID, nextDispositionActionDefinition.getId()); - props.put(PROP_DISPOSITION_ACTION, nextDispositionActionDefinition.getName()); - if (asOfDate != null) - { - props.put(PROP_DISPOSITION_AS_OF, asOfDate); - } - - // Create a new disposition action object - NodeRef dispositionActionNodeRef = this.nodeService.createNode( - nodeRef, - ASSOC_NEXT_DISPOSITION_ACTION, - ASSOC_NEXT_DISPOSITION_ACTION, - TYPE_DISPOSITION_ACTION, - props).getChildRef(); - - // Create the events - List events = nextDispositionActionDefinition.getEvents(); - for (RecordsManagementEvent event : events) - { - // For every event create an entry on the action - createEvent(event, dispositionActionNodeRef); - } - } - } - } - /** * Creates the given records management event for the given 'next action'. * diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java index 0564e46dc4..9130a583ef 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java @@ -187,7 +187,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx if (nodeService.exists(actionedUponNodeRef) == true && getSetDispositionActionComplete() == true) { // Update the disposition schedule - updateNextDispositionAction(actionedUponNodeRef); + dispositionService.updateNextDispositionAction(actionedUponNodeRef); } } else diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java index f542fab238..b1ce2dc692 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java @@ -43,19 +43,19 @@ import org.apache.commons.logging.LogFactory; * Action to implement the consequences of a change to the value of the DispositionActionDefinition * properties. When these properties are changed on a disposition schedule, then any associated * disposition actions may need to be updated as a consequence. - * + * * @author Neil McErlean */ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionExecuterAbstractBase { /** Logger */ private static Log logger = LogFactory.getLog(BroadcastDispositionActionDefinitionUpdateAction.class); - + public static final String NAME = "broadcastDispositionActionDefinitionUpdate"; public static final String CHANGED_PROPERTIES = "changedProperties"; - + private BehaviourFilter behaviourFilter; - + public void setBehaviourFilter(BehaviourFilter behaviourFilter) { this.behaviourFilter = behaviourFilter; @@ -73,14 +73,14 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx { return; } - + List changedProps = (List)action.getParameterValue(CHANGED_PROPERTIES); // Navigate up the containment hierarchy to get the record category grandparent and schedule. NodeRef dispositionScheduleNode = nodeService.getPrimaryParent(actionedUponNodeRef).getParentRef(); NodeRef rmContainer = nodeService.getPrimaryParent(dispositionScheduleNode).getParentRef(); DispositionSchedule dispositionSchedule = dispositionService.getAssociatedDispositionSchedule(rmContainer); - + behaviourFilter.disableBehaviour(); try { @@ -95,9 +95,9 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx behaviourFilter.enableBehaviour(); } } - + /** - * + * * @param ds * @param disposableItem * @param dispositionActionDefinition @@ -111,7 +111,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx if (itemDs != null && itemDs.getNodeRef().equals(ds.getNodeRef()) == true) { - if (this.nodeService.hasAspect(disposableItem, ASPECT_DISPOSITION_LIFECYCLE)) + if (nodeService.hasAspect(disposableItem, ASPECT_DISPOSITION_LIFECYCLE)) { // disposition lifecycle already exists for node so process changes processActionDefinitionChanges(dispositionActionDefinition, changedProps, disposableItem); @@ -119,43 +119,43 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx else { // disposition lifecycle does not exist on the node so setup disposition - updateNextDispositionAction(disposableItem); + dispositionService.updateNextDispositionAction(disposableItem); } - + // update rolled up search information rollupSearchProperties(disposableItem); } } - + /** * Manually update the rolled up search properties - * + * * @param disposableItem disposable item */ private void rollupSearchProperties(NodeRef disposableItem) { DispositionAction da = dispositionService.getNextDispositionAction(disposableItem); if (da != null) - { + { Map props = nodeService.getProperties(disposableItem); - - props.put(PROP_RS_DISPOSITION_ACTION_NAME, da.getName()); - props.put(PROP_RS_DISPOSITION_ACTION_AS_OF, da.getAsOfDate()); - props.put(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE, this.nodeService.getProperty(da.getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE)); - - DispositionActionDefinition daDefinition = da.getDispositionActionDefinition(); + + props.put(PROP_RS_DISPOSITION_ACTION_NAME, da.getName()); + props.put(PROP_RS_DISPOSITION_ACTION_AS_OF, da.getAsOfDate()); + props.put(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE, nodeService.getProperty(da.getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE)); + + DispositionActionDefinition daDefinition = da.getDispositionActionDefinition(); Period period = daDefinition.getPeriod(); if (period != null) { props.put(PROP_RS_DISPOSITION_PERIOD, period.getPeriodType()); - props.put(PROP_RS_DISPOSITION_PERIOD_EXPRESSION, period.getExpression()); + props.put(PROP_RS_DISPOSITION_PERIOD_EXPRESSION, period.getExpression()); } else { props.put(PROP_RS_DISPOSITION_PERIOD, null); props.put(PROP_RS_DISPOSITION_PERIOD_EXPRESSION, null); } - + List events = da.getEventCompletionDetails(); List list = new ArrayList(events.size()); for (EventCompletionDetails event : events) @@ -163,7 +163,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx list.add(event.getEventName()); } props.put(PROP_RS_DISPOSITION_EVENTS, (Serializable)list); - + nodeService.setProperties(disposableItem, props); } } @@ -171,7 +171,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx /** * Processes all the changes applied to the given disposition * action definition node for the given record or folder node. - * + * * @param dispositionActionDef The disposition action definition node * @param changedProps The set of properties changed on the action definition * @param recordOrFolder The record or folder the changes potentially need to be applied to @@ -189,12 +189,12 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx { persistPeriodChanges(dispositionActionDef, nextAction); } - + if (changedProps.contains(PROP_DISPOSITION_EVENT) || changedProps.contains(PROP_DISPOSITION_EVENT_COMBINATION)) { persistEventChanges(dispositionActionDef, nextAction); } - + if (changedProps.contains(PROP_DISPOSITION_ACTION_NAME)) { String action = (String)nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_ACTION_NAME); @@ -202,20 +202,20 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx } } } - + /** * Determines whether the disposition action definition (step) being * updated has any effect on the given next action - * + * * @param dispositionActionDef The disposition action definition node - * @param nextAction The next disposition action + * @param nextAction The next disposition action * @return true if the step change affects the next action */ - private boolean doesChangedStepAffectNextAction(NodeRef dispositionActionDef, + private boolean doesChangedStepAffectNextAction(NodeRef dispositionActionDef, DispositionAction nextAction) { boolean affectsNextAction = false; - + if (dispositionActionDef != null && nextAction != null) { // check whether the id of the action definition node being changed @@ -226,10 +226,10 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx affectsNextAction = true; } } - + return affectsNextAction; } - + /** * Persists any changes made to the period on the given disposition action * definition on the given next action. @@ -240,24 +240,24 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx private void persistPeriodChanges(NodeRef dispositionActionDef, DispositionAction nextAction) { Date newAsOfDate = null; - Period dispositionPeriod = (Period)nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_PERIOD); - + Period dispositionPeriod = (Period) nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_PERIOD); + if (dispositionPeriod != null) { // calculate the new as of date as we have been provided a new period Date now = new Date(); newAsOfDate = dispositionPeriod.getNextDate(now); } - + if (logger.isDebugEnabled()) { - logger.debug("Set disposition as of date for next action '" + nextAction.getName() + + logger.debug("Set disposition as of date for next action '" + nextAction.getName() + "' (" + nextAction.getNodeRef() + ") to: " + newAsOfDate); } - - this.nodeService.setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_AS_OF, newAsOfDate); + + nodeService.setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_AS_OF, newAsOfDate); } - + /** * Persists any changes made to the events on the given disposition action * definition on the given next action. @@ -269,7 +269,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx private void persistEventChanges(NodeRef dispositionActionDef, DispositionAction nextAction) { // go through the current events on the next action and remove any that are not present any more - List stepEvents = (List)nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_EVENT); + List stepEvents = (List) nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_EVENT); List eventsList = nextAction.getEventCompletionDetails(); List nextActionEvents = new ArrayList(eventsList.size()); for (EventCompletionDetails event : eventsList) @@ -277,19 +277,19 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx // take note of the event names present on the next action String eventName = event.getEventName(); nextActionEvents.add(eventName); - + // if the event has been removed delete from next action if (stepEvents != null && stepEvents.contains(event.getEventName()) == false) { // remove the child association representing the event nodeService.removeChild(nextAction.getNodeRef(), event.getNodeRef()); - + if (logger.isDebugEnabled()) - logger.debug("Removed '" + eventName + "' from next action '" + nextAction.getName() + + logger.debug("Removed '" + eventName + "' from next action '" + nextAction.getName() + "' (" + nextAction.getNodeRef() + ")"); } } - + // go through the disposition action definition step events and add any new ones if (stepEvents != null) { @@ -298,29 +298,29 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx if (!nextActionEvents.contains(eventName)) { createEvent(recordsManagementEventService.getEvent(eventName), nextAction.getNodeRef()); - + if (logger.isDebugEnabled()) { - logger.debug("Added '" + eventName + "' to next action '" + nextAction.getName() + + logger.debug("Added '" + eventName + "' to next action '" + nextAction.getName() + "' (" + nextAction.getNodeRef() + ")"); } } } } - + // NOTE: eventsList contains all the events that have been updated! // TODO: manually update the search properties for the parent node! - + // finally since events may have changed re-calculate the events eligible flag boolean eligible = updateEventEligible(nextAction); - + if (logger.isDebugEnabled()) { - logger.debug("Set events eligible flag to '" + eligible + "' for next action '" + nextAction.getName() + + logger.debug("Set events eligible flag to '" + eligible + "' for next action '" + nextAction.getName() + "' (" + nextAction.getNodeRef() + ")"); } } - + @Override protected void addParameterDefinitions(List paramList) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java index 92d923ce5d..ee38b1e197 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java @@ -18,28 +18,11 @@ */ package org.alfresco.module.org_alfresco_module_rm.action.impl; -import java.io.Serializable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.RMDispositionActionExecuterAbstractBase; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition; -import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; +import org.alfresco.module.org_alfresco_module_rm.transfer.TransferService; import org.alfresco.repo.action.executer.ActionExecuter; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.apache.commons.lang.StringUtils; -import org.springframework.extensions.surf.util.I18NUtil; /** * Transfer action @@ -48,25 +31,11 @@ import org.springframework.extensions.surf.util.I18NUtil; */ public class TransferAction extends RMDispositionActionExecuterAbstractBase { - /** Transfer node reference key */ - public static final String KEY_TRANSFER_NODEREF = "transferNodeRef"; - - /** I18N */ - private static final String MSG_NODE_ALREADY_TRANSFER = "rm.action.node-already-transfer"; - /** Indicates whether the transfer is an accession or not */ private boolean isAccession = false; - /** File plan service */ - private FilePlanService filePlanService; - - /** - * @param filePlanService file plan service - */ - public void setFilePlanService(FilePlanService filePlanService) - { - this.filePlanService = filePlanService; - } + /** transfer service */ + private TransferService transferService; /** * Indicates whether this transfer is an accession or not @@ -78,6 +47,14 @@ public class TransferAction extends RMDispositionActionExecuterAbstractBase this.isAccession = isAccession; } + /** + * @param transferService transfer service + */ + public void setTransferService(TransferService transferService) + { + this.transferService = transferService; + } + /** * Do not set the transfer action to auto-complete * @@ -110,102 +87,14 @@ public class TransferAction extends RMDispositionActionExecuterAbstractBase /** * Create the transfer node and link the disposition lifecycle node beneath it * - * @param dispositionLifeCycleNodeRef disposition lifecycle node + * @param action action + * @param dispositionLifeCycleNodeRef disposition lifecycle node */ private void doTransfer(Action action, NodeRef dispositionLifeCycleNodeRef) { - // Get the root rm node - NodeRef root = filePlanService.getFilePlan(dispositionLifeCycleNodeRef); - - // Get the transfer object - NodeRef transferNodeRef = (NodeRef)AlfrescoTransactionSupport.getResource(KEY_TRANSFER_NODEREF); - if (transferNodeRef == null) - { - // Calculate a transfer name - QName nodeDbid = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "node-dbid"); - Long dbId = (Long)this.nodeService.getProperty(dispositionLifeCycleNodeRef, nodeDbid); - String transferName = StringUtils.leftPad(dbId.toString(), 10, "0"); - - // Create the transfer object - Map transferProps = new HashMap(2); - transferProps.put(ContentModel.PROP_NAME, transferName); - transferProps.put(PROP_TRANSFER_ACCESSION_INDICATOR, this.isAccession); - - // setup location property from disposition schedule - DispositionAction da = dispositionService.getNextDispositionAction(dispositionLifeCycleNodeRef); - if (da != null) - { - DispositionActionDefinition actionDef = da.getDispositionActionDefinition(); - if (actionDef != null) - { - transferProps.put(PROP_TRANSFER_LOCATION, actionDef.getLocation()); - } - } - - NodeRef transferContainer = filePlanService.getTransferContainer(root); - transferNodeRef = this.nodeService.createNode(transferContainer, - ContentModel.ASSOC_CONTAINS, - QName.createQName(RM_URI, transferName), - TYPE_TRANSFER, - transferProps).getChildRef(); - - // Bind the hold node reference to the transaction - AlfrescoTransactionSupport.bindResource(KEY_TRANSFER_NODEREF, transferNodeRef); - } - else - { - // ensure this node has not already in the process of being transferred - List transferredAlready = nodeService.getChildAssocs(transferNodeRef, ASSOC_TRANSFERRED, ASSOC_TRANSFERRED); - for(ChildAssociationRef car : transferredAlready) - { - if(car.getChildRef().equals(dispositionLifeCycleNodeRef) == true) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NODE_ALREADY_TRANSFER, dispositionLifeCycleNodeRef.toString())); - - } - } - } - - // Link the record to the trasnfer object - this.nodeService.addChild(transferNodeRef, - dispositionLifeCycleNodeRef, - ASSOC_TRANSFERRED, - ASSOC_TRANSFERRED); - - // Set PDF indicator flag - setPDFIndicationFlag(transferNodeRef, dispositionLifeCycleNodeRef); - - // Set the transferring indicator aspect - nodeService.addAspect(dispositionLifeCycleNodeRef, ASPECT_TRANSFERRING, null); + NodeRef transferNodeRef = transferService.transfer(dispositionLifeCycleNodeRef, isAccession); // Set the return value of the action action.setParameterValue(ActionExecuter.PARAM_RESULT, transferNodeRef); } - - /** - * - * @param transferNodeRef - * @param dispositionLifeCycleNodeRef - */ - private void setPDFIndicationFlag(NodeRef transferNodeRef, NodeRef dispositionLifeCycleNodeRef) - { - if (recordFolderService.isRecordFolder(dispositionLifeCycleNodeRef) == true) - { - List records = recordService.getRecords(dispositionLifeCycleNodeRef); - for (NodeRef record : records) - { - setPDFIndicationFlag(transferNodeRef, record); - } - } - else - { - ContentData contentData = (ContentData)nodeService.getProperty(dispositionLifeCycleNodeRef, ContentModel.PROP_CONTENT); - if (contentData != null && - MimetypeMap.MIMETYPE_PDF.equals(contentData.getMimetype()) == true) - { - // Set the property indicator - nodeService.setProperty(transferNodeRef, PROP_TRANSFER_PDF_INDICATOR, true); - } - } - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java index 5b72524dbb..a9cf8e4f7a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java @@ -18,19 +18,12 @@ */ package org.alfresco.module.org_alfresco_module_rm.action.impl; -import java.util.Date; -import java.util.List; - import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.module.org_alfresco_module_rm.transfer.TransferService; import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; import org.springframework.extensions.surf.util.I18NUtil; /** @@ -43,6 +36,17 @@ public class TransferCompleteAction extends RMActionExecuterAbstractBase /** I18N */ private static final String MSG_NODE_NOT_TRANSFER = "rm.action.node-not-transfer"; + /** Transfer service */ + protected TransferService transferService; + + /** + * @param transferService transfer service + */ + public void setTransferService(TransferService transferService) + { + this.transferService = transferService; + } + /** * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, * org.alfresco.service.cmr.repository.NodeRef) @@ -50,80 +54,21 @@ public class TransferCompleteAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - QName className = this.nodeService.getType(actionedUponNodeRef); - if (this.dictionaryService.isSubClass(className, TYPE_TRANSFER) == true) - { - boolean accessionIndicator = ((Boolean)nodeService.getProperty(actionedUponNodeRef, PROP_TRANSFER_ACCESSION_INDICATOR)).booleanValue(); - String transferLocation = nodeService.getProperty(actionedUponNodeRef, PROP_TRANSFER_LOCATION).toString(); + checkTransferSubClass(actionedUponNodeRef); + transferService.complete(actionedUponNodeRef); + } - List assocs = this.nodeService.getChildAssocs(actionedUponNodeRef, ASSOC_TRANSFERRED, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef assoc : assocs) - { - markComplete(assoc.getChildRef(), accessionIndicator, transferLocation); - } - - // Delete the transfer object - this.nodeService.deleteNode(actionedUponNodeRef); - - NodeRef transferNodeRef = (NodeRef) AlfrescoTransactionSupport.getResource(TransferAction.KEY_TRANSFER_NODEREF); - if (transferNodeRef != null) - { - if (transferNodeRef.equals(actionedUponNodeRef)) - { - AlfrescoTransactionSupport.bindResource(TransferAction.KEY_TRANSFER_NODEREF, null); - } - } - } - else + /** + * Checks if the actioned upon node reference is a sub class of transfer + * + * @param actionedUponNodeRef actioned upon node reference + */ + private void checkTransferSubClass(NodeRef actionedUponNodeRef) + { + QName type = nodeService.getType(actionedUponNodeRef); + if (dictionaryService.isSubClass(type, TYPE_TRANSFER) == false) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NODE_NOT_TRANSFER)); } } - - /** - * Marks the node complete - * - * @param nodeRef - * disposition lifecycle node reference - */ - private void markComplete(NodeRef nodeRef, boolean accessionIndicator, String transferLocation) - { - // Set the completed date - DispositionAction da = dispositionService.getNextDispositionAction(nodeRef); - if (da != null) - { - nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_AT, new Date()); - nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_BY, AuthenticationUtil.getRunAsUser()); - } - - // Remove the transferring indicator aspect - nodeService.removeAspect(nodeRef, ASPECT_TRANSFERRING); - nodeService.setProperty(nodeRef, PROP_LOCATION, transferLocation); - - // Determine which marker aspect to use - QName markerAspectQName = null; - if (accessionIndicator == true) - { - markerAspectQName = ASPECT_ASCENDED; - } - else - { - markerAspectQName = ASPECT_TRANSFERRED; - } - - // Mark the object and children accordingly - nodeService.addAspect(nodeRef, markerAspectQName, null); - if (recordFolderService.isRecordFolder(nodeRef) == true) - { - List records = recordService.getRecords(nodeRef); - for (NodeRef record : records) - { - nodeService.addAspect(record, markerAspectQName, null); - nodeService.setProperty(record, PROP_LOCATION, transferLocation); - } - } - - // Update to the next disposition action - updateNextDispositionAction(nodeRef); - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java index d7a742fd5a..bcf6cc8a71 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java @@ -209,4 +209,11 @@ public interface DispositionService * @since 2.0 */ boolean isCutoff(NodeRef nodeRef); + + /** + * Updates the next disposition action + * + * @param nodeRef node reference + */ + void updateNextDispositionAction(NodeRef nodeRef); } 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 4696c82f8c..9a70807641 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 @@ -845,4 +845,128 @@ public class DispositionServiceImpl implements ParameterCheck.mandatory("nodeRef", nodeRef); return nodeService.hasAspect(nodeRef, ASPECT_CUT_OFF); } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef) + */ + @Override + public void updateNextDispositionAction(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + // Get this disposition instructions for the node + DispositionSchedule di = getDispositionSchedule(nodeRef); + if (di != null) + { + // Get the current action node + NodeRef currentDispositionAction = null; + if (nodeService.hasAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE) == true) + { + List assocs = nodeService.getChildAssocs(nodeRef, ASSOC_NEXT_DISPOSITION_ACTION, RegexQNamePattern.MATCH_ALL); + if (assocs.size() > 0) + { + currentDispositionAction = assocs.get(0).getChildRef(); + } + } + + if (currentDispositionAction != null) + { + // Move it to the history association + nodeService.moveNode(currentDispositionAction, nodeRef, ASSOC_DISPOSITION_ACTION_HISTORY, ASSOC_DISPOSITION_ACTION_HISTORY); + } + + List dispositionActionDefinitions = di.getDispositionActionDefinitions(); + DispositionActionDefinition currentDispositionActionDefinition = null; + DispositionActionDefinition nextDispositionActionDefinition = null; + + if (currentDispositionAction == null) + { + if (dispositionActionDefinitions.isEmpty() == false) + { + // The next disposition action is the first action + nextDispositionActionDefinition = dispositionActionDefinitions.get(0); + } + } + else + { + // Get the current action + String currentADId = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION_ID); + currentDispositionActionDefinition = di.getDispositionActionDefinition(currentADId); + + // Get the next disposition action + int index = currentDispositionActionDefinition.getIndex(); + index++; + if (index < dispositionActionDefinitions.size()) + { + nextDispositionActionDefinition = dispositionActionDefinitions.get(index); + } + } + + if (nextDispositionActionDefinition != null) + { + if (nodeService.hasAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE) == false) + { + // Add the disposition life cycle aspect + nodeService.addAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE, null); + } + + // Create the properties + Map props = new HashMap(10); + + // Calculate the asOf date + Date asOfDate = null; + Period period = nextDispositionActionDefinition.getPeriod(); + if (period != null) + { + Date contextDate = null; + + // Get the period properties value + QName periodProperty = nextDispositionActionDefinition.getPeriodProperty(); + if (periodProperty != null && + RecordsManagementModel.PROP_DISPOSITION_AS_OF.equals(periodProperty) == false) + { + // doesn't matter if the period property isn't set ... the asOfDate will get updated later + // when the value of the period property is set + contextDate = (Date) nodeService.getProperty(nodeRef, periodProperty); + } + else + { + // for now use 'NOW' as the default context date + // TODO set the default period property ... cut off date or last disposition date depending on context + contextDate = new Date(); + } + + // Calculate the as of date + if (contextDate != null) + { + asOfDate = period.getNextDate(contextDate); + } + } + + // Set the property values + props.put(PROP_DISPOSITION_ACTION_ID, nextDispositionActionDefinition.getId()); + props.put(PROP_DISPOSITION_ACTION, nextDispositionActionDefinition.getName()); + if (asOfDate != null) + { + props.put(PROP_DISPOSITION_AS_OF, asOfDate); + } + + // Create a new disposition action object + NodeRef dispositionActionNodeRef = nodeService.createNode( + nodeRef, + ASSOC_NEXT_DISPOSITION_ACTION, + ASSOC_NEXT_DISPOSITION_ACTION, + TYPE_DISPOSITION_ACTION, + props).getChildRef(); + + // Create the events + List events = nextDispositionActionDefinition.getEvents(); + for (RecordsManagementEvent event : events) + { + // For every event create an entry on the action + createEvent(event, dispositionActionNodeRef); + } + } + } + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferService.java index 83db9939ba..9b0bc35bdc 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferService.java @@ -37,4 +37,24 @@ public interface TransferService * @since 2.0 */ boolean isTransfer(NodeRef nodeRef); + + /** + * Create the transfer node and link the disposition lifecycle node beneath it + * + * @param nodeRef node reference to transfer + * @param isAccession Indicates whether this transfer is an accession or not + * @return Returns the transfer object node reference + * + * @since 2.2 + */ + NodeRef transfer(NodeRef nodeRef, boolean isAccession); + + /** + * Completes the transfer for the given node. + * + * @param nodeRef node reference to complete the transfer + * + * @since 2.2 + */ + void complete(NodeRef nodeRef); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java index 7c57663891..677c0fa4ef 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java @@ -18,9 +18,33 @@ */ package org.alfresco.module.org_alfresco_module_rm.transfer; +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; +import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.apache.commons.lang.StringUtils; +import org.springframework.extensions.surf.util.I18NUtil; import org.springframework.extensions.surf.util.ParameterCheck; /** @@ -31,6 +55,56 @@ import org.springframework.extensions.surf.util.ParameterCheck; */ public class TransferServiceImpl extends ServiceBaseImpl implements TransferService, RecordsManagementModel { + /** Transfer node reference key */ + public static final String KEY_TRANSFER_NODEREF = "transferNodeRef"; + + /** I18N */ + private static final String MSG_NODE_ALREADY_TRANSFER = "rm.action.node-already-transfer"; + + /** File Plan Service */ + protected FilePlanService filePlanService; + + /** Disposition service */ + protected DispositionService dispositionService; + + /** Record service */ + protected RecordService recordService; + + /** Record folder service */ + protected RecordFolderService recordFolderService; + + /** + * @param filePlanService file plan service + */ + public void setFilePlanService(FilePlanService filePlanService) + { + this.filePlanService = filePlanService; + } + + /** + * @param dispositionService disposition service + */ + public void setDispositionService(DispositionService dispositionService) + { + this.dispositionService = dispositionService; + } + + /** + * @param recordService record service + */ + public void setRecordService(RecordService recordService) + { + this.recordService = recordService; + } + + /** + * @param recordFolderService record folder service + */ + public void setRecordFolderService(RecordFolderService recordFolderService) + { + this.recordFolderService = recordFolderService; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.transfer.TransferService#isTransfer(NodeRef) */ @@ -40,4 +114,181 @@ public class TransferServiceImpl extends ServiceBaseImpl implements TransferServ ParameterCheck.mandatory("nodeRef", nodeRef); return instanceOf(nodeRef, TYPE_TRANSFER); } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.transfer.TransferService#transfer(NodeRef, boolean) + */ + @Override + public NodeRef transfer(NodeRef nodeRef, boolean isAccession) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + // Get the root rm node + NodeRef root = filePlanService.getFilePlan(nodeRef); + + // Get the transfer object + NodeRef transferNodeRef = (NodeRef)AlfrescoTransactionSupport.getResource(KEY_TRANSFER_NODEREF); + if (transferNodeRef == null) + { + // Calculate a transfer name + QName nodeDbid = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "node-dbid"); + Long dbId = (Long) nodeService.getProperty(nodeRef, nodeDbid); + String transferName = StringUtils.leftPad(dbId.toString(), 10, "0"); + + // Create the transfer object + Map transferProps = new HashMap(2); + transferProps.put(ContentModel.PROP_NAME, transferName); + transferProps.put(PROP_TRANSFER_ACCESSION_INDICATOR, isAccession); + + // setup location property from disposition schedule + DispositionAction da = dispositionService.getNextDispositionAction(nodeRef); + if (da != null) + { + DispositionActionDefinition actionDef = da.getDispositionActionDefinition(); + if (actionDef != null) + { + transferProps.put(PROP_TRANSFER_LOCATION, actionDef.getLocation()); + } + } + + NodeRef transferContainer = filePlanService.getTransferContainer(root); + transferNodeRef = nodeService.createNode(transferContainer, + ContentModel.ASSOC_CONTAINS, + QName.createQName(RM_URI, transferName), + TYPE_TRANSFER, + transferProps).getChildRef(); + + // Bind the hold node reference to the transaction + AlfrescoTransactionSupport.bindResource(KEY_TRANSFER_NODEREF, transferNodeRef); + } + else + { + // ensure this node has not already in the process of being transferred + List transferredAlready = nodeService.getChildAssocs(transferNodeRef, ASSOC_TRANSFERRED, ASSOC_TRANSFERRED); + for(ChildAssociationRef car : transferredAlready) + { + if(car.getChildRef().equals(nodeRef) == true) + { + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NODE_ALREADY_TRANSFER, nodeRef.toString())); + + } + } + } + + // Link the record to the trasnfer object + nodeService.addChild(transferNodeRef, + nodeRef, + ASSOC_TRANSFERRED, + ASSOC_TRANSFERRED); + + // Set PDF indicator flag + setPDFIndicationFlag(transferNodeRef, nodeRef); + + // Set the transferring indicator aspect + nodeService.addAspect(nodeRef, ASPECT_TRANSFERRING, null); + + return transferNodeRef; + } + + /** + * + * @param transferNodeRef + * @param dispositionLifeCycleNodeRef + */ + private void setPDFIndicationFlag(NodeRef transferNodeRef, NodeRef dispositionLifeCycleNodeRef) + { + if (recordFolderService.isRecordFolder(dispositionLifeCycleNodeRef) == true) + { + List records = recordService.getRecords(dispositionLifeCycleNodeRef); + for (NodeRef record : records) + { + setPDFIndicationFlag(transferNodeRef, record); + } + } + else + { + ContentData contentData = (ContentData)nodeService.getProperty(dispositionLifeCycleNodeRef, ContentModel.PROP_CONTENT); + if (contentData != null && + MimetypeMap.MIMETYPE_PDF.equals(contentData.getMimetype()) == true) + { + // Set the property indicator + nodeService.setProperty(transferNodeRef, PROP_TRANSFER_PDF_INDICATOR, true); + } + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.transfer.TransferService#complete(NodeRef) + */ + @Override + public void complete(NodeRef nodeRef) + { + boolean accessionIndicator = ((Boolean)nodeService.getProperty(nodeRef, PROP_TRANSFER_ACCESSION_INDICATOR)).booleanValue(); + String transferLocation = nodeService.getProperty(nodeRef, PROP_TRANSFER_LOCATION).toString(); + + List assocs = nodeService.getChildAssocs(nodeRef, ASSOC_TRANSFERRED, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef assoc : assocs) + { + markComplete(assoc.getChildRef(), accessionIndicator, transferLocation); + } + + // Delete the transfer object + nodeService.deleteNode(nodeRef); + + NodeRef transferNodeRef = (NodeRef) AlfrescoTransactionSupport.getResource(KEY_TRANSFER_NODEREF); + if (transferNodeRef != null) + { + if (transferNodeRef.equals(nodeRef)) + { + AlfrescoTransactionSupport.bindResource(KEY_TRANSFER_NODEREF, null); + } + } + } + + /** + * Marks the node complete + * + * @param nodeRef + * disposition lifecycle node reference + */ + private void markComplete(NodeRef nodeRef, boolean accessionIndicator, String transferLocation) + { + // Set the completed date + DispositionAction da = dispositionService.getNextDispositionAction(nodeRef); + if (da != null) + { + nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_AT, new Date()); + nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_BY, AuthenticationUtil.getRunAsUser()); + } + + // Remove the transferring indicator aspect + nodeService.removeAspect(nodeRef, ASPECT_TRANSFERRING); + nodeService.setProperty(nodeRef, PROP_LOCATION, transferLocation); + + // Determine which marker aspect to use + QName markerAspectQName = null; + if (accessionIndicator == true) + { + markerAspectQName = ASPECT_ASCENDED; + } + else + { + markerAspectQName = ASPECT_TRANSFERRED; + } + + // Mark the object and children accordingly + nodeService.addAspect(nodeRef, markerAspectQName, null); + if (recordFolderService.isRecordFolder(nodeRef) == true) + { + List records = recordService.getRecords(nodeRef); + for (NodeRef record : records) + { + nodeService.addAspect(record, markerAspectQName, null); + nodeService.setProperty(record, PROP_LOCATION, transferLocation); + } + } + + // Update to the next disposition action + dispositionService.updateNextDispositionAction(nodeRef); + } }