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 45bffc5d56..ab6a4032c1 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.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -27,12 +26,8 @@ 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.DispositionService; -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.RecordsManagementEventService; -import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventType; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; @@ -51,7 +46,6 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.PropertyCheck; import org.springframework.beans.factory.BeanNameAware; @@ -468,73 +462,4 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe { return null; } - - /** - * Creates the given records management event for the given 'next action'. - * - * @param event The event to create - * @param nextActionNodeRef The next action node - * @return The created event NodeRef - */ - protected NodeRef createEvent(RecordsManagementEvent event, NodeRef nextActionNodeRef) - { - NodeRef eventNodeRef = null; - - Map eventProps = new HashMap(7); - eventProps.put(PROP_EVENT_EXECUTION_NAME, event.getName()); - // TODO display label - RecordsManagementEventType eventType = recordsManagementEventService.getEventType(event.getType()); - eventProps.put(PROP_EVENT_EXECUTION_AUTOMATIC, eventType.isAutomaticEvent()); - eventProps.put(PROP_EVENT_EXECUTION_COMPLETE, false); - - // Create the event execution object - this.nodeService.createNode(nextActionNodeRef, ASSOC_EVENT_EXECUTIONS, - ASSOC_EVENT_EXECUTIONS, TYPE_EVENT_EXECUTION, eventProps); - - return eventNodeRef; - } - - /** - * Calculates and updates the rma:dispositionEventsEligible - * property for the given next disposition action. - * - * @param nextAction The next disposition action - * @return The result of calculation - */ - protected boolean updateEventEligible(DispositionAction nextAction) - { - List events = nextAction.getEventCompletionDetails(); - - boolean eligible = false; - if (!nextAction.getDispositionActionDefinition().eligibleOnFirstCompleteEvent()) - { - eligible = true; - for (EventCompletionDetails event : events) - { - if (!event.isEventComplete()) - { - eligible = false; - break; - } - } - } - else - { - for (EventCompletionDetails event : events) - { - if (event.isEventComplete()) - { - eligible = true; - break; - } - } - } - - // Update the property with the eligible value - this.nodeService.setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE, eligible); - - return eligible; - } - - } 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 f75fc3a497..8a6b87193b 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 @@ -192,7 +192,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx if (changedProps.contains(PROP_DISPOSITION_EVENT) || changedProps.contains(PROP_DISPOSITION_EVENT_COMBINATION)) { - persistEventChanges(dispositionActionDef, nextAction); + nextAction.refreshEvents(); } if (changedProps.contains(PROP_DISPOSITION_ACTION_NAME)) @@ -265,63 +265,88 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx * @param dispositionActionDef The disposition action definition node * @param nextAction The next disposition action */ - @SuppressWarnings("unchecked") - 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 eventsList = nextAction.getEventCompletionDetails(); - List nextActionEvents = new ArrayList(eventsList.size()); - for (EventCompletionDetails event : eventsList) - { - // 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())) - { - // 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() + - "' (" + nextAction.getNodeRef() + ")"); - } - } - } - - // go through the disposition action definition step events and add any new ones - if (stepEvents != null) - { - for (String eventName : stepEvents) - { - if (!nextActionEvents.contains(eventName)) - { - createEvent(recordsManagementEventService.getEvent(eventName), nextAction.getNodeRef()); - - if (logger.isDebugEnabled()) - { - 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() + - "' (" + nextAction.getNodeRef() + ")"); - } - } +// @SuppressWarnings("unchecked") +// 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 eventsList = nextAction.getEventCompletionDetails(); +// List nextActionEvents = new ArrayList(eventsList.size()); +// for (EventCompletionDetails event : eventsList) +// { +// // 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())) +// { +// // 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() + +// "' (" + nextAction.getNodeRef() + ")"); +// } +// } +// } +// +// // go through the disposition action definition step events and add any new ones +// if (stepEvents != null) +// { +// for (String eventName : stepEvents) +// { +// if (!nextActionEvents.contains(eventName)) +// { +// createEvent(recordsManagementEventService.getEvent(eventName), nextAction.getNodeRef()); +// +// if (logger.isDebugEnabled()) +// { +// 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() + +// "' (" + nextAction.getNodeRef() + ")"); +// } +// } + +// /** +// * Creates the given records management event for the given 'next action'. +// * +// * @param event The event to create +// * @param nextActionNodeRef The next action node +// * @return The created event NodeRef +// */ +// protected NodeRef createEvent(RecordsManagementEvent event, NodeRef nextActionNodeRef) +// { +// NodeRef eventNodeRef = null; +// +// Map eventProps = new HashMap(7); +// eventProps.put(PROP_EVENT_EXECUTION_NAME, event.getName()); +// // TODO display label +// RecordsManagementEventType eventType = recordsManagementEventService.getEventType(event.getType()); +// eventProps.put(PROP_EVENT_EXECUTION_AUTOMATIC, eventType.isAutomaticEvent()); +// eventProps.put(PROP_EVENT_EXECUTION_COMPLETE, false); +// +// // Create the event execution object +// this.nodeService.createNode(nextActionNodeRef, ASSOC_EVENT_EXECUTIONS, +// ASSOC_EVENT_EXECUTIONS, TYPE_EVENT_EXECUTION, eventProps); +// +// return eventNodeRef; +// } @Override protected void addParameterDefinitions(List paramList) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java index 5b8b86d043..ea8aa9667a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java @@ -18,30 +18,29 @@ */ package org.alfresco.module.org_alfresco_module_rm.action.impl; -import java.io.Serializable; import java.util.Date; import java.util.List; -import java.util.Map; 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.event.EventCompletionDetails; import org.alfresco.repo.action.ParameterDefinitionImpl; -import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.QName; /** * Complete event action * * @author Roy Wetherall + * @since 1.0 */ public class CompleteEventAction extends RMActionExecuterAbstractBase { + /** action name */ public static final String NAME = "completeEvent"; + + /** action parameter names */ public static final String PARAM_EVENT_NAME = "eventName"; public static final String PARAM_EVENT_COMPLETED_BY = "eventCompletedBy"; public static final String PARAM_EVENT_COMPLETED_AT = "eventCompletedAt"; @@ -52,8 +51,12 @@ public class CompleteEventAction extends RMActionExecuterAbstractBase @Override protected void addParameterDefinitions(List paramList) { - paramList.add(new ParameterDefinitionImpl(PARAM_EVENT_NAME, DataTypeDefinition.TEXT, true, - getParamDisplayLabel(PARAM_EVENT_NAME), false, "rm-ac-manual-events")); + paramList.add(new ParameterDefinitionImpl(PARAM_EVENT_NAME, + DataTypeDefinition.TEXT, + true, + getParamDisplayLabel(PARAM_EVENT_NAME), + false, + "rm-ac-manual-events")); } /** @@ -66,6 +69,7 @@ public class CompleteEventAction extends RMActionExecuterAbstractBase if (nodeService.exists(actionedUponNodeRef) && !freezeService.isFrozen(actionedUponNodeRef)) { + /** get parameter values */ String eventName = (String)action.getParameterValue(PARAM_EVENT_NAME); String eventCompletedBy = (String)action.getParameterValue(PARAM_EVENT_COMPLETED_BY); Date eventCompletedAt = (Date)action.getParameterValue(PARAM_EVENT_COMPLETED_AT); @@ -76,61 +80,10 @@ public class CompleteEventAction extends RMActionExecuterAbstractBase DispositionAction da = this.dispositionService.getNextDispositionAction(actionedUponNodeRef); if (da != null) { - // Get the disposition event - EventCompletionDetails event = getEvent(da, eventName); - if (event != null) - { - if (eventCompletedAt == null) - { - eventCompletedAt = new Date(); - } - - if (eventCompletedBy == null) - { - eventCompletedBy = AuthenticationUtil.getRunAsUser(); - } - - // Update the event so that it is complete - NodeRef eventNodeRef = event.getNodeRef(); - Map props = this.nodeService.getProperties(eventNodeRef); - props.put(PROP_EVENT_EXECUTION_COMPLETE, true); - props.put(PROP_EVENT_EXECUTION_COMPLETED_AT, eventCompletedAt); - props.put(PROP_EVENT_EXECUTION_COMPLETED_BY, eventCompletedBy); - this.nodeService.setProperties(eventNodeRef, props); - - // Check to see if the events eligible property needs to be updated - updateEventEligible(da); - - } - // else - // { - // RM-695: Commenting error handling out. If the current disposition stage does not define the event being completed nothing should happen. - // throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_EVENT_NO_DISP_LC, eventName)); - // } + // complete event + da.completeEvent(eventName, eventCompletedAt, eventCompletedBy); } } } } - - /** - * Get the event from the dispostion action - * - * @param da - * @param eventName - * @return - */ - private EventCompletionDetails getEvent(DispositionAction da, String eventName) - { - EventCompletionDetails result = null; - List events = da.getEventCompletionDetails(); - for (EventCompletionDetails event : events) - { - if (eventName.equals(event.getEventName())) - { - result = event; - break; - } - } - return result; - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java index 3466e623b7..2c1e95e819 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java @@ -18,30 +18,22 @@ */ package org.alfresco.module.org_alfresco_module_rm.action.impl; -import java.io.Serializable; import java.util.List; -import java.util.Map; -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.module.org_alfresco_module_rm.event.EventCompletionDetails; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.QName; -import org.springframework.extensions.surf.util.I18NUtil; /** * Undo event action * * @author Roy Wetherall + * @since 1.0 */ public class UndoEventAction extends RMActionExecuterAbstractBase { - /** I18N */ - private static final String MSG_EVENT_NOT_DONE = "rm.action.event-not-undone"; - /** Params */ public static final String PARAM_EVENT_NAME = "eventName"; @@ -59,91 +51,12 @@ public class UndoEventAction extends RMActionExecuterAbstractBase DispositionAction da = this.dispositionService.getNextDispositionAction(actionedUponNodeRef); if (da != null) { - // Get the disposition event - EventCompletionDetails event = getEvent(da, eventName); - if (event != null) - { - // Update the event so that it is undone - NodeRef eventNodeRef = event.getNodeRef(); - Map props = this.nodeService.getProperties(eventNodeRef); - props.put(PROP_EVENT_EXECUTION_COMPLETE, false); - props.put(PROP_EVENT_EXECUTION_COMPLETED_AT, null); - props.put(PROP_EVENT_EXECUTION_COMPLETED_BY, null); - this.nodeService.setProperties(eventNodeRef, props); - - // Check to see if the events eligible property needs to be updated - updateEventEigible(da); - - } - else - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_EVENT_NOT_DONE, eventName)); - } + // undo completed event + da.undoEvent(eventName); } } } - /** - * Get the event from the disposition action - * - * @param da - * @param eventName - * @return - */ - private EventCompletionDetails getEvent(DispositionAction da, String eventName) - { - EventCompletionDetails result = null; - List events = da.getEventCompletionDetails(); - for (EventCompletionDetails event : events) - { - if (eventName.equals(event.getEventName())) - { - result = event; - break; - } - } - return result; - } - - /** - * - * @param da - * @param nodeRef - */ - private void updateEventEigible(DispositionAction da) - { - List events = da.getEventCompletionDetails(); - - boolean eligible = false; - if (!da.getDispositionActionDefinition().eligibleOnFirstCompleteEvent()) - { - eligible = true; - for (EventCompletionDetails event : events) - { - if (!event.isEventComplete()) - { - eligible = false; - break; - } - } - } - else - { - for (EventCompletionDetails event : events) - { - if (event.isEventComplete()) - { - eligible = true; - break; - } - } - } - - // Update the property with the eligible value - this.nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE, eligible); - } - - /** * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List) */ @@ -152,6 +65,5 @@ public class UndoEventAction extends RMActionExecuterAbstractBase { // TODO add parameter definitions .... // eventName - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AuditEvent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AuditEvent.java index 08b65e580b..17f3815e25 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AuditEvent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AuditEvent.java @@ -30,6 +30,7 @@ import org.springframework.extensions.surf.util.I18NUtil; * * @author Gavin Cornwell * @author Roy Wetherall + * @since 1.0 */ public class AuditEvent implements RecordsManagementModel, Comparator { @@ -42,9 +43,6 @@ public class AuditEvent implements RecordsManagementModel, Comparator getEventCompletionDetails(); + + /** + * Get the event completion details for a named event. + * + * @param eventName event name + * @return {@link EventCompletionDetails} event completion details + * @since 2.2 + */ + EventCompletionDetails getEventCompletionDetails(String eventName); + + /** + * Add new completion details to the disposition action based on the provided + * event. + * + * @param event records management event + * @since 2.2 + */ + void addEventCompletionDetails(RecordsManagementEvent event); + + /** + * Complete an event. + *

+ * If null is provided, the complete at date will be take as 'now' and the completed by user + * as the fully authenticated user. + * + * @param eventName event name + * @param completedAt completed at 'date', now if null + * @param completedBy completed by user, authenticated user if null + * @since 2.2 + */ + void completeEvent(String eventName, Date completedAt, String completedBy); + + /** + * Undo the completion of an event. + * + * @param eventName event name + * @since 2.2 + */ + void undoEvent(String eventName); + + /** + * Refresh events against current disposition action definition. + *

+ * Called when disposition action definition has changed. + * + * @since 2.2 + */ + void refreshEvents(); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionActionImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionActionImpl.java index 58ea6f8fe8..06bae7fb1c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionActionImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionActionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2011 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -21,33 +21,51 @@ package org.alfresco.module.org_alfresco_module_rm.disposition; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction; 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.model.RecordsManagementModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; 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.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** + * Disposition action implementation. + * * @author Roy Wetherall + * @since 1.0 */ public class DispositionActionImpl implements DispositionAction, RecordsManagementModel { + /** logger */ + private static Log logger = LogFactory.getLog(DispositionActionImpl.class); + + /** records management service registry */ private RecordsManagementServiceRegistry services; + + /** disposition node reference */ private NodeRef dispositionNodeRef; + + /** disposition action definition */ private DispositionActionDefinition dispositionActionDefinition; /** * Constructor * - * @param services - * @param dispositionActionNodeRef + * @param services records management service registry + * @param dispositionActionNodeRef disposition action node reference */ public DispositionActionImpl(RecordsManagementServiceRegistry services, NodeRef dispositionActionNodeRef) { @@ -60,26 +78,26 @@ public class DispositionActionImpl implements DispositionAction, */ public DispositionActionDefinition getDispositionActionDefinition() { - if (this.dispositionActionDefinition == null) + if (dispositionActionDefinition == null) { // Get the current action String id = (String)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_ID); // Get the disposition instructions for the owning node - NodeRef recordNodeRef = this.services.getNodeService().getPrimaryParent(this.dispositionNodeRef).getParentRef(); + NodeRef recordNodeRef = services.getNodeService().getPrimaryParent(this.dispositionNodeRef).getParentRef(); if (recordNodeRef != null) { - DispositionSchedule ds = this.services.getDispositionService().getDispositionSchedule(recordNodeRef); + DispositionSchedule ds = services.getDispositionService().getDispositionSchedule(recordNodeRef); if (ds != null) { // Get the disposition action definition - this.dispositionActionDefinition = ds.getDispositionActionDefinition(id); + dispositionActionDefinition = ds.getDispositionActionDefinition(id); } } } - return this.dispositionActionDefinition; + return dispositionActionDefinition; } @@ -100,7 +118,7 @@ public class DispositionActionImpl implements DispositionAction, String label = name; // get the disposition action from the RM action service - RecordsManagementAction action = this.services.getRecordsManagementActionService().getDispositionAction(name); + RecordsManagementAction action = services.getRecordsManagementActionService().getDispositionAction(name); if (action != null) { label = action.getLabel(); @@ -114,7 +132,7 @@ public class DispositionActionImpl implements DispositionAction, */ public String getId() { - return (String)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_ID); + return (String)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_ID); } /** @@ -122,7 +140,7 @@ public class DispositionActionImpl implements DispositionAction, */ public String getName() { - return (String)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION); + return (String)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION); } /** @@ -130,7 +148,7 @@ public class DispositionActionImpl implements DispositionAction, */ public Date getAsOfDate() { - return (Date)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_AS_OF); + return (Date)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_AS_OF); } /** @@ -138,7 +156,7 @@ public class DispositionActionImpl implements DispositionAction, */ public boolean isEventsEligible() { - return ((Boolean)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_EVENTS_ELIGIBLE)).booleanValue(); + return ((Boolean)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_EVENTS_ELIGIBLE)).booleanValue(); } /** @@ -146,7 +164,7 @@ public class DispositionActionImpl implements DispositionAction, */ public Date getCompletedAt() { - return (Date)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_AT); + return (Date)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_AT); } /** @@ -154,23 +172,23 @@ public class DispositionActionImpl implements DispositionAction, */ public String getCompletedBy() { - return (String)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_BY); + return (String)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_BY); } - /* + /** * @see org.alfresco.module.org_alfresco_module_rm.DispositionAction#getStartedAt() */ public Date getStartedAt() { - return (Date)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_STARTED_AT); + return (Date)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_STARTED_AT); } - /* + /** * @see org.alfresco.module.org_alfresco_module_rm.DispositionAction#getStartedBy() */ public String getStartedBy() { - return (String)this.services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_STARTED_BY); + return (String)services.getNodeService().getProperty(this.dispositionNodeRef, PROP_DISPOSITION_ACTION_STARTED_BY); } /** @@ -178,27 +196,46 @@ public class DispositionActionImpl implements DispositionAction, */ public List getEventCompletionDetails() { - List assocs = this.services.getNodeService().getChildAssocs( + List assocs = services.getNodeService().getChildAssocs( this.dispositionNodeRef, ASSOC_EVENT_EXECUTIONS, RegexQNamePattern.MATCH_ALL); List result = new ArrayList(assocs.size()); for (ChildAssociationRef assoc : assocs) { - Map props = this.services.getNodeService().getProperties(assoc.getChildRef()); - String eventName = (String)props.get(PROP_EVENT_EXECUTION_NAME); - EventCompletionDetails ecd = new EventCompletionDetails( - assoc.getChildRef(), eventName, - this.services.getRecordsManagementEventService().getEvent(eventName).getDisplayLabel(), - getBooleanValue(props.get(PROP_EVENT_EXECUTION_AUTOMATIC), false), - getBooleanValue(props.get(PROP_EVENT_EXECUTION_COMPLETE), false), - (Date)props.get(PROP_EVENT_EXECUTION_COMPLETED_AT), - (String)props.get(PROP_EVENT_EXECUTION_COMPLETED_BY)); - result.add(ecd); + result.add(getEventCompletionDetailsFromNodeRef(assoc.getChildRef())); } return result; } + + /** + * Helper method to create object representation of event completed details from + * node reference. + * + * @param nodeRef node reference + * @return {@link EventCompletionDetails} event completion details + */ + private EventCompletionDetails getEventCompletionDetailsFromNodeRef(NodeRef nodeRef) + { + // get the properties + Map props = this.services.getNodeService().getProperties(nodeRef); + + // get the event name + String eventName = (String)props.get(PROP_EVENT_EXECUTION_NAME); + + // create event completion details + EventCompletionDetails ecd = new EventCompletionDetails( + nodeRef, + eventName, + services.getRecordsManagementEventService().getEvent(eventName).getDisplayLabel(), + getBooleanValue(props.get(PROP_EVENT_EXECUTION_AUTOMATIC), false), + getBooleanValue(props.get(PROP_EVENT_EXECUTION_COMPLETE), false), + (Date)props.get(PROP_EVENT_EXECUTION_COMPLETED_AT), + (String)props.get(PROP_EVENT_EXECUTION_COMPLETED_BY)); + + return ecd; + } /** * Helper method to deal with boolean values @@ -217,4 +254,254 @@ public class DispositionActionImpl implements DispositionAction, return result; } + /** + * Gets the event completion details for the named event. + *

+ * Returns null if event can not be found. + * + * @param eventName name of the event + * @return {@link EventCompletionDetails} event completion details for named event, null otherwise + * + * @since 2.2 + */ + @Override + public EventCompletionDetails getEventCompletionDetails(String eventName) + { + EventCompletionDetails result = null; + List assocs = services.getNodeService().getChildAssocsByPropertyValue(dispositionNodeRef, PROP_EVENT_EXECUTION_NAME, eventName); + + if (!assocs.isEmpty()) + { + if (assocs.size() != 1) + { + throw new AlfrescoRuntimeException("Unable to get event completion details, because more than one child was found for event " + eventName); + } + + result = getEventCompletionDetailsFromNodeRef(assocs.get(0).getChildRef()); + } + + return result; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction#completeEvent(java.lang.String, java.util.Date, java.lang.String) + */ + @Override + public void completeEvent(final String eventName, final Date completedAt, final String completedBy) + { + final EventCompletionDetails event = getEventCompletionDetails(eventName); + if (event != null && !event.isEventComplete()) + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + // use "now" if no completed date set + Date completedAtValue = completedAt; + if (completedAt == null) + { + completedAtValue = new Date(); + } + + // use the currently authenticated user if none set + String completedByValue = completedBy; + if (completedBy == null) + { + completedByValue = AuthenticationUtil.getFullyAuthenticatedUser(); + } + + // Update the event so that it is complete + NodeRef eventNodeRef = event.getNodeRef(); + Map props = services.getNodeService().getProperties(eventNodeRef); + props.put(PROP_EVENT_EXECUTION_COMPLETE, true); + props.put(PROP_EVENT_EXECUTION_COMPLETED_AT, completedAtValue); + props.put(PROP_EVENT_EXECUTION_COMPLETED_BY, completedByValue); + services.getNodeService().setProperties(eventNodeRef, props); + + // Check to see if the events eligible property needs to be updated + updateEventEligible(); + + return null; + } + }); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction#undoEvent(java.lang.String) + */ + @Override + public void undoEvent(final String eventName) + { + final EventCompletionDetails event = getEventCompletionDetails(eventName); + if (event != null && event.isEventComplete()) + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + // Update the event so that it is undone + NodeRef eventNodeRef = event.getNodeRef(); + Map props = services.getNodeService().getProperties(eventNodeRef); + props.put(PROP_EVENT_EXECUTION_COMPLETE, false); + props.put(PROP_EVENT_EXECUTION_COMPLETED_AT, null); + props.put(PROP_EVENT_EXECUTION_COMPLETED_BY, null); + services.getNodeService().setProperties(eventNodeRef, props); + + // Check to see if the events eligible property needs to be updated + updateEventEligible(); + + return null; + } + }); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction#refreshEvents() + */ + @SuppressWarnings("unchecked") + @Override + public void refreshEvents() + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + // go through the current events on the next action and remove any that are not present any more + List stepEvents = (List) services.getNodeService().getProperty(getDispositionActionDefinition().getNodeRef(), PROP_DISPOSITION_EVENT); + + List eventsList = getEventCompletionDetails(); + List nextActionEvents = new ArrayList(eventsList.size()); + + for (EventCompletionDetails event : eventsList) + { + // 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())) + { + // remove the child association representing the event + services.getNodeService().removeChild(getNodeRef(), event.getNodeRef()); + + if (logger.isDebugEnabled()) + { + logger.debug("Removed '" + eventName + "' from next action '" + getName() + + "' (" + getNodeRef() + ")"); + } + } + } + + // go through the disposition action definition step events and add any new ones + if (stepEvents != null) + { + for (String eventName : stepEvents) + { + if (!nextActionEvents.contains(eventName)) + { + // add the details of the new event + addEventCompletionDetails(services.getRecordsManagementEventService().getEvent(eventName)); + + if (logger.isDebugEnabled()) + { + logger.debug("Added '" + eventName + "' to next action '" + getName() + + "' (" + 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(); + + if (logger.isDebugEnabled()) + { + logger.debug("Set events eligible flag to '" + eligible + "' for next action '" + getName() + + "' (" + getNodeRef() + ")"); + } + + return null; + } + }); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction#addEventCompletionDetails(org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent) + */ + @Override + public void addEventCompletionDetails(RecordsManagementEvent event) + { + Map eventProps = new HashMap(7); + eventProps.put(PROP_EVENT_EXECUTION_NAME, event.getName()); + // TODO display label + eventProps.put(PROP_EVENT_EXECUTION_AUTOMATIC, event.getRecordsManagementEventType().isAutomaticEvent()); + eventProps.put(PROP_EVENT_EXECUTION_COMPLETE, false); + + // Create the event execution object + services.getNodeService().createNode(getNodeRef(), + ASSOC_EVENT_EXECUTIONS, + ASSOC_EVENT_EXECUTIONS, + TYPE_EVENT_EXECUTION, + eventProps); + } + + + /** + * Calculates and updates the rma:dispositionEventsEligible + * property for the given next disposition action. + * + * @param nextAction The next disposition action + * @return The result of calculation + * + * @since 2.2 + */ + private boolean updateEventEligible() + { + boolean eligible = false; + + // get the events for the next disposition action + List events = getEventCompletionDetails(); + + if (!events.isEmpty()) + { + if (!getDispositionActionDefinition().eligibleOnFirstCompleteEvent()) + { + // if one event is complete then the disposition action is eligible + eligible = true; + for (EventCompletionDetails event : events) + { + if (!event.isEventComplete()) + { + eligible = false; + break; + } + } + } + else + { + // all events must be complete for the disposition action to be eligible + for (EventCompletionDetails event : events) + { + if (event.isEventComplete()) + { + eligible = true; + break; + } + } + } + } + + // Update the property with the eligible value + services.getNodeService().setProperty(getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE, eligible); + + return eligible; + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionSelectionStrategy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionSelectionStrategy.java index c68eab0bf3..0ba9f66d62 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionSelectionStrategy.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionSelectionStrategy.java @@ -98,10 +98,7 @@ public class DispositionSelectionStrategy implements RecordsManagementModel else { SortedSet sortedFolders = new TreeSet(new DispositionableNodeRefComparator()); - for (NodeRef f : recordFolders) - { - sortedFolders.add(f); - } + sortedFolders.addAll(recordFolders); recordFolder = sortedFolders.first(); } @@ -137,16 +134,39 @@ public class DispositionSelectionStrategy implements RecordsManagementModel { public Integer doWork() throws Exception { - return Integer.valueOf(compareImpl(f1, f2)); + return compareImpl(f1, f2); } - }).intValue(); + }); } private int compareImpl(NodeRef f1, NodeRef f2) { - //TODO Check the nodeRefs have the correct aspect + // quick check to see if the node references are the same + if (f1.equals(f2)) + { + return 0; + } + + // get the disposition schedules for the folders + DispositionSchedule ds1 = dispositionService.getDispositionSchedule(f1); + DispositionSchedule ds2 = dispositionService.getDispositionSchedule(f2); + + // make sure each folder has a disposition schedule + if (ds1 == null && ds2 != null) + { + return 1; + } + else if (ds1 != null && ds2 == null) + { + return -1; + } + else if (ds1 == null && ds2 == null) + { + return 0; + } + // TODO this won't work correctly if we are trying to compare schedules that are record based!! DispositionAction da1 = dispositionService.getNextDispositionAction(f1); DispositionAction da2 = dispositionService.getNextDispositionAction(f2); 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 dfe9115115..e19872d443 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 @@ -31,7 +31,6 @@ import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry; import org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty; import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent; -import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventType; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; @@ -654,44 +653,18 @@ public class DispositionServiceImpl extends ServiceBaseImpl ASSOC_NEXT_DISPOSITION_ACTION, TYPE_DISPOSITION_ACTION, props).getChildRef(); + DispositionAction da = new DispositionActionImpl(serviceRegistry, dispositionActionNodeRef); // Create the events List events = dispositionActionDefinition.getEvents(); for (RecordsManagementEvent event : events) { // For every event create an entry on the action - createEvent(event, dispositionActionNodeRef); + da.addEventCompletionDetails(event); + // createEvent(event, dispositionActionNodeRef); } } - /** - * Creates the given records management event for the given 'next action'. - * - * @param event The event to create - * @param nextActionNodeRef The next action node - * @return The created event NodeRef - */ - private NodeRef createEvent(RecordsManagementEvent event, NodeRef nextActionNodeRef) - { - NodeRef eventNodeRef = null; - - Map eventProps = new HashMap(7); - eventProps.put(PROP_EVENT_EXECUTION_NAME, event.getName()); - // TODO display label - RecordsManagementEventType eventType = serviceRegistry.getRecordsManagementEventService().getEventType(event.getType()); - eventProps.put(PROP_EVENT_EXECUTION_AUTOMATIC, eventType.isAutomaticEvent()); - eventProps.put(PROP_EVENT_EXECUTION_COMPLETE, false); - - // Create the event execution object - this.nodeService.createNode(nextActionNodeRef, - ASSOC_EVENT_EXECUTIONS, - ASSOC_EVENT_EXECUTIONS, - TYPE_EVENT_EXECUTION, - eventProps); - - return eventNodeRef; - } - /** * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isNextDispositionActionEligible(org.alfresco.service.cmr.repository.NodeRef) */ @@ -953,13 +926,14 @@ public class DispositionServiceImpl extends ServiceBaseImpl ASSOC_NEXT_DISPOSITION_ACTION, TYPE_DISPOSITION_ACTION, props).getChildRef(); + DispositionAction da = new DispositionActionImpl(serviceRegistry, dispositionActionNodeRef); // Create the events List events = nextDispositionActionDefinition.getEvents(); for (RecordsManagementEvent event : events) { // For every event create an entry on the action - createEvent(event, dispositionActionNodeRef); + da.addEventCompletionDetails(event); } } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/EventCompletionDetails.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/EventCompletionDetails.java index 6641fb1c31..ac3ae125f7 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/EventCompletionDetails.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/EventCompletionDetails.java @@ -29,7 +29,10 @@ import org.alfresco.service.cmr.repository.NodeRef; */ public class EventCompletionDetails { + /** node reference */ private NodeRef nodeRef; + + /** event name */ private String eventName; private String eventLabel; private boolean eventExecutionAutomatic; @@ -39,13 +42,15 @@ public class EventCompletionDetails /** - * @param nodeRef - * @param eventName - * @param eventLabel - * @param eventExecutionAutomatic - * @param eventComplete - * @param eventCompletedAt - * @param eventCompletedBy + * Constructor + * + * @param nodeRef node reference + * @param eventName event name + * @param eventLabel event label + * @param eventExecutionAutomatic indicates whether the event is executed automatically or not + * @param eventComplete indicates whether the event is complete or not + * @param eventCompletedAt when the event was completed + * @param eventCompletedBy who completed the event */ public EventCompletionDetails( NodeRef nodeRef, String eventName, diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEvent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEvent.java index da6e95e3a8..e93ce2b2b9 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEvent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEvent.java @@ -18,15 +18,18 @@ */ package org.alfresco.module.org_alfresco_module_rm.event; +import org.alfresco.util.ParameterCheck; + /** * Records management event * * @author Roy Wetherall + * @since 1.0 */ public class RecordsManagementEvent { /** Records management event type */ - private String type; + private RecordsManagementEventType type; /** Records management event name */ private String name; @@ -41,21 +44,37 @@ public class RecordsManagementEvent * @param name event name * @param displayLabel event display label */ - public RecordsManagementEvent(String type, String name, String displayLabel) + public RecordsManagementEvent(RecordsManagementEventType type, String name, String displayLabel) { + ParameterCheck.mandatory("type", type); + ParameterCheck.mandatory("name", name); + ParameterCheck.mandatory("displayLabel", displayLabel); + this.type = type; this.name = name; this.displayLabel = displayLabel; } /** - * Get records management type + * Get records management type name * - * @return String records management type + * @return String records management event type name */ public String getType() { - return this.type; + return type.getName(); + } + + /** + * Get the records management event type. + * + * @return {@link RecordsManagementEventType} records management event type + * + * @since 2.2 + */ + public RecordsManagementEventType getRecordsManagementEventType() + { + return type; } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEventServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEventServiceImpl.java index fc8ead986e..efc47bb9f6 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEventServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/RecordsManagementEventServiceImpl.java @@ -229,13 +229,13 @@ public class RecordsManagementEventServiceImpl implements RecordsManagementEvent } // Create event and add to map - RecordsManagementEvent event = new RecordsManagementEvent(eventType, eventName, eventDisplayLabel); + RecordsManagementEvent event = new RecordsManagementEvent(eventTypes.get(eventType), eventName, eventDisplayLabel); getEventMap().put(event.getName(), event); // Persist the changes to the event list saveEvents(); - return new RecordsManagementEvent(eventType, eventName, eventDisplayLabel); + return new RecordsManagementEvent(eventTypes.get(eventType), eventName, eventDisplayLabel); } /** @@ -318,7 +318,7 @@ public class RecordsManagementEventServiceImpl implements RecordsManagementEvent } // Create event and add to map - RecordsManagementEvent event = new RecordsManagementEvent(eventType, eventName, eventDisplayLabel); + RecordsManagementEvent event = new RecordsManagementEvent(eventTypes.get(eventType), eventName, eventDisplayLabel); events.put(event.getName(), event); } return null; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java index e231ad10da..07eb687e19 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java @@ -18,6 +18,7 @@ */ package org.alfresco.module.org_alfresco_module_rm.test; +import org.alfresco.module.org_alfresco_module_rm.test.integration.IntegrationTestSuite; import org.alfresco.repo.ParameterProcessorTestSuite; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -37,9 +38,8 @@ import org.junit.runners.Suite.SuiteClasses; CapabilitiesTestSuite.class, ServicesTestSuite.class, WebScriptTestSuite.class, - IssueTestSuite.class, ParameterProcessorTestSuite.class, - DoD5015TestSuite.class + IntegrationTestSuite.class }) public class AllTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/capabilities/DeclarativeCapabilityTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/capabilities/DeclarativeCapabilityTest.java index 9826116fc4..f8dc248a06 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/capabilities/DeclarativeCapabilityTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/capabilities/DeclarativeCapabilityTest.java @@ -38,6 +38,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; +import org.springframework.extensions.webscripts.GUID; /** * Declarative capability unit test @@ -59,6 +60,8 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase private NodeRef moveToFolder; private NodeRef moveToCategory; + + private NodeRef hold; @Override protected boolean isUserTest() @@ -106,9 +109,12 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase utils.declareRecord(declaredRecord); utils.declareRecord(frozenRecord); utils.declareRecord(frozenRecord2); - utils.freeze(frozenRecord); - utils.freeze(frozenRecordFolder); - utils.freeze(frozenRecord2); + + hold = holdService.createHold(filePlan, GUID.generate(), "reason", "description"); + + holdService.addToHold(hold, frozenRecord); + holdService.addToHold(hold, frozenRecordFolder); + holdService.addToHold(hold, frozenRecord2); return null; } @@ -119,9 +125,9 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase protected void tearDownImpl() { // Unfreeze stuff so it can be deleted - utils.unfreeze(frozenRecord); - utils.unfreeze(frozenRecordFolder); - utils.unfreeze(frozenRecord2); + holdService.removeFromHold(hold, frozenRecord); + holdService.removeFromHold(hold, frozenRecordFolder); + holdService.removeFromHold(hold, frozenRecord2); super.tearDownImpl(); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java new file mode 100755 index 0000000000..20d246662a --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.test.integration; + +import org.alfresco.module.org_alfresco_module_rm.test.integration.dod.DoD5015TestSuite; +import org.alfresco.module.org_alfresco_module_rm.test.integration.event.EventTestSuite; +import org.alfresco.module.org_alfresco_module_rm.test.integration.issue.IssueTestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + + +/** + * RM Integration Test Suite + * + * @author Roy Wetherall + * @since 2.2 + */ +@RunWith(Suite.class) +@SuiteClasses( +{ + DoD5015TestSuite.class, + IssueTestSuite.class, + EventTestSuite.class +}) +public class IntegrationTestSuite +{ +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/DoD5015TestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/DoD5015TestSuite.java similarity index 80% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/DoD5015TestSuite.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/DoD5015TestSuite.java index 238ee8c7dd..aa049ab276 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/DoD5015TestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/DoD5015TestSuite.java @@ -16,10 +16,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test; +package org.alfresco.module.org_alfresco_module_rm.test.integration.dod; -import org.alfresco.module.org_alfresco_module_rm.test.dod.RM1147DODRMSiteTest; -import org.alfresco.module.org_alfresco_module_rm.test.dod.RM1194ExcludeDoDRecordTypesTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/dod/RM1147DODRMSiteTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/RM1147DODRMSiteTest.java similarity index 96% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/dod/RM1147DODRMSiteTest.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/RM1147DODRMSiteTest.java index a0fb05c689..7293b767cc 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/dod/RM1147DODRMSiteTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/RM1147DODRMSiteTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.dod; +package org.alfresco.module.org_alfresco_module_rm.test.integration.dod; import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/dod/RM1194ExcludeDoDRecordTypesTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/RM1194ExcludeDoDRecordTypesTest.java similarity index 95% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/dod/RM1194ExcludeDoDRecordTypesTest.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/RM1194ExcludeDoDRecordTypesTest.java index c00e3edc62..1c7ffcbdd1 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/dod/RM1194ExcludeDoDRecordTypesTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/dod/RM1194ExcludeDoDRecordTypesTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.dod; +package org.alfresco.module.org_alfresco_module_rm.test.integration.dod; import java.util.Set; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/event/CompleteEventsTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/event/CompleteEventsTest.java new file mode 100755 index 0000000000..80620326f7 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/event/CompleteEventsTest.java @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.test.integration.event; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.impl.CompleteEventAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; +import org.alfresco.module.org_alfresco_module_rm.event.EventCompletionDetails; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.GUID; + +/** + * Complete events integration tests. + *

+ * Relates to: + * - https://issues.alfresco.com/jira/browse/RM-1341 + * + * @author Roy Wetherall + * @since 2.2 + */ +public class CompleteEventsTest extends BaseRMTestCase +{ + private static final String ANOTHER_EVENT = "abolished"; + + /** + * test completion of a single event on a record level disposition schedule + */ + public void testCompleteSingleEventRecordLevel() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef record; + + public void given() + { + // create record category + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + + // create disposition schedule + utils.createBasicDispositionSchedule(recordCategory, "instructions", "authority", true, true); + + // create record folder + NodeRef recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + + // file record + record = utils.createRecord(recordFolder, GUID.generate(), "title"); + utils.declareRecord(record); + } + + public void when() + { + // build action properties + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + + // complete event + rmActionService.executeRecordsManagementAction(record, CompleteEventAction.NAME, params); + + } + + public void then() + { + // check that the record is now eligible for the next disposition action + assertTrue(dispositionService.isNextDispositionActionEligible(record)); + + // check the next disposition action + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(record); + assertNotNull(dispositionAction); + assertEquals("cutoff", dispositionAction.getName()); + + EventCompletionDetails eventDetails = dispositionAction.getEventCompletionDetails(CommonRMTestUtils.DEFAULT_EVENT_NAME); + assertNotNull(eventDetails); + assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, eventDetails.getEventName()); + assertTrue(eventDetails.isEventComplete()); + assertNotNull(eventDetails.getEventCompletedAt()); + assertNotNull(eventDetails.getEventCompletedBy()); + } + }); + } + + /** + * test completion of a single event at the record level + */ + public void testCompleteSimpleSingleEventRecordFolderLevel() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef recordFolder; + + public void given() + { + // create record category + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + + // create disposition schedule + utils.createBasicDispositionSchedule(recordCategory, "instructions", "authority", false, true); + + // create record folder + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + + // file record + NodeRef record = utils.createRecord(recordFolder, GUID.generate(), "title"); + utils.declareRecord(record); + + } + + public void when() + { + // build action properties + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + + // complete event + rmActionService.executeRecordsManagementAction(recordFolder, CompleteEventAction.NAME, params); + } + + public void then() + { + // check that the record is now eligible for the next disposition action + assertTrue(dispositionService.isNextDispositionActionEligible(recordFolder)); + + // check the next disposition action + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(recordFolder); + assertNotNull(dispositionAction); + assertEquals("cutoff", dispositionAction.getName()); + + EventCompletionDetails eventDetails = dispositionAction.getEventCompletionDetails(CommonRMTestUtils.DEFAULT_EVENT_NAME); + assertNotNull(eventDetails); + assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, eventDetails.getEventName()); + assertTrue(eventDetails.isEventComplete()); + assertNotNull(eventDetails.getEventCompletedAt()); + assertNotNull(eventDetails.getEventCompletedBy()); + } + }); + } + + /** + * test complete event given at least one event is needed for the disposition action to be eligible + */ + public void testAtLeastOneEventToBeEligible() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + NodeRef recordFolder = null; + + public void given() + { + // create record category + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + + // create disposition schedule + DispositionSchedule mySchedule = utils.createBasicDispositionSchedule(recordCategory, "instructions", "authority", false, false); + + Map adParams = new HashMap(3); + adParams.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); + adParams.put(PROP_DISPOSITION_DESCRIPTION, CommonRMTestUtils.DEFAULT_DISPOSITION_DESCRIPTION); + + List events = new ArrayList(1); + events.add(CommonRMTestUtils.DEFAULT_EVENT_NAME); + events.add(ANOTHER_EVENT); + adParams.put(PROP_DISPOSITION_EVENT, (Serializable)events); + dispositionService.addDispositionActionDefinition(mySchedule, adParams); + + // create record folder + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + + // file record + NodeRef record = utils.createRecord(recordFolder, GUID.generate(), "title"); + utils.declareRecord(record); + + } + public void when() + { + // build action properties + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + + // complete event + rmActionService.executeRecordsManagementAction(recordFolder, CompleteEventAction.NAME, params); + } + + public void then() + { + // check that the record is now eligible for the next disposition action + assertTrue(dispositionService.isNextDispositionActionEligible(recordFolder)); + + // check the next disposition action + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(recordFolder); + assertNotNull(dispositionAction); + assertEquals("cutoff", dispositionAction.getName()); + + EventCompletionDetails eventDetails = dispositionAction.getEventCompletionDetails(CommonRMTestUtils.DEFAULT_EVENT_NAME); + assertNotNull(eventDetails); + assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, eventDetails.getEventName()); + assertTrue(eventDetails.isEventComplete()); + assertNotNull(eventDetails.getEventCompletedAt()); + assertNotNull(eventDetails.getEventCompletedBy()); + + eventDetails = dispositionAction.getEventCompletionDetails(ANOTHER_EVENT); + assertNotNull(eventDetails); + assertEquals(ANOTHER_EVENT, eventDetails.getEventName()); + assertFalse(eventDetails.isEventComplete()); + assertNull(eventDetails.getEventCompletedAt()); + assertNull(eventDetails.getEventCompletedBy()); + } + }); + } + + /** + * test that disposition action is not eligible given all events need to be completed and only has been + */ + public void testOnlyOneOfAllEventsSoNotEligible() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + NodeRef recordFolder = null; + + public void given() + { + // create record category + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + + // create disposition schedule + DispositionSchedule mySchedule = utils.createBasicDispositionSchedule(recordCategory, "instructions", "authority", false, false); + + Map adParams = new HashMap(3); + adParams.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); + adParams.put(PROP_DISPOSITION_DESCRIPTION, CommonRMTestUtils.DEFAULT_DISPOSITION_DESCRIPTION); + adParams.put(PROP_DISPOSITION_EVENT_COMBINATION, "and"); + + List events = new ArrayList(1); + events.add(CommonRMTestUtils.DEFAULT_EVENT_NAME); + events.add(ANOTHER_EVENT); + adParams.put(PROP_DISPOSITION_EVENT, (Serializable)events); + dispositionService.addDispositionActionDefinition(mySchedule, adParams); + + // create record folder + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + + // file record + NodeRef record = utils.createRecord(recordFolder, GUID.generate(), "title"); + utils.declareRecord(record); + } + + public void when() + { + // build action properties + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + + // complete event + rmActionService.executeRecordsManagementAction(recordFolder, CompleteEventAction.NAME, params); + } + + public void then() + { + assertFalse(dispositionService.isNextDispositionActionEligible(recordFolder)); + + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(recordFolder); + assertNotNull(dispositionAction); + assertEquals("cutoff", dispositionAction.getName()); + + EventCompletionDetails eventDetails = dispositionAction.getEventCompletionDetails(CommonRMTestUtils.DEFAULT_EVENT_NAME); + assertNotNull(eventDetails); + assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, eventDetails.getEventName()); + assertTrue(eventDetails.isEventComplete()); + assertNotNull(eventDetails.getEventCompletedAt()); + assertNotNull(eventDetails.getEventCompletedBy()); + + eventDetails = dispositionAction.getEventCompletionDetails(ANOTHER_EVENT); + assertNotNull(eventDetails); + assertEquals(ANOTHER_EVENT, eventDetails.getEventName()); + assertFalse(eventDetails.isEventComplete()); + assertNull(eventDetails.getEventCompletedAt()); + assertNull(eventDetails.getEventCompletedBy()); + } + }); + } + + /** + * test event complete makes disposition eligible given that all events are complete and required + */ + public void testAllEventsSoEligible() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + NodeRef recordFolder = null; + + public void given() + { + // create record category + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + + // create disposition schedule + DispositionSchedule mySchedule = utils.createBasicDispositionSchedule(recordCategory, "instructions", "authority", false, false); + + Map adParams = new HashMap(3); + adParams.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); + adParams.put(PROP_DISPOSITION_DESCRIPTION, CommonRMTestUtils.DEFAULT_DISPOSITION_DESCRIPTION); + adParams.put(PROP_DISPOSITION_EVENT_COMBINATION, "and"); + + List events = new ArrayList(1); + events.add(CommonRMTestUtils.DEFAULT_EVENT_NAME); + events.add(ANOTHER_EVENT); + adParams.put(PROP_DISPOSITION_EVENT, (Serializable)events); + dispositionService.addDispositionActionDefinition(mySchedule, adParams); + + // create record folder + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + + // file record + NodeRef record = utils.createRecord(recordFolder, GUID.generate(), "title"); + utils.declareRecord(record); + } + + public void when() + { + // build action properties + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + + // complete event + rmActionService.executeRecordsManagementAction(recordFolder, CompleteEventAction.NAME, params); + + // build action properties + params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, ANOTHER_EVENT); + + // complete event + rmActionService.executeRecordsManagementAction(recordFolder, CompleteEventAction.NAME, params); + } + + public void then() + { + assertTrue(dispositionService.isNextDispositionActionEligible(recordFolder)); + + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(recordFolder); + assertNotNull(dispositionAction); + assertEquals("cutoff", dispositionAction.getName()); + + EventCompletionDetails eventDetails = dispositionAction.getEventCompletionDetails(CommonRMTestUtils.DEFAULT_EVENT_NAME); + assertNotNull(eventDetails); + assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, eventDetails.getEventName()); + assertTrue(eventDetails.isEventComplete()); + assertNotNull(eventDetails.getEventCompletedAt()); + assertNotNull(eventDetails.getEventCompletedBy()); + + eventDetails = dispositionAction.getEventCompletionDetails(ANOTHER_EVENT); + assertNotNull(eventDetails); + assertEquals(ANOTHER_EVENT, eventDetails.getEventName()); + assertTrue(eventDetails.isEventComplete()); + assertNotNull(eventDetails.getEventCompletedAt()); + assertNotNull(eventDetails.getEventCompletedBy()); + + } + }); + } + + /** + * test complete event works for multi-filed record + */ + public void testCompleteEventWhenCutoffMultiFiled_RM1341() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef record; + + public void given() + { + // create record category + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + NodeRef recordCategory2 = filePlanService.createRecordCategory(filePlan, GUID.generate()); + + // create disposition schedule + utils.createBasicDispositionSchedule(recordCategory, "instructions", "authority", true, true); + + // create record folder + NodeRef recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + NodeRef recordFolder2 = recordFolderService.createRecordFolder(recordCategory2, GUID.generate()); + + // file record + String recordName = GUID.generate(); + record = utils.createRecord(recordFolder, recordName, "title"); + utils.declareRecord(record); + + // link record to second record folder + nodeService.addChild(recordFolder2, record, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, recordName)); + } + + public void when() + { + // build action properties + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + + // complete event + rmActionService.executeRecordsManagementAction(record, CompleteEventAction.NAME, params); + } + + public void then() + { + // check that the record is now eligible for the next disposition action + assertTrue(dispositionService.isNextDispositionActionEligible(record)); + + // check the next disposition action + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(record); + assertNotNull(dispositionAction); + assertEquals("cutoff", dispositionAction.getName()); + + EventCompletionDetails eventDetails = dispositionAction.getEventCompletionDetails(CommonRMTestUtils.DEFAULT_EVENT_NAME); + assertNotNull(eventDetails); + assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, eventDetails.getEventName()); + assertTrue(eventDetails.isEventComplete()); + assertNotNull(eventDetails.getEventCompletedAt()); + assertNotNull(eventDetails.getEventCompletedBy()); + } + }); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/event/EventTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/event/EventTestSuite.java new file mode 100755 index 0000000000..f379874344 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/event/EventTestSuite.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.test.integration.event; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Event integration test suite + * + * @author Roy Wetherall + * @since 2.2 + */ +@RunWith(Suite.class) +@SuiteClasses( +{ + CompleteEventsTest.class +}) +public class EventTestSuite +{ +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/IssueTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java old mode 100644 new mode 100755 similarity index 65% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/IssueTestSuite.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java index 8da2f5b7e5..8c2a99e986 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/IssueTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java @@ -16,15 +16,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; -import org.alfresco.module.org_alfresco_module_rm.test.issue.RM1008Test; -import org.alfresco.module.org_alfresco_module_rm.test.issue.RM1027Test; -import org.alfresco.module.org_alfresco_module_rm.test.issue.RM1030Test; -import org.alfresco.module.org_alfresco_module_rm.test.issue.RM1039Test; -import org.alfresco.module.org_alfresco_module_rm.test.issue.RM452Test; -import org.alfresco.module.org_alfresco_module_rm.test.issue.RM804Test; -import org.alfresco.module.org_alfresco_module_rm.test.issue.RM994Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1008Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java old mode 100644 new mode 100755 similarity index 96% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1008Test.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java index c31693246c..0b2456386c --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1008Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import java.io.Serializable; import java.util.HashMap; @@ -38,7 +38,7 @@ import org.alfresco.util.GUID; /** - * System test for RM-1008 + * Test for RM-1008 * * @author Roy Wetherall * @since 2.1 diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1027Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1027Test.java similarity index 95% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1027Test.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1027Test.java index 5d02b0fdb9..3c170bce9b 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1027Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1027Test.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.service.cmr.model.FileInfo; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1030Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1030Test.java old mode 100644 new mode 100755 similarity index 95% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1030Test.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1030Test.java index b08cd2ec8c..84c3446d74 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1030Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1030Test.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import java.util.List; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1039Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java similarity index 96% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1039Test.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java index 54ded82371..3df4a051a4 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM1039Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import java.io.Serializable; import java.util.HashMap; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM452Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM452Test.java similarity index 94% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM452Test.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM452Test.java index 380022d301..64c136da85 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM452Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM452Test.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM804Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java similarity index 95% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM804Test.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java index 7105d692ce..5fdd3afed0 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM804Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM981SystemTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM981SystemTest.java similarity index 95% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM981SystemTest.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM981SystemTest.java index e0faf86bf5..21c8a8bd82 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM981SystemTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM981SystemTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM994Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM994Test.java similarity index 95% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM994Test.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM994Test.java index 5dd658e9af..54a44b7f45 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/issue/RM994Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM994Test.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.module.org_alfresco_module_rm.test.issue; +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordDefinition; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index 3ef66c4ba1..f63ae08cb1 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -808,7 +808,51 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase { // empty implementation } - - + } + + protected void doBehaviourDrivenTest(BehaviourDrivenTest test) + { + test.run(); + } + + protected abstract class BehaviourDrivenTest + { + public abstract void given(); + + public abstract void when(); + + public abstract void then(); + + public void run() + { + doTestInTransaction(new VoidTest() + { + @Override + public void runImpl() throws Exception + { + given(); + } + }); + + doTestInTransaction(new VoidTest() + { + + @Override + public void runImpl() throws Exception + { + when(); + } + }); + + doTestInTransaction(new VoidTest() + { + + @Override + public void runImpl() throws Exception + { + then(); + } + }); + } } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMWebScriptTestCase.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMWebScriptTestCase.java index 7a496c223a..fdfa9ca05c 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMWebScriptTestCase.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMWebScriptTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2012 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java index e8c24fc941..9a81c06650 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java @@ -1,5 +1,20 @@ -/** +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . */ package org.alfresco.module.org_alfresco_module_rm.test.util; @@ -17,13 +32,11 @@ import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService; import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction; -import org.alfresco.module.org_alfresco_module_rm.action.impl.FreezeAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction; import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService; 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.dod5015.DOD5015Model; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityService; import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; @@ -41,6 +54,8 @@ import org.apache.commons.lang.StringUtils; import org.springframework.context.ApplicationContext; /** + * Common RM test utility methods. + * * @author Roy Wetherall */ public class CommonRMTestUtils implements RecordsManagementModel @@ -73,9 +88,10 @@ public class CommonRMTestUtils implements RecordsManagementModel } /** - * - * @param container - * @return + * Create a disposition schedule + * + * @param container record category + * @return {@link DispositionSchedule} created disposition schedule node reference */ public DispositionSchedule createBasicDispositionSchedule(NodeRef container) { @@ -207,15 +223,8 @@ public class CommonRMTestUtils implements RecordsManagementModel modelSecurityService.setEnabled(false); try { - // Declare record - nodeService.setProperty(record, DOD5015Model.PROP_PUBLICATION_DATE, new Date()); - nodeService.setProperty(record, DOD5015Model.PROP_MEDIA_TYPE, "mediaTypeValue"); - nodeService.setProperty(record, DOD5015Model.PROP_FORMAT, "formatValue"); - nodeService.setProperty(record, DOD5015Model.PROP_DATE_RECEIVED, new Date()); - nodeService.setProperty(record, RecordsManagementModel.PROP_DATE_FILED, new Date()); - nodeService.setProperty(record, DOD5015Model.PROP_ORIGINATOR, "origValue"); - nodeService.setProperty(record, DOD5015Model.PROP_ORIGINATING_ORGANIZATION, "origOrgValue"); - nodeService.setProperty(record, ContentModel.PROP_TITLE, "titleValue"); + nodeService.setProperty(record, RecordsManagementModel.PROP_DATE_FILED, new Date()); + nodeService.setProperty(record, ContentModel.PROP_TITLE, "titleValue"); actionService.executeRecordsManagementAction(record, "declareRecord"); } finally @@ -251,37 +260,6 @@ public class CommonRMTestUtils implements RecordsManagementModel }, AuthenticationUtil.getAdminUserName()); } - public void freeze(final NodeRef nodeRef) - { - AuthenticationUtil.runAs(new RunAsWork() - { - @Override - public Void doWork() throws Exception - { - Map params = new HashMap(1); - params.put(FreezeAction.PARAM_REASON, "Freeze reason."); - actionService.executeRecordsManagementAction(nodeRef, "freeze", params); - - return null; - } - - }, AuthenticationUtil.getSystemUserName()); - } - - public void unfreeze(final NodeRef nodeRef) - { - AuthenticationUtil.runAs(new RunAsWork() - { - @Override - public Void doWork() throws Exception - { - actionService.executeRecordsManagementAction(nodeRef, "unfreeze"); - return null; - } - - }, AuthenticationUtil.getSystemUserName()); - } - public Role createRole(NodeRef filePlan, String roleName, String ... capabilityNames) { Set capabilities = new HashSet(capabilityNames.length);