RM-1097: Refactored TransferAction and TransferCompleteAction

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@57963 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2013-11-18 14:45:12 +00:00
parent 3c8e7ed6fc
commit 23c9d41bb4
11 changed files with 606 additions and 490 deletions

View File

@@ -699,7 +699,7 @@
</bean> </bean>
<bean id="transfer" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction" parent="rmAction"> <bean id="transfer" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction" parent="rmAction">
<property name="filePlanService" ref="FilePlanService" /> <property name="transferService" ref="RmTransferService" />
<property name="isAccession" value="false"/> <property name="isAccession" value="false"/>
</bean> </bean>
@@ -717,6 +717,7 @@
</bean> </bean>
<bean id="transferComplete" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferCompleteAction" parent="rmAction" > <bean id="transferComplete" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferCompleteAction" parent="rmAction" >
<property name="transferService" ref="RmTransferService" />
<property name="auditedImmediately" value="true"/> <property name="auditedImmediately" value="true"/>
</bean> </bean>
@@ -744,7 +745,7 @@
</bean> </bean>
<bean id="accession" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction" parent="rmAction"> <bean id="accession" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction" parent="rmAction">
<property name="filePlanService" ref="FilePlanService" /> <property name="transferService" ref="RmTransferService" />
<property name="isAccession" value="true"/> <property name="isAccession" value="true"/>
</bean> </bean>
@@ -762,6 +763,7 @@
</bean> </bean>
<bean id="accessionComplete" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferCompleteAction" parent="rmAction"> <bean id="accessionComplete" class="org.alfresco.module.org_alfresco_module_rm.action.impl.TransferCompleteAction" parent="rmAction">
<property name="transferService" ref="RmTransferService" />
<property name="auditedImmediately" value="true"/> <property name="auditedImmediately" value="true"/>
</bean> </bean>

View File

@@ -3,9 +3,9 @@
<beans> <beans>
<!-- Helper beans --> <!-- Helper beans -->
<bean id="baseTransaction" abstract="true" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <bean id="baseTransaction" abstract="true" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager"> <property name="transactionManager">
<ref bean="transactionManager"/> <ref bean="transactionManager"/>
</property> </property>
@@ -26,12 +26,12 @@
<property name="afterInvocationManager"> <property name="afterInvocationManager">
<ref bean="afterInvocationManager"/> <ref bean="afterInvocationManager"/>
</property> </property>
</bean> </bean>
<bean id="baseService" abstract="true"> <bean id="baseService" abstract="true">
<property name="nodeService" ref="NodeService"/> <property name="nodeService" ref="NodeService"/>
<property name="dictionaryService" ref="DictionaryService"/> <property name="dictionaryService" ref="DictionaryService"/>
</bean> </bean>
<!-- Records Management Service Registry --> <!-- Records Management Service Registry -->
@@ -259,7 +259,12 @@
</bean> </bean>
<!-- Transfer Service --> <!-- Transfer Service -->
<bean id="rmTransferService" class="org.alfresco.module.org_alfresco_module_rm.transfer.TransferServiceImpl" parent="baseService" /> <bean id="rmTransferService" class="org.alfresco.module.org_alfresco_module_rm.transfer.TransferServiceImpl" parent="baseService">
<property name="filePlanService" ref="FilePlanService" />
<property name="dispositionService" ref="DispositionService" />
<property name="recordService" ref="RecordService" />
<property name="recordFolderService" ref="RecordFolderService" />
</bean>
<bean id="RmTransferService" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="RmTransferService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"> <property name="proxyInterfaces">
@@ -367,74 +372,74 @@
<property name="namespaceService" ref="NamespaceService" /> <property name="namespaceService" ref="NamespaceService" />
<property name="searchService" ref="SearchService" /> <property name="searchService" ref="SearchService" />
<property name="reportsJSON"> <property name="reportsJSON">
<value> <value>
<![CDATA[ <![CDATA[
[ [
{ {
"name" : "rm.savedsearch.vitalRecordsName", "name" : "rm.savedsearch.vitalRecordsName",
"description" : "rm.savedsearch.vitalRecordsDesc", "description" : "rm.savedsearch.vitalRecordsDesc",
"search" : "rma:reviewAsOf:[MIN TO TODAY]", "search" : "rma:reviewAsOf:[MIN TO TODAY]",
"searchparams" : "searchparams" :
{ {
"records" : true, "records" : true,
"vitalrecords" : true "vitalrecords" : true
} }
}, },
{ {
"name" : "rm.savedsearch.incompleteRecordsName", "name" : "rm.savedsearch.incompleteRecordsName",
"description" : "rm.savedsearch.incompleteRecordsDesc", "description" : "rm.savedsearch.incompleteRecordsDesc",
"search" : "ISNODE:T AND NOT ASPECT:\"rma:declaredRecord\"", "search" : "ISNODE:T AND NOT ASPECT:\"rma:declaredRecord\"",
"searchparams" : "searchparams" :
{ {
"records" : true, "records" : true,
"recordfolders" : false, "recordfolders" : false,
"undeclaredrecords" : true "undeclaredrecords" : true
} }
}, },
{ {
"name" : "rm.savedsearch.cutoffRecordsName", "name" : "rm.savedsearch.cutoffRecordsName",
"description" : "rm.savedsearch.cutoffRecordsDesc", "description" : "rm.savedsearch.cutoffRecordsDesc",
"search" : "dispositionActionName:\"cutoff\" AND (dispositionEventsEligible:true OR dispositionActionAsOf:[MIN TO TODAY]) AND NOT ASPECT:\"rma:cutoff\"", "search" : "dispositionActionName:\"cutoff\" AND (dispositionEventsEligible:true OR dispositionActionAsOf:[MIN TO TODAY]) AND NOT ASPECT:\"rma:cutoff\"",
"searchparams" : "searchparams" :
{ {
"records" : true, "records" : true,
"recordfolders" : true "recordfolders" : true
} }
}, },
{ {
"name" : "rm.savedsearch.transferRecordsName", "name" : "rm.savedsearch.transferRecordsName",
"description" : "rm.savedsearch.transferRecordsDesc", "description" : "rm.savedsearch.transferRecordsDesc",
"search" : "dispositionActionName:\"transfer\" AND (dispositionEventsEligible:true OR dispositionActionAsOf:[MIN TO TODAY]) AND NOT ASPECT:\"rma:transferred\" AND NOT ASPECT:\"rma:transferring\"", "search" : "dispositionActionName:\"transfer\" AND (dispositionEventsEligible:true OR dispositionActionAsOf:[MIN TO TODAY]) AND NOT ASPECT:\"rma:transferred\" AND NOT ASPECT:\"rma:transferring\"",
"searchparams" : "searchparams" :
{ {
"records" : true, "records" : true,
"recordfolders" : true, "recordfolders" : true,
"cutoff" : true "cutoff" : true
} }
}, },
{ {
"name" : "rm.savedsearch.destructionRecordsName", "name" : "rm.savedsearch.destructionRecordsName",
"description" : "rm.savedsearch.destructionRecordsDesc", "description" : "rm.savedsearch.destructionRecordsDesc",
"search" : "dispositionActionName:\"destroy\" AND (dispositionEventsEligible:true OR dispositionActionAsOf:[MIN TO TODAY]) AND NOT ASPECT:\"rma:ghosted\"", "search" : "dispositionActionName:\"destroy\" AND (dispositionEventsEligible:true OR dispositionActionAsOf:[MIN TO TODAY]) AND NOT ASPECT:\"rma:ghosted\"",
"searchparams" : "searchparams" :
{ {
"records" : true, "records" : true,
"recordfolders" : true, "recordfolders" : true,
"cutoff" : true "cutoff" : true
} }
}, },
{ {
"name" : "rm.savedsearch.frozenRecordsName", "name" : "rm.savedsearch.frozenRecordsName",
"description" : "rm.savedsearch.frozenRecordsDesc", "description" : "rm.savedsearch.frozenRecordsDesc",
"search" : "ISNODE:T", "search" : "ISNODE:T",
"searchparams" : "searchparams" :
{ {
"records" : true, "records" : true,
"recordfolders" : true, "recordfolders" : true,
"frozen" : true, "frozen" : true,
"undeclaredrecords" : true "undeclaredrecords" : true
} }
} }
] ]
]]> ]]>
</value> </value>
@@ -495,8 +500,8 @@
<!-- File Plan Service --> <!-- File Plan Service -->
<bean id="filePlanService" <bean id="filePlanService"
parent="baseService" parent="baseService"
class="org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanServiceImpl"> class="org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanServiceImpl">
<!-- NOTE: for some reason we need to grab these references within the class to avoid cyclic Spring issues! --> <!-- NOTE: for some reason we need to grab these references within the class to avoid cyclic Spring issues! -->
<!-- <property name="permissionService" ref="permissionService"/> --> <!-- <property name="permissionService" ref="permissionService"/> -->
@@ -555,10 +560,10 @@
</property> </property>
</bean> </bean>
<!-- File Plan Permission Service --> <!-- File Plan Permission Service -->
<bean id="filePlanPermissionService" <bean id="filePlanPermissionService"
parent="baseService" parent="baseService"
class="org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionServiceImpl" class="org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionServiceImpl"
init-method="init"> init-method="init">
<property name="permissionService" ref="PermissionService"/> <property name="permissionService" ref="PermissionService"/>
@@ -610,7 +615,7 @@
<![CDATA[ <![CDATA[
org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService.setPermission=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService.setPermission=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService.deletePermission=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService.deletePermission=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService.*=RM_DENY org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService.*=RM_DENY
]]> ]]>
</value> </value>
</property> </property>
@@ -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.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.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.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
]]> ]]>
</value> </value>
</property> </property>
@@ -732,7 +737,7 @@
<property name="objectDefinitionSource"> <property name="objectDefinitionSource">
<value> <value>
<![CDATA[ <![CDATA[
org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService.*=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService.*=RM_ALLOW
]]> ]]>
</value> </value>
</property> </property>
@@ -744,10 +749,10 @@
class="org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityServiceImpl" class="org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityServiceImpl"
init-method="init"> init-method="init">
<property name="enabled" value="true" /> <property name="enabled" value="true" />
<property name="policyComponent" ref="policyComponent" /> <property name="policyComponent" ref="policyComponent" />
<property name="nodeService" ref="NodeService" /> <property name="nodeService" ref="NodeService" />
<property name="namespaceService" ref="namespaceService" /> <property name="namespaceService" ref="namespaceService" />
<property name="filePlanService" ref="FilePlanService" /> <property name="filePlanService" ref="FilePlanService" />
</bean> </bean>
<bean id="ModelSecurityService" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="ModelSecurityService" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -790,7 +795,7 @@
<property name="objectDefinitionSource"> <property name="objectDefinitionSource">
<value> <value>
<![CDATA[ <![CDATA[
org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityService.*=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityService.*=RM_ALLOW
]]> ]]>
</value> </value>
</property> </property>
@@ -936,12 +941,12 @@
<property name="contentService" ref="contentService"/> <property name="contentService" ref="contentService"/>
<property name="dictionaryRepositoryBootstrap" ref="dictionaryRepositoryBootstrap"/> <property name="dictionaryRepositoryBootstrap" ref="dictionaryRepositoryBootstrap"/>
<property name="customisableTypes"> <property name="customisableTypes">
<list> <list>
<value>rma:recordCategory</value> <value>rma:recordCategory</value>
<value>rma:recordFolder</value> <value>rma:recordFolder</value>
<value>rma:record</value> <value>rma:record</value>
<value>rma:nonElectronicDocument</value> <value>rma:nonElectronicDocument</value>
</list> </list>
</property> </property>
</bean> </bean>
@@ -1320,7 +1325,7 @@
<bean id="filePlanAuthenticationService" <bean id="filePlanAuthenticationService"
class="org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationServiceImpl"> class="org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationServiceImpl">
<property name="rmAdminUserName" value="${bootstrap.rmadmin.name}" /> <property name="rmAdminUserName" value="${bootstrap.rmadmin.name}" />
<property name="tenantService"> <property name="tenantService">
<ref bean="tenantService"/> <ref bean="tenantService"/>
</property> </property>
@@ -1348,7 +1353,7 @@
<property name="objectDefinitionSource"> <property name="objectDefinitionSource">
<value> <value>
<![CDATA[ <![CDATA[
org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationService.*=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationService.*=RM_ALLOW
]]> ]]>
</value> </value>
</property> </property>
@@ -1433,15 +1438,15 @@
<!-- RM Notification Helper --> <!-- RM Notification Helper -->
<bean id="recordsManagementNotificationHelper" class="org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper" > <bean id="recordsManagementNotificationHelper" class="org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper" >
<property name="filePlanRoleService" ref="FilePlanRoleService"/> <property name="filePlanRoleService" ref="FilePlanRoleService"/>
<property name="notificationService" ref="NotificationService"/> <property name="notificationService" ref="NotificationService"/>
<property name="filePlanService" ref="FilePlanService"/> <property name="filePlanService" ref="FilePlanService"/>
<property name="nodeService" ref="nodeService"/> <property name="nodeService" ref="nodeService"/>
<property name="tenantAdminService" ref="tenantAdminService"/> <property name="tenantAdminService" ref="tenantAdminService"/>
<property name="namespaceService" ref="namespaceService"/> <property name="namespaceService" ref="namespaceService"/>
<property name="searchService" ref="searchService"/> <property name="searchService" ref="searchService"/>
<property name="siteService" ref="SiteService" /> <property name="siteService" ref="SiteService" />
<property name="authorityService" ref="authorityService" /> <property name="authorityService" ref="authorityService" />
<property name="notificationRole" value="${rm.notification.role}"/> <property name="notificationRole" value="${rm.notification.role}"/>
</bean> </bean>
<!-- RM caveats --> <!-- RM caveats -->
@@ -1470,12 +1475,12 @@
</bean> </bean>
<!-- ===================================== --> <!-- ===================================== -->
<!-- Record Management Caveat Config Cache --> <!-- Record Management Caveat Config Cache -->
<!-- ===================================== --> <!-- ===================================== -->
<!-- The cross-transaction shared cache for in-memory CaveatConfig --> <!-- The cross-transaction shared cache for in-memory CaveatConfig -->
<bean name="caveatConfigSharedCache" class="org.alfresco.repo.cache.DefaultSimpleCache"/> <bean name="caveatConfigSharedCache" class="org.alfresco.repo.cache.DefaultSimpleCache"/>
<!-- The transactional cache for in-memory CaveatConfig --> <!-- The transactional cache for in-memory CaveatConfig -->

View File

@@ -19,7 +19,6 @@
package org.alfresco.module.org_alfresco_module_rm.action; package org.alfresco.module.org_alfresco_module_rm.action;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; 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.admin.RecordsManagementAdminService;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService; 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.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.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.event.EventCompletionDetails; import org.alfresco.module.org_alfresco_module_rm.event.EventCompletionDetails;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent; 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.ActionService;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; 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.ContentService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; 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.cmr.security.OwnableService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.BeanNameAware;
@@ -475,127 +469,6 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe
return null; 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<ChildAssociationRef> 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<DispositionActionDefinition> 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<QName, Serializable> props = new HashMap<QName, Serializable>(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<RecordsManagementEvent> 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'. * Creates the given records management event for the given 'next action'.
* *

View File

@@ -187,7 +187,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
if (nodeService.exists(actionedUponNodeRef) == true && getSetDispositionActionComplete() == true) if (nodeService.exists(actionedUponNodeRef) == true && getSetDispositionActionComplete() == true)
{ {
// Update the disposition schedule // Update the disposition schedule
updateNextDispositionAction(actionedUponNodeRef); dispositionService.updateNextDispositionAction(actionedUponNodeRef);
} }
} }
else else

View File

@@ -111,7 +111,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx
if (itemDs != null && if (itemDs != null &&
itemDs.getNodeRef().equals(ds.getNodeRef()) == true) 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 // disposition lifecycle already exists for node so process changes
processActionDefinitionChanges(dispositionActionDefinition, changedProps, disposableItem); processActionDefinitionChanges(dispositionActionDefinition, changedProps, disposableItem);
@@ -119,7 +119,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx
else else
{ {
// disposition lifecycle does not exist on the node so setup disposition // disposition lifecycle does not exist on the node so setup disposition
updateNextDispositionAction(disposableItem); dispositionService.updateNextDispositionAction(disposableItem);
} }
// update rolled up search information // update rolled up search information
@@ -141,7 +141,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx
props.put(PROP_RS_DISPOSITION_ACTION_NAME, da.getName()); props.put(PROP_RS_DISPOSITION_ACTION_NAME, da.getName());
props.put(PROP_RS_DISPOSITION_ACTION_AS_OF, da.getAsOfDate()); 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)); props.put(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE, nodeService.getProperty(da.getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE));
DispositionActionDefinition daDefinition = da.getDispositionActionDefinition(); DispositionActionDefinition daDefinition = da.getDispositionActionDefinition();
Period period = daDefinition.getPeriod(); Period period = daDefinition.getPeriod();
@@ -240,7 +240,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx
private void persistPeriodChanges(NodeRef dispositionActionDef, DispositionAction nextAction) private void persistPeriodChanges(NodeRef dispositionActionDef, DispositionAction nextAction)
{ {
Date newAsOfDate = null; Date newAsOfDate = null;
Period dispositionPeriod = (Period)nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_PERIOD); Period dispositionPeriod = (Period) nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_PERIOD);
if (dispositionPeriod != null) if (dispositionPeriod != null)
{ {
@@ -255,7 +255,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx
"' (" + nextAction.getNodeRef() + ") to: " + newAsOfDate); "' (" + nextAction.getNodeRef() + ") to: " + newAsOfDate);
} }
this.nodeService.setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_AS_OF, newAsOfDate); nodeService.setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_AS_OF, newAsOfDate);
} }
/** /**
@@ -269,7 +269,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx
private void persistEventChanges(NodeRef dispositionActionDef, DispositionAction nextAction) 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 // go through the current events on the next action and remove any that are not present any more
List<String> stepEvents = (List<String>)nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_EVENT); List<String> stepEvents = (List<String>) nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_EVENT);
List<EventCompletionDetails> eventsList = nextAction.getEventCompletionDetails(); List<EventCompletionDetails> eventsList = nextAction.getEventCompletionDetails();
List<String> nextActionEvents = new ArrayList<String>(eventsList.size()); List<String> nextActionEvents = new ArrayList<String>(eventsList.size());
for (EventCompletionDetails event : eventsList) for (EventCompletionDetails event : eventsList)

View File

@@ -18,28 +18,11 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.action.impl; 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.action.RMDispositionActionExecuterAbstractBase;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; import org.alfresco.module.org_alfresco_module_rm.transfer.TransferService;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.repo.action.executer.ActionExecuter; 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.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.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 * Transfer action
@@ -48,25 +31,11 @@ import org.springframework.extensions.surf.util.I18NUtil;
*/ */
public class TransferAction extends RMDispositionActionExecuterAbstractBase 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 */ /** Indicates whether the transfer is an accession or not */
private boolean isAccession = false; private boolean isAccession = false;
/** File plan service */ /** transfer service */
private FilePlanService filePlanService; private TransferService transferService;
/**
* @param filePlanService file plan service
*/
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
/** /**
* Indicates whether this transfer is an accession or not * Indicates whether this transfer is an accession or not
@@ -78,6 +47,14 @@ public class TransferAction extends RMDispositionActionExecuterAbstractBase
this.isAccession = isAccession; this.isAccession = isAccession;
} }
/**
* @param transferService transfer service
*/
public void setTransferService(TransferService transferService)
{
this.transferService = transferService;
}
/** /**
* Do not set the transfer action to auto-complete * 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 * 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) private void doTransfer(Action action, NodeRef dispositionLifeCycleNodeRef)
{ {
// Get the root rm node NodeRef transferNodeRef = transferService.transfer(dispositionLifeCycleNodeRef, isAccession);
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<QName, Serializable> transferProps = new HashMap<QName, Serializable>(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<ChildAssociationRef> 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);
// Set the return value of the action // Set the return value of the action
action.setParameterValue(ActionExecuter.PARAM_RESULT, transferNodeRef); action.setParameterValue(ActionExecuter.PARAM_RESULT, transferNodeRef);
} }
/**
*
* @param transferNodeRef
* @param dispositionLifeCycleNodeRef
*/
private void setPDFIndicationFlag(NodeRef transferNodeRef, NodeRef dispositionLifeCycleNodeRef)
{
if (recordFolderService.isRecordFolder(dispositionLifeCycleNodeRef) == true)
{
List<NodeRef> 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);
}
}
}
} }

View File

@@ -18,19 +18,12 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.action.impl; 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.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase; import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; import org.alfresco.module.org_alfresco_module_rm.transfer.TransferService;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.action.Action; 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.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.springframework.extensions.surf.util.I18NUtil; import org.springframework.extensions.surf.util.I18NUtil;
/** /**
@@ -43,6 +36,17 @@ public class TransferCompleteAction extends RMActionExecuterAbstractBase
/** I18N */ /** I18N */
private static final String MSG_NODE_NOT_TRANSFER = "rm.action.node-not-transfer"; 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, * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action,
* org.alfresco.service.cmr.repository.NodeRef) * org.alfresco.service.cmr.repository.NodeRef)
@@ -50,80 +54,21 @@ public class TransferCompleteAction extends RMActionExecuterAbstractBase
@Override @Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
{ {
QName className = this.nodeService.getType(actionedUponNodeRef); checkTransferSubClass(actionedUponNodeRef);
if (this.dictionaryService.isSubClass(className, TYPE_TRANSFER) == true) transferService.complete(actionedUponNodeRef);
{ }
boolean accessionIndicator = ((Boolean)nodeService.getProperty(actionedUponNodeRef, PROP_TRANSFER_ACCESSION_INDICATOR)).booleanValue();
String transferLocation = nodeService.getProperty(actionedUponNodeRef, PROP_TRANSFER_LOCATION).toString();
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(actionedUponNodeRef, ASSOC_TRANSFERRED, RegexQNamePattern.MATCH_ALL); /**
for (ChildAssociationRef assoc : assocs) * Checks if the actioned upon node reference is a sub class of transfer
{ *
markComplete(assoc.getChildRef(), accessionIndicator, transferLocation); * @param actionedUponNodeRef actioned upon node reference
} */
private void checkTransferSubClass(NodeRef actionedUponNodeRef)
// Delete the transfer object {
this.nodeService.deleteNode(actionedUponNodeRef); QName type = nodeService.getType(actionedUponNodeRef);
if (dictionaryService.isSubClass(type, TYPE_TRANSFER) == false)
NodeRef transferNodeRef = (NodeRef) AlfrescoTransactionSupport.getResource(TransferAction.KEY_TRANSFER_NODEREF);
if (transferNodeRef != null)
{
if (transferNodeRef.equals(actionedUponNodeRef))
{
AlfrescoTransactionSupport.bindResource(TransferAction.KEY_TRANSFER_NODEREF, null);
}
}
}
else
{ {
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NODE_NOT_TRANSFER)); 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<NodeRef> 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);
}
} }

View File

@@ -209,4 +209,11 @@ public interface DispositionService
* @since 2.0 * @since 2.0
*/ */
boolean isCutoff(NodeRef nodeRef); boolean isCutoff(NodeRef nodeRef);
/**
* Updates the next disposition action
*
* @param nodeRef node reference
*/
void updateNextDispositionAction(NodeRef nodeRef);
} }

View File

@@ -845,4 +845,128 @@ public class DispositionServiceImpl implements
ParameterCheck.mandatory("nodeRef", nodeRef); ParameterCheck.mandatory("nodeRef", nodeRef);
return nodeService.hasAspect(nodeRef, ASPECT_CUT_OFF); 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<ChildAssociationRef> 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<DispositionActionDefinition> 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<QName, Serializable> props = new HashMap<QName, Serializable>(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<RecordsManagementEvent> events = nextDispositionActionDefinition.getEvents();
for (RecordsManagementEvent event : events)
{
// For every event create an entry on the action
createEvent(event, dispositionActionNodeRef);
}
}
}
}
} }

View File

@@ -37,4 +37,24 @@ public interface TransferService
* @since 2.0 * @since 2.0
*/ */
boolean isTransfer(NodeRef nodeRef); 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);
} }

View File

@@ -18,9 +18,33 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.transfer; 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.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.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.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; 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 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) * @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); ParameterCheck.mandatory("nodeRef", nodeRef);
return instanceOf(nodeRef, TYPE_TRANSFER); 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<QName, Serializable> transferProps = new HashMap<QName, Serializable>(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<ChildAssociationRef> 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<NodeRef> 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<ChildAssociationRef> 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<NodeRef> 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);
}
} }