diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties
index c55856199e..ab66f43877 100644
--- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties
+++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties
@@ -34,4 +34,5 @@ rm.action.node-already-transfer=Node is already being transfered.
rm.action.node-not-transfer=Node is not a transfer object.
rm.action.undo-not-last=Can not undo cut off, because last disposition action was not cut off.
rm.action.records_only_undeclared=Only records can be undeclared.
-rm.action.event-not-undone=The event {0} can not be undone, because it is not defined on the disposition lifecycle.
\ No newline at end of file
+rm.action.event-not-undone=The event {0} can not be undone, because it is not defined on the disposition lifecycle.
+rm.action.empty-set-of-noderefs=The set of nodeRefs is empty.
\ No newline at end of file
diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml
index 7ff02d14d0..2731aefaaa 100644
--- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml
+++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml
@@ -398,8 +398,9 @@
-
-
+
+
+
@@ -425,8 +426,9 @@
-
-
+
+
+
@@ -442,8 +444,9 @@
-
-
+
+
+
@@ -469,7 +472,8 @@
-
+
+
diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
index eb95219e78..8d6aa004ec 100644
--- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
+++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
@@ -722,6 +722,7 @@
+
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 6623bf9dc0..2ce37fad33 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
@@ -365,8 +365,11 @@ public abstract class RMActionExecuterAbstractBase extends ActionExecuterAbstra
* @param s String to pad with leading zero '0' characters
* @param len Length to pad to
*
- * @return padded string or the original if already at >=len characters
+ * @return padded string or the original if already at >=len characters
+ *
+ * @deprecated As of 2.1, replaced by {@link org.apache.commons.lang.StringUtils.leftPad}
*/
+ @Deprecated
protected String padString(String s, int len)
{
String result = s;
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java
index f840f8e42f..3308e06ff0 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java
@@ -25,9 +25,11 @@ import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
+import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
+import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -37,83 +39,93 @@ import org.springframework.extensions.surf.util.I18NUtil;
*/
public class EditHoldReasonAction extends RMActionExecuterAbstractBase
{
- private static final String MSG_HOLD_EDIT_REASON_NONE = "rm.action.hold-edit-reason-none";
- private static final String MSG_HOLD_EDIT_TYPE = "rm.action.hold-edit-type";
-
- /** Parameter names */
- public static final String PARAM_REASON = "reason";
-
- /**
- * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
- */
- @Override
- protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
- {
- QName nodeType = this.nodeService.getType(actionedUponNodeRef);
- if (this.dictionaryService.isSubClass(nodeType, TYPE_HOLD) == true)
- {
- // Get the property values
- String reason = (String)action.getParameterValue(PARAM_REASON);
- if (reason == null || reason.length() == 0)
- {
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_HOLD_EDIT_REASON_NONE));
- }
-
- // Set the hold reason
- nodeService.setProperty(actionedUponNodeRef, PROP_HOLD_REASON, reason);
+ private static final String MSG_HOLD_EDIT_REASON_NONE = "rm.action.hold-edit-reason-none";
+ private static final String MSG_HOLD_EDIT_TYPE = "rm.action.hold-edit-type";
- }
- else
- {
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_HOLD_EDIT_TYPE, TYPE_HOLD.toString(), actionedUponNodeRef.toString()));
- }
- }
-
- /**
- * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedAspects()
- */
- @Override
- public Set getProtectedAspects()
- {
- HashSet qnames = new HashSet();
- qnames.add(ASPECT_FROZEN);
- return qnames;
- }
+ /** Parameter names */
+ public static final String PARAM_REASON = "reason";
- /**
- * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedProperties()
- */
- @Override
- public Set getProtectedProperties()
- {
- HashSet qnames = new HashSet();
- qnames.add(PROP_HOLD_REASON);
- return qnames;
- }
+ /** Freeze Service */
+ private FreezeService freezeService;
- /**
- * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#isExecutableImpl(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, boolean)
- */
- @Override
- protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
- {
- QName nodeType = this.nodeService.getType(filePlanComponent);
- if (this.dictionaryService.isSubClass(nodeType, TYPE_HOLD) == true)
- {
- return true;
- }
- else
- {
- if(throwException)
- {
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_HOLD_EDIT_TYPE, TYPE_HOLD.toString(), filePlanComponent.toString()));
- }
- else
- {
- return false;
- }
- }
- }
+ /**
+ * Set freeze service
+ *
+ * @param freezeService freeze service
+ */
+ public void setFreezeService(FreezeService freezeService)
+ {
+ this.freezeService = freezeService;
+ }
+
+ /**
+ * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
+ {
+ if (freezeService.isHold(actionedUponNodeRef))
+ {
+ // Get the property values
+ String reason = (String) action.getParameterValue(PARAM_REASON);
+ if (StringUtils.isBlank(reason))
+ {
+ throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_HOLD_EDIT_REASON_NONE));
+ }
+
+ // Update hold reason
+ freezeService.updateReason(actionedUponNodeRef, reason);
+ }
+ else
+ {
+ throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_HOLD_EDIT_TYPE, TYPE_HOLD.toString(), actionedUponNodeRef.toString()));
+ }
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedAspects()
+ */
+ @Override
+ public Set getProtectedAspects()
+ {
+ HashSet qnames = new HashSet();
+ qnames.add(ASPECT_FROZEN);
+ return qnames;
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedProperties()
+ */
+ @Override
+ public Set getProtectedProperties()
+ {
+ HashSet qnames = new HashSet();
+ qnames.add(PROP_HOLD_REASON);
+ return qnames;
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#isExecutableImpl(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, boolean)
+ */
+ @Override
+ protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
+ {
+ QName nodeType = this.nodeService.getType(filePlanComponent);
+ if (this.dictionaryService.isSubClass(nodeType, TYPE_HOLD) == true)
+ {
+ return true;
+ }
+ else
+ {
+ if(throwException)
+ {
+ throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_HOLD_EDIT_TYPE, TYPE_HOLD.toString(), filePlanComponent.toString()));
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
-
}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileAction.java
index 5a0e0cc058..754eb1fe2a 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileAction.java
@@ -38,6 +38,7 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
+import org.apache.commons.lang.StringUtils;
/**
* Files a record into a particular record folder
@@ -79,7 +80,7 @@ public class FileAction extends RMActionExecuterAbstractBase
// Calculate the filed date and record identifier
String year = Integer.toString(fileCalendar.get(Calendar.YEAR));
QName nodeDbid = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "node-dbid");
- String recordId = year + "-" + padString(recordProperties.get(nodeDbid).toString(), 10);
+ String recordId = year + "-" + StringUtils.leftPad(recordProperties.get(nodeDbid).toString(), 10, "0");
recordProperties.put(RecordsManagementModel.PROP_IDENTIFIER, recordId);
}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java
index 2ceb3da826..0455bdea9d 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java
@@ -19,24 +19,16 @@
package org.alfresco.module.org_alfresco_module_rm.action.impl;
import java.io.Serializable;
-import java.util.Date;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
-import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
+import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -46,180 +38,95 @@ import org.springframework.extensions.surf.util.I18NUtil;
*/
public class FreezeAction extends RMActionExecuterAbstractBase
{
- private static final String MSG_FREEZE_NO_REASON = "rm.action.freeze-no-reason";
- private static final String MSG_FREEZE_ONLY_RECORDS_FOLDERS = "rm.action.freeze-only-records-folders";
-
- /** Logger */
- private static Log logger = LogFactory.getLog(FreezeAction.class);
+ private static final String MSG_FREEZE_NO_REASON = "rm.action.freeze-no-reason";
+ private static final String MSG_FREEZE_ONLY_RECORDS_FOLDERS = "rm.action.freeze-only-records-folders";
- /** Parameter names */
- public static final String PARAM_REASON = "reason";
-
- /** Hold node reference key */
- private static final String KEY_HOLD_NODEREF = "holdNodeRef";
-
- /**
- * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
- */
- @Override
- protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
- {
- final boolean isRecord = recordsManagementService.isRecord(actionedUponNodeRef);
- final boolean isFolder = this.recordsManagementService.isRecordFolder(actionedUponNodeRef);
-
- if (isRecord || isFolder)
- {
- // Get the property values
- String reason = (String)action.getParameterValue(PARAM_REASON);
+ /** Parameter names */
+ public static final String PARAM_REASON = "reason";
+
+ /** Freeze Service */
+ private FreezeService freezeService;
+
+ /**
+ * Set freeze service
+ *
+ * @param freezeService freeze service
+ */
+ public void setFreezeService(FreezeService freezeService)
+ {
+ this.freezeService = freezeService;
+ }
+
+ /**
+ * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
+ {
+ freezeService.freeze((String) action.getParameterValue(PARAM_REASON), actionedUponNodeRef);
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedAspects()
+ */
+ @Override
+ public Set getProtectedAspects()
+ {
+ HashSet qnames = new HashSet();
+ qnames.add(ASPECT_FROZEN);
+ return qnames;
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedProperties()
+ */
+ @Override
+ public Set getProtectedProperties()
+ {
+ HashSet qnames = new HashSet();
+ qnames.add(PROP_HOLD_REASON);
+ //TODO Add prop frozen at/by?
+ return qnames;
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#isExecutableImpl(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, boolean)
+ */
+ @Override
+ protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
+ {
+ if (this.recordsManagementService.isRecord(filePlanComponent) == true ||
+ this.recordsManagementService.isRecordFolder(filePlanComponent) == true)
+ {
+ // Get the property values
+ if(parameters != null)
+ {
+ String reason = (String)parameters.get(PARAM_REASON);
if (reason == null || reason.length() == 0)
{
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_FREEZE_NO_REASON));
+ if(throwException)
+ {
+ throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_FREEZE_NO_REASON));
+ }
+ else
+ {
+ return false;
+ }
}
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Freezing node ").append(actionedUponNodeRef);
- if (isFolder)
- {
- msg.append(" (folder)");
- }
- msg.append(" with reason '").append(reason).append("'");
- logger.debug(msg.toString());
- }
-
- // Get the root rm node
- NodeRef root = this.recordsManagementService.getFilePlan(actionedUponNodeRef);
-
- // Get the hold object
- NodeRef holdNodeRef = (NodeRef)AlfrescoTransactionSupport.getResource(KEY_HOLD_NODEREF);
-
- if (holdNodeRef == null)
- {
- // Calculate a transfer name
- QName nodeDbid = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "node-dbid");
- Long dbId = (Long)this.nodeService.getProperty(actionedUponNodeRef, nodeDbid);
- String transferName = padString(dbId.toString(), 10);
-
- // Create the hold object
- Map holdProps = new HashMap(2);
- holdProps.put(ContentModel.PROP_NAME, transferName);
- holdProps.put(PROP_HOLD_REASON, reason);
- final QName transferQName = QName.createQName(RM_URI, transferName);
- holdNodeRef = this.nodeService.createNode(root,
- ASSOC_HOLDS,
- transferQName,
- TYPE_HOLD,
- holdProps).getChildRef();
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Created hold object ").append(holdNodeRef)
- .append(" with transfer name ").append(transferQName);
- logger.debug(msg.toString());
- }
-
- // Bind the hold node reference to the transaction
- AlfrescoTransactionSupport.bindResource(KEY_HOLD_NODEREF, holdNodeRef);
- }
-
- // Link the record to the hold
- this.nodeService.addChild( holdNodeRef,
- actionedUponNodeRef,
- ASSOC_FROZEN_RECORDS,
- ASSOC_FROZEN_RECORDS);
-
- // Apply the freeze aspect
- Map props = new HashMap(2);
- props.put(PROP_FROZEN_AT, new Date());
- props.put(PROP_FROZEN_BY, AuthenticationUtil.getFullyAuthenticatedUser());
- this.nodeService.addAspect(actionedUponNodeRef, ASPECT_FROZEN, props);
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Frozen aspect applied to ").append(actionedUponNodeRef);
- logger.debug(msg.toString());
- }
-
-
- // Mark all the folders contents as frozen
- if (isFolder)
- {
- List records = this.recordsManagementService.getRecords(actionedUponNodeRef);
- for (NodeRef record : records)
- {
- this.nodeService.addAspect(record, ASPECT_FROZEN, props);
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Frozen aspect applied to ").append(record);
- logger.debug(msg.toString());
- }
- }
- }
- }
- else
- {
+ }
+ return true;
+ }
+ else
+ {
+ if(throwException)
+ {
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_FREEZE_ONLY_RECORDS_FOLDERS));
- }
- }
-
- @Override
- public Set getProtectedAspects()
- {
- HashSet qnames = new HashSet();
- qnames.add(ASPECT_FROZEN);
- return qnames;
- }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
- @Override
- public Set getProtectedProperties()
- {
- HashSet qnames = new HashSet();
- qnames.add(PROP_HOLD_REASON);
- //TODO Add prop frozen at/by?
- return qnames;
- }
-
- @Override
- protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
- {
- if (this.recordsManagementService.isRecord(filePlanComponent) == true ||
- this.recordsManagementService.isRecordFolder(filePlanComponent) == true)
- {
- // Get the property values
- if(parameters != null)
- {
- String reason = (String)parameters.get(PARAM_REASON);
- if (reason == null || reason.length() == 0)
- {
- if(throwException)
- {
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_FREEZE_NO_REASON));
- }
- else
- {
- return false;
- }
- }
- }
- return true;
- }
- else
- {
- if(throwException)
- {
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_FREEZE_ONLY_RECORDS_FOLDERS));
- }
- else
- {
- return false;
- }
- }
- }
-
-
}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java
index 5fdb6a9676..f0e205d088 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java
@@ -20,20 +20,15 @@ package org.alfresco.module.org_alfresco_module_rm.action.impl;
import java.io.Serializable;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
-import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
+import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
import org.alfresco.service.cmr.action.Action;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
-import org.alfresco.service.namespace.RegexQNamePattern;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -43,158 +38,71 @@ import org.springframework.extensions.surf.util.I18NUtil;
*/
public class RelinquishHoldAction extends RMActionExecuterAbstractBase
{
- /** Logger */
- private static Log logger = LogFactory.getLog(RelinquishHoldAction.class);
-
- /** I18N */
- private static final String MSG_NOT_HOLD_TYPE = "rm.action.not-hold-type";
+ /** I18N */
+ private static final String MSG_NOT_HOLD_TYPE = "rm.action.not-hold-type";
- /**
- * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
- */
- @Override
- protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
- {
- QName nodeType = this.nodeService.getType(actionedUponNodeRef);
- if (this.dictionaryService.isSubClass(nodeType, TYPE_HOLD) == true)
- {
- final NodeRef holdBeingRelinquished = actionedUponNodeRef;
- List frozenNodeAssocs = nodeService.getChildAssocs(holdBeingRelinquished, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Relinquishing hold ").append(holdBeingRelinquished)
- .append(" which has ").append(frozenNodeAssocs.size()).append(" frozen node(s).");
- logger.debug(msg.toString());
- }
-
- for (ChildAssociationRef assoc : frozenNodeAssocs)
- {
- final NodeRef nextFrozenNode = assoc.getChildRef();
-
- // Remove the freeze if this is the only hold that references the node
- removeFreeze(nextFrozenNode, holdBeingRelinquished);
- }
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Deleting hold object ").append(holdBeingRelinquished)
- .append(" with name ").append(nodeService.getProperty(holdBeingRelinquished, ContentModel.PROP_NAME));
- logger.debug(msg.toString());
- }
-
- // Delete the hold node
- this.nodeService.deleteNode(holdBeingRelinquished);
- }
- else
- {
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NOT_HOLD_TYPE, TYPE_HOLD.toString(), actionedUponNodeRef.toString()));
- }
- }
-
- /**
- * Removes a freeze from a node
- *
- * @param nodeRef node reference
- */
- private void removeFreeze(NodeRef nodeRef, NodeRef holdBeingRelinquished)
- {
- // We should only remove the frozen aspect if there are no other 'holds' in effect for this node.
- // One complication to consider is that holds can be placed on records or on folders.
- // Therefore if the nodeRef here is a record, we need to go up the containment hierarchy looking
- // for holds at each level.
+ /** Freeze Service */
+ private FreezeService freezeService;
- // Get all the holds and remove this node from them.
- List parentAssocs = this.nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
- // If the nodeRef is a record, there could also be applicable holds as parents of the folder(s).
- if (recordsManagementService.isRecord(nodeRef))
- {
- List parentFolders = recordsManagementService.getRecordFolders(nodeRef);
- for (NodeRef folder : parentFolders)
- {
- List moreAssocs = nodeService.getParentAssocs(folder, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
- parentAssocs.addAll(moreAssocs);
- }
- }
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Removing freeze from ").append(nodeRef).append(" which has ")
- .append(parentAssocs.size()).append(" holds");
- logger.debug(msg.toString());
- }
+ /**
+ * Set freeze service
+ *
+ * @param freezeService freeze service
+ */
+ public void setFreezeService(FreezeService freezeService)
+ {
+ this.freezeService = freezeService;
+ }
- boolean otherHoldsAreInEffect = false;
- for (ChildAssociationRef chAssRef : parentAssocs)
- {
- if (!chAssRef.getParentRef().equals(holdBeingRelinquished))
- {
- otherHoldsAreInEffect = true;
- break;
- }
- }
-
- if (!otherHoldsAreInEffect)
- {
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Removing frozen aspect from ").append(nodeRef);
- logger.debug(msg.toString());
- }
+ /**
+ * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
+ {
+ if (freezeService.isHold(actionedUponNodeRef))
+ {
+ freezeService.relinquish(actionedUponNodeRef);
+ }
+ else
+ {
+ throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NOT_HOLD_TYPE, TYPE_HOLD.toString(), actionedUponNodeRef.toString()));
+ }
+ }
- // Remove the aspect
- this.nodeService.removeAspect(nodeRef, ASPECT_FROZEN);
- }
-
- // Remove the freezes on the child records as long as there is no other hold referencing them
- if (this.recordsManagementService.isRecordFolder(nodeRef) == true)
- {
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append(nodeRef).append(" is a record folder");
- logger.debug(msg.toString());
- }
- for (NodeRef record : recordsManagementService.getRecords(nodeRef))
- {
- removeFreeze(record, holdBeingRelinquished);
- }
- }
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedAspects()
+ */
+ @Override
+ public Set getProtectedAspects()
+ {
+ HashSet qnames = new HashSet();
+ qnames.add(ASPECT_FROZEN);
+ return qnames;
+ }
- }
-
- @Override
- public Set getProtectedAspects()
- {
- HashSet qnames = new HashSet();
- qnames.add(ASPECT_FROZEN);
- return qnames;
- }
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#isExecutableImpl(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, boolean)
+ */
+ @Override
+ protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
+ {
+ QName nodeType = this.nodeService.getType(filePlanComponent);
+ if (this.dictionaryService.isSubClass(nodeType, TYPE_HOLD) == true)
+ {
+ return true;
+ }
+ else
+ {
+ if(throwException)
+ {
+ throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NOT_HOLD_TYPE, TYPE_HOLD.toString(), filePlanComponent.toString()));
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
- @Override
- protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
- {
- QName nodeType = this.nodeService.getType(filePlanComponent);
- if (this.dictionaryService.isSubClass(nodeType, TYPE_HOLD) == true)
- {
- return true;
- }
- else
- {
- if(throwException)
- {
- throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NOT_HOLD_TYPE, TYPE_HOLD.toString(), filePlanComponent.toString()));
- }
- else
- {
- return false;
- }
- }
- }
-
-
}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java
index ba051b93b6..709fb3dfdc 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java
@@ -37,6 +37,7 @@ import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
+import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -111,7 +112,7 @@ public class TransferAction extends RMDispositionActionExecuterAbstractBase
// Calculate a transfer name
QName nodeDbid = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "node-dbid");
Long dbId = (Long)this.nodeService.getProperty(dispositionLifeCycleNodeRef, nodeDbid);
- String transferName = padString(dbId.toString(), 10);
+ String transferName = StringUtils.leftPad(dbId.toString(), 10, "0");
// Create the transfer object
Map transferProps = new HashMap(2);
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java
index 9189184f75..a3b7c71582 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java
@@ -20,19 +20,14 @@ package org.alfresco.module.org_alfresco_module_rm.action.impl;
import java.io.Serializable;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
+import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
import org.alfresco.service.cmr.action.Action;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
-import org.alfresco.service.namespace.RegexQNamePattern;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
/**
* Unfreeze Action
@@ -41,119 +36,46 @@ import org.apache.commons.logging.LogFactory;
*/
public class UnfreezeAction extends RMActionExecuterAbstractBase
{
- /** Logger */
- private static Log logger = LogFactory.getLog(UnfreezeAction.class);
+ /** Freeze Service */
+ private FreezeService freezeService;
- /**
- * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action,
- * org.alfresco.service.cmr.repository.NodeRef)
- */
- @Override
- protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
- {
- if (this.nodeService.hasAspect(actionedUponNodeRef, ASPECT_FROZEN) == true)
- {
- final boolean isFolder = this.recordsManagementService.isRecordFolder(actionedUponNodeRef);
+ /**
+ * Set freeze service
+ *
+ * @param freezeService freeze service
+ */
+ public void setFreezeService(FreezeService freezeService)
+ {
+ this.freezeService = freezeService;
+ }
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Unfreezing node ").append(actionedUponNodeRef);
- if (isFolder)
- {
- msg.append(" (folder)");
- }
- logger.debug(msg.toString());
- }
+ /**
+ * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
+ {
+ freezeService.unFreeze(actionedUponNodeRef);
+ }
- // Remove freeze from node
- removeFreeze(actionedUponNodeRef);
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedAspects()
+ */
+ @Override
+ public Set getProtectedAspects()
+ {
+ HashSet qnames = new HashSet();
+ qnames.add(ASPECT_FROZEN);
+ return qnames;
+ }
- // Remove freeze from records if a record folder
- if (isFolder)
- {
- List records = this.recordsManagementService.getRecords(actionedUponNodeRef);
- for (NodeRef record : records)
- {
- removeFreeze(record);
- }
- }
- }
- }
-
- /**
- * Removes a freeze from a node
- *
- * @param nodeRef
- * node reference
- */
- private void removeFreeze(NodeRef nodeRef)
- {
- // Get all the holds and remove this node from them
- List assocs = this.nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Removing freeze from node ").append(nodeRef)
- .append("which has ").append(assocs.size()).append(" holds");
- logger.debug(msg.toString());
- }
-
- for (ChildAssociationRef assoc : assocs)
- {
- // Remove the frozen node as a child
- NodeRef holdNodeRef = assoc.getParentRef();
- this.nodeService.removeChild(holdNodeRef, nodeRef);
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Removed frozen node from hold ").append(holdNodeRef);
- logger.debug(msg.toString());
- }
-
- // Check to see if we should delete the hold
- List holdAssocs = this.nodeService.getChildAssocs(holdNodeRef, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
- if (holdAssocs.size() == 0)
- {
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Hold node ").append(holdNodeRef)
- .append(" with name ").append(nodeService.getProperty(holdNodeRef, ContentModel.PROP_NAME))
- .append(" has no frozen nodes. Hence deleting it.");
- logger.debug(msg.toString());
- }
-
- // Delete the hold object
- this.nodeService.deleteNode(holdNodeRef);
- }
- }
-
- // Remove the aspect
- this.nodeService.removeAspect(nodeRef, ASPECT_FROZEN);
-
- if (logger.isDebugEnabled())
- {
- StringBuilder msg = new StringBuilder();
- msg.append("Removed frozen aspect from ").append(nodeRef);
- logger.debug(msg.toString());
- }
- }
-
- @Override
- public Set getProtectedAspects()
- {
- HashSet qnames = new HashSet();
- qnames.add(ASPECT_FROZEN);
- return qnames;
- }
-
- @Override
- protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
- {
- return this.nodeService.hasAspect(filePlanComponent, ASPECT_FROZEN);
- }
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#isExecutableImpl(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, boolean)
+ */
+ @Override
+ protected boolean isExecutableImpl(NodeRef filePlanComponent, Map parameters, boolean throwException)
+ {
+ return this.nodeService.hasAspect(filePlanComponent, ASPECT_FROZEN);
+ }
}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeService.java
index 66d372eb64..9c8c79f86b 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeService.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeService.java
@@ -18,6 +18,9 @@
*/
package org.alfresco.module.org_alfresco_module_rm.freeze;
+import java.util.Set;
+
+import org.alfresco.service.cmr.repository.NodeRef;
/**
* Freeze Service Interface
@@ -39,7 +42,7 @@ public interface FreezeService
* @param nodeRef hold node reference
* @return boolean true if hold, false otherwise
*/
- // TODO boolean isHold(NodeRef nodeRef);
+ boolean isHold(NodeRef nodeRef);
/**
* Indicates whether the passed node reference is frozen.
@@ -47,7 +50,7 @@ public interface FreezeService
* @param nodeRef node reference
* @return boolean true if frozen, false otherwise
*/
- // TODO boolean isFrozen(NodeRef nodeRef);
+ boolean isFrozen(NodeRef nodeRef);
/**
* Get the 'root' frozen node references in a hold.
@@ -55,7 +58,7 @@ public interface FreezeService
* @param hold hold node reference
* @return Set frozen node references
*/
- // TODO Set getFrozen(NodeRef hold);
+ Set getFrozen(NodeRef hold);
/**
* Freezes a node with the provided reason, creating a hold node reference.
@@ -64,7 +67,7 @@ public interface FreezeService
* @param nodeRef node reference
* @return NodeRef hold node reference
*/
- // TODO NodeRef freeze(String reason, NodeRef nodeRef);
+ NodeRef freeze(String reason, NodeRef nodeRef);
/**
* Freezes a node, adding it an existing hold.
@@ -72,24 +75,24 @@ public interface FreezeService
* @param hold hold node reference
* @param nodeRef node reference
*/
- // TODO void freeze(NodeRef hold, NodeRef nodeRef);
+ void freeze(NodeRef hold, NodeRef nodeRef);
/**
* Freezes a collection of nodes with the given reason, creating a hold.
*
* @param reason freeze reason
- * @param Set set of nodes to freeze
+ * @param nodeRefs set of nodes to freeze
* @return NodeRef hold node reference
*/
- // TODO NodeRef freeze(String reason, Set nodeRef);
+ NodeRef freeze(String reason, Set nodeRefs);
/**
* Freeze a collection of nodes, adding them to an existing hold.
*
* @param hold hold node reference
- * @param nodeRef set of nodes to freeze
+ * @param nodeRefs set of nodes to freeze
*/
- // TODO void freeze(NodeRef hold, Set nodeRef);
+ void freeze(NodeRef hold, Set nodeRefs);
/**
* Unfreeze a frozen node.
@@ -99,7 +102,7 @@ public interface FreezeService
*
* @param nodeRef node reference
*/
- // TODO void unFreeze(NodeRef nodeRef);
+ void unFreeze(NodeRef nodeRef);
/**
* Unfreeze a collection of nodes.
@@ -107,16 +110,16 @@ public interface FreezeService
* The unfrozen nodes are automatically removed from the hold(s) the are in. If the hold(s) is
* subsequently empty, the hold is automatically deleted.
*
- * @param Set set of nodes to unfreeze
+ * @param nodeRefs set of nodes to unfreeze
*/
- // TODO void unFreeze(Set nodeRef);
+ void unFreeze(Set nodeRefs);
/**
* Unfreezes all nodes within a hold and deletes the hold.
*
* @param hold hold node reference
*/
- // TODO void relinquish(NodeRef hold);
+ void relinquish(NodeRef hold);
/**
* Gets the freeze reason for a hold.
@@ -124,7 +127,7 @@ public interface FreezeService
* @param hold hold node reference
* @return String freeze reason
*/
- // TODO String getReason(NodeRef hold);
+ String getReason(NodeRef hold);
/**
* Updates the freeze reason for a given hold.
@@ -132,5 +135,5 @@ public interface FreezeService
* @param hold hold node reference
* @param reason updated reason
*/
- // TODO void updateReason(NodeRef hold, String reason);
+ void updateReason(NodeRef hold, String reason);
}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java
index f28a7bd57b..ea8feb9920 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java
@@ -18,20 +18,38 @@
*/
package org.alfresco.module.org_alfresco_module_rm.freeze;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.node.NodeServicePolicies;
+import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
-import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.AccessDeniedException;
+import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.util.ParameterCheck;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.extensions.surf.util.I18NUtil;
/**
* Freeze Service Implementation
@@ -42,101 +60,579 @@ public class FreezeServiceImpl implements FreezeService,
RecordsManagementModel,
NodeServicePolicies.BeforeDeleteNodePolicy
{
- /** Policy Component */
- private PolicyComponent policyComponent;
-
- /** Node Service */
- private NodeService nodeService;
+ /** Logger */
+ private static Log logger = LogFactory.getLog(FreezeServiceImpl.class);
- /** Records Management Service */
- private RecordsManagementService recordsManagementService;
+ /** I18N */
+ private static final String MSG_FREEZE_ONLY_RECORDS_FOLDERS = "rm.action.freeze-only-records-folders";
+ private static final String MSG_EMPTY_SET_OF_NODEREFS = "rm.action.empty-set-of-noderefs";
- /**
- * @param policyComponent policy component
- */
- public void setPolicyComponent(PolicyComponent policyComponent)
- {
- this.policyComponent = policyComponent;
- }
-
- /**
- * @param nodeService node service
- */
- public void setNodeService(NodeService nodeService)
- {
- this.nodeService = nodeService;
- }
-
- /**
- * @param recordsManagementService records management service
- */
- public void setRecordsManagementService(RecordsManagementService recordsManagementService)
- {
- this.recordsManagementService = recordsManagementService;
- }
-
- /**
- * Init service
- */
- public void init()
- {
- policyComponent.bindClassBehaviour(
- NodeServicePolicies.BeforeDeleteNodePolicy.QNAME,
- this,
- new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.FIRST_EVENT));
+ /** Hold node reference key */
+ private static final String KEY_HOLD_NODEREF = "holdNodeRef";
+
+ /** Policy Component */
+ private PolicyComponent policyComponent;
+
+ /** Node Service */
+ private NodeService nodeService;
+
+ /** Records Management Service */
+ private RecordsManagementService recordsManagementService;
+
+ /** Dictionary Service */
+ private DictionaryService dictionaryService;
+
+ /**
+ * @param policyComponent policy component
+ */
+ public void setPolicyComponent(PolicyComponent policyComponent)
+ {
+ this.policyComponent = policyComponent;
+ }
+
+ /**
+ * @param nodeService node service
+ */
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ /**
+ * @param recordsManagementService records management service
+ */
+ public void setRecordsManagementService(RecordsManagementService recordsManagementService)
+ {
+ this.recordsManagementService = recordsManagementService;
+ }
+
+ /**
+ * @param dictionaryService dictionary service
+ */
+ public void setDictionaryService(DictionaryService dictionaryService)
+ {
+ this.dictionaryService = dictionaryService;
+ }
+
+ /**
+ * Init service
+ */
+ public void init()
+ {
+ policyComponent.bindClassBehaviour(
+ NodeServicePolicies.BeforeDeleteNodePolicy.QNAME,
+ this,
+ new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.FIRST_EVENT));
}
- /**
- * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
- */
- @Override
- public void beforeDeleteNode(final NodeRef nodeRef)
- {
- AuthenticationUtil.runAsSystem(new RunAsWork(){
+ /**
+ * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public void beforeDeleteNode(final NodeRef nodeRef)
+ {
+ AuthenticationUtil.runAsSystem(new RunAsWork(){
- @Override
- public Void doWork() throws Exception
+ @Override
+ public Void doWork() throws Exception
+ {
+ if (nodeService.exists(nodeRef) == true &&
+ recordsManagementService.isFilePlanComponent(nodeRef) == true)
{
- if (nodeService.exists(nodeRef) == true &&
- recordsManagementService.isFilePlanComponent(nodeRef) == true)
- {
- if (recordsManagementService.isFrozen(nodeRef) == true)
- {
- // never allowed to delete a frozen node
- throw new AccessDeniedException("Frozen nodes can not be deleted.");
- }
-
- // check children
- checkChildren(nodeService.getChildAssocs(nodeRef));
- }
-
- return null;
- }});
-
- }
-
- /**
- * Checks the children for frozen nodes. Throws security error if any are found.
- *
- * @param assocs
- */
- private void checkChildren(List assocs)
- {
- for (ChildAssociationRef assoc : assocs)
- {
- // we only care about primary children
- if (assoc.isPrimary() == true)
- {
- NodeRef nodeRef = assoc.getChildRef();
- if (recordsManagementService.isFrozen(nodeRef) == true)
- {
- // never allowed to delete a node with a frozen child
- throw new AccessDeniedException("Can not delete node, because it contains a frozen child node.");
- }
-
- // check children
- checkChildren(nodeService.getChildAssocs(nodeRef));
+ if (recordsManagementService.isFrozen(nodeRef) == true)
+ {
+ // never allowed to delete a frozen node
+ throw new AccessDeniedException("Frozen nodes can not be deleted.");
+ }
+
+ // check children
+ checkChildren(nodeService.getChildAssocs(nodeRef));
}
- }
+ return null;
+ }
+ });
}
+
+ /**
+ * Checks the children for frozen nodes. Throws security error if any are found.
+ *
+ * @param assocs
+ */
+ private void checkChildren(List assocs)
+ {
+ for (ChildAssociationRef assoc : assocs)
+ {
+ // we only care about primary children
+ if (assoc.isPrimary() == true)
+ {
+ NodeRef nodeRef = assoc.getChildRef();
+ if (recordsManagementService.isFrozen(nodeRef) == true)
+ {
+ // never allowed to delete a node with a frozen child
+ throw new AccessDeniedException("Can not delete node, because it contains a frozen child node.");
+ }
+
+ // check children
+ checkChildren(nodeService.getChildAssocs(nodeRef));
+ }
+ }
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#isHold(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public boolean isHold(NodeRef nodeRef)
+ {
+ ParameterCheck.mandatory("nodeRef", nodeRef);
+
+ return dictionaryService.isSubClass(nodeService.getType(nodeRef), TYPE_HOLD);
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#isFrozen(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public boolean isFrozen(NodeRef nodeRef)
+ {
+ ParameterCheck.mandatory("nodeRef", nodeRef);
+
+ return nodeService.hasAspect(nodeRef, ASPECT_FROZEN);
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFrozen(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public Set getFrozen(NodeRef hold)
+ {
+ ParameterCheck.mandatory("hold", hold);
+
+ Set frozenNodes = new HashSet();
+ List childAssocs = nodeService.getChildAssocs(hold, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
+ if (childAssocs != null && !childAssocs.isEmpty())
+ {
+ for (ChildAssociationRef childAssociationRef : childAssocs)
+ {
+ frozenNodes.add(childAssociationRef.getChildRef());
+ }
+ }
+ return frozenNodes;
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(java.lang.String, org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public NodeRef freeze(String reason, NodeRef nodeRef)
+ {
+ ParameterCheck.mandatoryString("reason", reason);
+ ParameterCheck.mandatory("nodeRef", nodeRef);
+
+ // Check if the actionedUponNodeRef is a valid file plan component
+ boolean isRecord = recordsManagementService.isRecord(nodeRef);
+ boolean isFolder = recordsManagementService.isRecordFolder(nodeRef);
+
+ if (!(isRecord || isFolder))
+ {
+ throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_FREEZE_ONLY_RECORDS_FOLDERS));
+ }
+
+ // Log a message about freezing the node with the reason
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Freezing node '").append(nodeRef).append("'");
+ if (isFolder)
+ {
+ msg.append(" (folder)");
+ }
+ msg.append(" with reason '").append(reason).append("'.");
+ logger.debug(msg.toString());
+ }
+
+ // Create the hold object
+ NodeRef holdNodeRef = createHold(nodeRef, reason);
+
+ // Freeze the node and add it to the hold
+ freeze(holdNodeRef, nodeRef);
+
+ return holdNodeRef;
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public void freeze(NodeRef hold, NodeRef nodeRef)
+ {
+ ParameterCheck.mandatory("hold", hold);
+ ParameterCheck.mandatory("nodeRef", nodeRef);
+
+ // Link the record to the hold
+ nodeService.addChild(hold, nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
+
+ // Apply the freeze aspect
+ Map props = new HashMap(2);
+ props.put(PROP_FROZEN_AT, new Date());
+ props.put(PROP_FROZEN_BY, AuthenticationUtil.getFullyAuthenticatedUser());
+ nodeService.addAspect(nodeRef, ASPECT_FROZEN, props);
+
+ // Log a message about applying the the frozen aspect
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Frozen aspect applied to '").append(nodeRef).append("'.");
+ logger.debug(msg.toString());
+ }
+
+ // Mark all the folders contents as frozen
+ if (recordsManagementService.isRecordFolder(nodeRef))
+ {
+ List records = recordsManagementService.getRecords(nodeRef);
+ for (NodeRef record : records)
+ {
+ nodeService.addAspect(record, ASPECT_FROZEN, props);
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Frozen aspect applied to '").append(record).append("'.");
+ logger.debug(msg.toString());
+ }
+ }
+ }
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(java.lang.String, java.util.Set)
+ */
+ @Override
+ public NodeRef freeze(String reason, Set nodeRefs)
+ {
+ ParameterCheck.mandatoryString("reason", reason);
+ ParameterCheck.mandatory("nodeRefs", nodeRefs);
+
+ if (nodeRefs.isEmpty())
+ {
+ throw new AlfrescoRuntimeException(MSG_EMPTY_SET_OF_NODEREFS);
+ }
+
+ // FIXME: Can we assume that the nodeRefs are in the same filePlan???
+ NodeRef nodeRef = nodeRefs.iterator().next();
+ NodeRef hold = createHold(nodeRef, reason);
+
+ freeze(hold, nodeRefs);
+
+ return hold;
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(org.alfresco.service.cmr.repository.NodeRef, java.util.Set)
+ */
+ @Override
+ public void freeze(NodeRef hold, Set nodeRefs)
+ {
+ ParameterCheck.mandatory("hold", hold);
+ ParameterCheck.mandatory("nodeRefs", nodeRefs);
+
+ for (NodeRef nodeRef : nodeRefs)
+ {
+ freeze(hold, nodeRef);
+ }
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#unFreeze(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public void unFreeze(NodeRef nodeRef)
+ {
+ ParameterCheck.mandatory("nodeRef", nodeRef);
+
+ if (nodeService.hasAspect(nodeRef, ASPECT_FROZEN))
+ {
+ boolean isRecordFolder = recordsManagementService.isRecordFolder(nodeRef);
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Unfreezing node '").append(nodeRef).append("'");
+ if (isRecordFolder)
+ {
+ msg.append(" (folder)");
+ }
+ msg.append(".");
+ logger.debug(msg.toString());
+ }
+
+ // Remove freeze from node
+ removeFreeze(nodeRef);
+
+ // Remove freeze from records if a record folder
+ if (isRecordFolder)
+ {
+ List records = recordsManagementService.getRecords(nodeRef);
+ for (NodeRef record : records)
+ {
+ removeFreeze(record);
+ }
+ }
+ }
+ else
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("The node '").append(nodeRef).append("' was not frozen. So it cannot be unfrozen!");
+ logger.info(msg.toString());
+ }
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#unFreeze(java.util.Set)
+ */
+ @Override
+ public void unFreeze(Set nodeRefs)
+ {
+ ParameterCheck.mandatory("nodeRefs", nodeRefs);
+
+ for (NodeRef nodeRef : nodeRefs)
+ {
+ unFreeze(nodeRef);
+ }
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#relinquish(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public void relinquish(NodeRef hold)
+ {
+ ParameterCheck.mandatory("hold", hold);
+
+ final NodeRef holdBeingRelinquished = hold;
+ List frozenNodeAssocs = nodeService.getChildAssocs(holdBeingRelinquished, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Relinquishing hold ").append(holdBeingRelinquished)
+ .append(" which has ").append(frozenNodeAssocs.size()).append(" frozen node(s).");
+ logger.debug(msg.toString());
+ }
+
+ for (ChildAssociationRef assoc : frozenNodeAssocs)
+ {
+ final NodeRef nextFrozenNode = assoc.getChildRef();
+
+ // Remove the freeze if this is the only hold that references the node
+ removeFreeze(nextFrozenNode, holdBeingRelinquished);
+ }
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Deleting hold object ").append(holdBeingRelinquished)
+ .append(" with name ").append(nodeService.getProperty(holdBeingRelinquished, ContentModel.PROP_NAME));
+ logger.debug(msg.toString());
+ }
+
+ // Delete the hold node
+ this.nodeService.deleteNode(holdBeingRelinquished);
+ }
+
+ /**
+ * Removes a freeze from a node
+ *
+ * @param nodeRef node reference
+ */
+ private void removeFreeze(NodeRef nodeRef, NodeRef holdBeingRelinquished)
+ {
+ // We should only remove the frozen aspect if there are no other 'holds' in effect for this node.
+ // One complication to consider is that holds can be placed on records or on folders.
+ // Therefore if the nodeRef here is a record, we need to go up the containment hierarchy looking
+ // for holds at each level.
+
+ // Get all the holds and remove this node from them.
+ List parentAssocs = this.nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
+ // If the nodeRef is a record, there could also be applicable holds as parents of the folder(s).
+ if (recordsManagementService.isRecord(nodeRef))
+ {
+ List parentFolders = recordsManagementService.getRecordFolders(nodeRef);
+ for (NodeRef folder : parentFolders)
+ {
+ List moreAssocs = nodeService.getParentAssocs(folder, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
+ parentAssocs.addAll(moreAssocs);
+ }
+ }
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Removing freeze from ").append(nodeRef).append(" which has ")
+ .append(parentAssocs.size()).append(" holds");
+ logger.debug(msg.toString());
+ }
+
+ boolean otherHoldsAreInEffect = false;
+ for (ChildAssociationRef chAssRef : parentAssocs)
+ {
+ if (!chAssRef.getParentRef().equals(holdBeingRelinquished))
+ {
+ otherHoldsAreInEffect = true;
+ break;
+ }
+ }
+
+ if (!otherHoldsAreInEffect)
+ {
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Removing frozen aspect from ").append(nodeRef);
+ logger.debug(msg.toString());
+ }
+
+ // Remove the aspect
+ this.nodeService.removeAspect(nodeRef, ASPECT_FROZEN);
+ }
+
+ // Remove the freezes on the child records as long as there is no other hold referencing them
+ if (this.recordsManagementService.isRecordFolder(nodeRef) == true)
+ {
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append(nodeRef).append(" is a record folder");
+ logger.debug(msg.toString());
+ }
+ for (NodeRef record : recordsManagementService.getRecords(nodeRef))
+ {
+ removeFreeze(record, holdBeingRelinquished);
+ }
+ }
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getReason(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ public String getReason(NodeRef hold)
+ {
+ ParameterCheck.mandatory("hold", hold);
+
+ return (String) nodeService.getProperty(hold, PROP_HOLD_REASON);
+ }
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#updateReason(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
+ */
+ @Override
+ public void updateReason(NodeRef hold, String reason)
+ {
+ ParameterCheck.mandatory("hold", hold);
+ ParameterCheck.mandatoryString("reason", reason);
+
+ nodeService.setProperty(hold, PROP_HOLD_REASON, reason);
+ }
+
+ /**
+ * Creates a hold using the given nodeRef and reason
+ *
+ * @param nodeRef the nodeRef which will be frozen
+ * @param reason the reason why the record will be frozen
+ * @return NodeRef of the created hold
+ */
+ private NodeRef createHold(NodeRef nodeRef, String reason)
+ {
+ NodeRef holdNodeRef = null;
+
+ // Calculate a transfer name
+ QName nodeDbid = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "node-dbid");
+ Long dbId = (Long) nodeService.getProperty(nodeRef, nodeDbid);
+ String transferName = StringUtils.leftPad(dbId.toString(), 10, "0");
+
+ // Create the hold object
+ Map holdProps = new HashMap(2);
+ holdProps.put(ContentModel.PROP_NAME, transferName);
+ holdProps.put(PROP_HOLD_REASON, reason);
+
+ // Get the root rm node
+ NodeRef root = recordsManagementService.getFilePlan(nodeRef);
+ final QName transferQName = QName.createQName(RM_URI, transferName);
+ holdNodeRef = nodeService.createNode(root, ASSOC_HOLDS, transferQName, TYPE_HOLD, holdProps).getChildRef();
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Created hold object ").append(holdNodeRef)
+ .append(" with transfer name ").append(transferQName);
+ logger.debug(msg.toString());
+ }
+
+ // Bind the hold node reference to the transaction
+ AlfrescoTransactionSupport.bindResource(KEY_HOLD_NODEREF, holdNodeRef);
+
+ return holdNodeRef;
+ }
+
+ /**
+ * Removes a freeze from a node. The unfrozen node is automatically removed from the hold(s) it is in.
+ * If the hold is subsequently empty, the hold is automatically deleted.
+ *
+ * @param nodeRef node reference
+ */
+ private void removeFreeze(NodeRef nodeRef)
+ {
+ // Get all the holds and remove this node from them
+ List assocs = nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Removing freeze from node '").append(nodeRef)
+ .append("' which has '").append(assocs.size()).append("' holds.");
+ logger.debug(msg.toString());
+ }
+
+ for (ChildAssociationRef assoc : assocs)
+ {
+ // Remove the frozen node as a child
+ NodeRef holdNodeRef = assoc.getParentRef();
+ nodeService.removeChild(holdNodeRef, nodeRef);
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Removed frozen node from hold '").append(holdNodeRef).append("'.");
+ logger.debug(msg.toString());
+ }
+
+ // Check to see if we should delete the hold
+ List holdAssocs = nodeService.getChildAssocs(holdNodeRef, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL);
+ if (holdAssocs != null && holdAssocs.isEmpty())
+ {
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Hold node '").append(holdNodeRef)
+ .append("' with name '").append(nodeService.getProperty(holdNodeRef, ContentModel.PROP_NAME))
+ .append("' has no frozen nodes. Hence deleting it.");
+ logger.debug(msg.toString());
+ }
+
+ // Delete the hold object
+ nodeService.deleteNode(holdNodeRef);
+ }
+ }
+
+ // Remove the aspect
+ this.nodeService.removeAspect(nodeRef, ASPECT_FROZEN);
+
+ if (logger.isDebugEnabled())
+ {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Removed frozen aspect from ").append(nodeRef);
+ logger.debug(msg.toString());
+ }
+ }
}