Fixes the following bugs:

- RM-249 (Disposition steps sequence can be violated)
- RM-790 (Cannot delete disposition schedule step)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@54223 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2013-08-19 08:37:48 +00:00
parent e392d679b1
commit 0e67b7fc58
4 changed files with 110 additions and 85 deletions

View File

@@ -1 +1 @@
{} <#include "dispositionschedule.get.json.ftl">

View File

@@ -28,20 +28,21 @@ import javax.servlet.http.HttpServletResponse;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition; 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.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent; import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptRequest;
/** /**
* Abstract base class for all disposition related java backed webscripts. * Abstract base class for all disposition related java backed webscripts.
* *
* @author Gavin Cornwell * @author Gavin Cornwell
*/ */
public class DispositionAbstractBase extends AbstractRmWebScript public class DispositionAbstractBase extends AbstractRmWebScript
{ {
/** /**
* Parses the request and providing it's valid returns the DispositionSchedule object. * Parses the request and providing it's valid returns the DispositionSchedule object.
* *
* @param req The webscript request * @param req The webscript request
* @return The DispositionSchedule object the request is aimed at * @return The DispositionSchedule object the request is aimed at
*/ */
@@ -49,7 +50,7 @@ public class DispositionAbstractBase extends AbstractRmWebScript
{ {
// get the NodeRef from the request // get the NodeRef from the request
NodeRef nodeRef = parseRequestForNodeRef(req); NodeRef nodeRef = parseRequestForNodeRef(req);
// Determine whether we are getting the inherited disposition schedule or not // Determine whether we are getting the inherited disposition schedule or not
boolean inherited = true; boolean inherited = true;
String inheritedString = req.getParameter("inherited"); String inheritedString = req.getParameter("inherited");
@@ -57,7 +58,7 @@ public class DispositionAbstractBase extends AbstractRmWebScript
{ {
inherited = Boolean.parseBoolean(inheritedString); inherited = Boolean.parseBoolean(inheritedString);
} }
// make sure the node passed in has a disposition schedule attached // make sure the node passed in has a disposition schedule attached
DispositionSchedule schedule = null; DispositionSchedule schedule = null;
if (inherited == true) if (inherited == true)
@@ -70,16 +71,16 @@ public class DispositionAbstractBase extends AbstractRmWebScript
} }
if (schedule == null) if (schedule == null)
{ {
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Node " + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Node " +
nodeRef.toString() + " does not have a disposition schedule"); nodeRef.toString() + " does not have a disposition schedule");
} }
return schedule; return schedule;
} }
/** /**
* Parses the request and providing it's valid returns the DispositionActionDefinition object. * Parses the request and providing it's valid returns the DispositionActionDefinition object.
* *
* @param req The webscript request * @param req The webscript request
* @param schedule The disposition schedule * @param schedule The disposition schedule
* @return The DispositionActionDefinition object the request is aimed at * @return The DispositionActionDefinition object the request is aimed at
@@ -93,16 +94,16 @@ public class DispositionAbstractBase extends AbstractRmWebScript
DispositionActionDefinition actionDef = schedule.getDispositionActionDefinition(actionDefId); DispositionActionDefinition actionDef = schedule.getDispositionActionDefinition(actionDefId);
if (actionDef == null) if (actionDef == null)
{ {
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND,
"Requested disposition action definition (id:" + actionDefId + ") does not exist"); "Requested disposition action definition (id:" + actionDefId + ") does not exist");
} }
return actionDef; return actionDef;
} }
/** /**
* Helper to create a model to represent the given disposition action definition. * Helper to create a model to represent the given disposition action definition.
* *
* @param actionDef The DispositionActionDefinition instance to generate model for * @param actionDef The DispositionActionDefinition instance to generate model for
* @param url The URL for the DispositionActionDefinition * @param url The URL for the DispositionActionDefinition
* @return Map representing the model * @return Map representing the model
@@ -111,34 +112,34 @@ public class DispositionAbstractBase extends AbstractRmWebScript
String url) String url)
{ {
Map<String, Object> model = new HashMap<String, Object>(8); Map<String, Object> model = new HashMap<String, Object>(8);
model.put("id", actionDef.getId()); model.put("id", actionDef.getId());
model.put("index", actionDef.getIndex()); model.put("index", actionDef.getIndex());
model.put("url", url); model.put("url", url);
model.put("name", actionDef.getName()); model.put("name", actionDef.getName());
model.put("label", actionDef.getLabel()); model.put("label", actionDef.getLabel());
model.put("eligibleOnFirstCompleteEvent", actionDef.eligibleOnFirstCompleteEvent()); model.put("eligibleOnFirstCompleteEvent", actionDef.eligibleOnFirstCompleteEvent());
if (actionDef.getDescription() != null) if (actionDef.getDescription() != null)
{ {
model.put("description", actionDef.getDescription()); model.put("description", actionDef.getDescription());
} }
if (actionDef.getPeriod() != null) if (actionDef.getPeriod() != null)
{ {
model.put("period", actionDef.getPeriod().toString()); model.put("period", actionDef.getPeriod().toString());
} }
if (actionDef.getPeriodProperty() != null) if (actionDef.getPeriodProperty() != null)
{ {
model.put("periodProperty", actionDef.getPeriodProperty().toPrefixString(this.namespaceService)); model.put("periodProperty", actionDef.getPeriodProperty().toPrefixString(this.namespaceService));
} }
if (actionDef.getLocation() != null) if (actionDef.getLocation() != null)
{ {
model.put("location", actionDef.getLocation()); model.put("location", actionDef.getLocation());
} }
List<RecordsManagementEvent> events = actionDef.getEvents(); List<RecordsManagementEvent> events = actionDef.getEvents();
if (events != null && events.size() > 0) if (events != null && events.size() > 0)
{ {
@@ -149,7 +150,66 @@ public class DispositionAbstractBase extends AbstractRmWebScript
} }
model.put("events", eventNames); model.put("events", eventNames);
} }
return model;
}
/**
* Helper method to parse the request and retrieve the disposition schedule model.
*
* @param req The webscript request
* @return Map representing the model
*/
protected Map<String, Object> getDispositionScheduleModel(WebScriptRequest req)
{
// parse the request to retrieve the schedule object
DispositionSchedule schedule = parseRequestForSchedule(req);
// add all the schedule data to Map
Map<String, Object> scheduleModel = new HashMap<String, Object>(8);
// build url
String serviceUrl = req.getServiceContextPath() + req.getPathInfo();
scheduleModel.put("url", serviceUrl);
String actionsUrl = serviceUrl + "/dispositionactiondefinitions";
scheduleModel.put("actionsUrl", actionsUrl);
scheduleModel.put("nodeRef", schedule.getNodeRef().toString());
scheduleModel.put("recordLevelDisposition", schedule.isRecordLevelDisposition());
scheduleModel.put("canStepsBeRemoved",
!this.dispositionService.hasDisposableItems(schedule));
if (schedule.getDispositionAuthority() != null)
{
scheduleModel.put("authority", schedule.getDispositionAuthority());
}
if (schedule.getDispositionInstructions() != null)
{
scheduleModel.put("instructions", schedule.getDispositionInstructions());
}
boolean unpublishedUpdates = false;
boolean publishInProgress = false;
List<Map<String, Object>> actions = new ArrayList<Map<String, Object>>();
for (DispositionActionDefinition actionDef : schedule.getDispositionActionDefinitions())
{
NodeRef actionDefNodeRef = actionDef.getNodeRef();
if (nodeService.hasAspect(actionDefNodeRef, RecordsManagementModel.ASPECT_UNPUBLISHED_UPDATE) == true)
{
unpublishedUpdates = true;
publishInProgress = ((Boolean)nodeService.getProperty(actionDefNodeRef, RecordsManagementModel.PROP_PUBLISH_IN_PROGRESS)).booleanValue();
}
actions.add(createActionDefModel(actionDef, actionsUrl + "/" + actionDef.getId()));
}
scheduleModel.put("actions", actions);
scheduleModel.put("unpublishedUpdates", unpublishedUpdates);
scheduleModel.put("publishInProgress", publishInProgress);
// create model object with just the schedule data
Map<String, Object> model = new HashMap<String, Object>(1);
model.put("schedule", scheduleModel);
return model; return model;
} }
} }

View File

@@ -18,7 +18,7 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.script; package org.alfresco.module.org_alfresco_module_rm.script;
import java.util.HashMap; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
@@ -29,7 +29,7 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
/** /**
* Implementation for Java backed webscript to delete a dispostion action definition. * Implementation for Java backed webscript to delete a dispostion action definition.
* *
* @author Gavin Cornwell * @author Gavin Cornwell
*/ */
public class DispositionActionDefinitionDelete extends DispositionAbstractBase public class DispositionActionDefinitionDelete extends DispositionAbstractBase
@@ -42,14 +42,33 @@ public class DispositionActionDefinitionDelete extends DispositionAbstractBase
{ {
// parse the request to retrieve the schedule object // parse the request to retrieve the schedule object
DispositionSchedule schedule = parseRequestForSchedule(req); DispositionSchedule schedule = parseRequestForSchedule(req);
// parse the request to retrieve the action definition object // parse the request to retrieve the action definition object
DispositionActionDefinition actionDef = parseRequestForActionDefinition(req, schedule); DispositionActionDefinition actionDef = parseRequestForActionDefinition(req, schedule);
// remove the action definition from the schedule // remove the action definition from the schedule
this.dispositionService.removeDispositionActionDefinition(schedule, actionDef); removeDispositionActionDefinitions(schedule, actionDef);
// return an empty model // return the disposition schedule model
return new HashMap<String, Object>(); return getDispositionScheduleModel(req);
}
/**
* Helper method to remove a disposition action definition and the following definition(s)
*
* @param schedule The disposition schedule
* @param actionDef The disposition action definition
*/
private void removeDispositionActionDefinitions(DispositionSchedule schedule, DispositionActionDefinition actionDef)
{
int index = actionDef.getIndex();
List<DispositionActionDefinition> dispositionActionDefinitions = schedule.getDispositionActionDefinitions();
for (DispositionActionDefinition dispositionActionDefinition : dispositionActionDefinitions)
{
if (dispositionActionDefinition.getIndex() >= index)
{
dispositionService.removeDispositionActionDefinition(schedule, dispositionActionDefinition);
}
}
} }
} }

View File

@@ -18,15 +18,8 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.script; package org.alfresco.module.org_alfresco_module_rm.script;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
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.model.RecordsManagementModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptRequest;
@@ -34,7 +27,7 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
/** /**
* Implementation for Java backed webscript to return full details * Implementation for Java backed webscript to return full details
* about a disposition schedule. * about a disposition schedule.
* *
* @author Gavin Cornwell * @author Gavin Cornwell
*/ */
public class DispositionScheduleGet extends DispositionAbstractBase public class DispositionScheduleGet extends DispositionAbstractBase
@@ -45,54 +38,7 @@ public class DispositionScheduleGet extends DispositionAbstractBase
@Override @Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{ {
// parse the request to retrieve the schedule object // return the disposition schedule model
DispositionSchedule schedule = parseRequestForSchedule(req); return getDispositionScheduleModel(req);
// add all the schedule data to Map
Map<String, Object> scheduleModel = new HashMap<String, Object>(8);
// build url
String serviceUrl = req.getServiceContextPath() + req.getPathInfo();
scheduleModel.put("url", serviceUrl);
String actionsUrl = serviceUrl + "/dispositionactiondefinitions";
scheduleModel.put("actionsUrl", actionsUrl);
scheduleModel.put("nodeRef", schedule.getNodeRef().toString());
scheduleModel.put("recordLevelDisposition", schedule.isRecordLevelDisposition());
scheduleModel.put("canStepsBeRemoved",
!this.dispositionService.hasDisposableItems(schedule));
if (schedule.getDispositionAuthority() != null)
{
scheduleModel.put("authority", schedule.getDispositionAuthority());
}
if (schedule.getDispositionInstructions() != null)
{
scheduleModel.put("instructions", schedule.getDispositionInstructions());
}
boolean unpublishedUpdates = false;
boolean publishInProgress = false;
List<Map<String, Object>> actions = new ArrayList<Map<String, Object>>();
for (DispositionActionDefinition actionDef : schedule.getDispositionActionDefinitions())
{
NodeRef actionDefNodeRef = actionDef.getNodeRef();
if (nodeService.hasAspect(actionDefNodeRef, RecordsManagementModel.ASPECT_UNPUBLISHED_UPDATE) == true)
{
unpublishedUpdates = true;
publishInProgress = ((Boolean)nodeService.getProperty(actionDefNodeRef, RecordsManagementModel.PROP_PUBLISH_IN_PROGRESS)).booleanValue();
}
actions.add(createActionDefModel(actionDef, actionsUrl + "/" + actionDef.getId()));
}
scheduleModel.put("actions", actions);
scheduleModel.put("unpublishedUpdates", unpublishedUpdates);
scheduleModel.put("publishInProgress", publishInProgress);
// create model object with just the schedule data
Map<String, Object> model = new HashMap<String, Object>(1);
model.put("schedule", scheduleModel);
return model;
} }
} }