diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml index 9429d9194a..fceb2d0549 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml @@ -77,6 +77,7 @@ + HOLD RECORD_FOLDER RECORD @@ -96,6 +97,7 @@ + HOLD RECORD_FOLDER RECORD 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 65f9af3a2d..43c6458641 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 @@ -1639,9 +1639,9 @@ + parent="baseService" + class="org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImpl"> - @@ -1649,7 +1649,7 @@ - org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService + org.alfresco.module.org_alfresco_module_rm.hold.HoldService @@ -1669,12 +1669,21 @@ 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 7560e1bb4a..e755bbc4c5 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 @@ -41,6 +41,7 @@ public class EditHoldReasonAction extends RMActionExecuterAbstractBase /** * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) */ + @SuppressWarnings("deprecation") @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { 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 429c5749e2..93742fa54d 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 @@ -50,6 +50,7 @@ public class FreezeAction extends RMActionExecuterAbstractBase /** * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) */ + @SuppressWarnings("deprecation") @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { 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 17a90807fb..66b889f9be 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 @@ -37,6 +37,7 @@ public class RelinquishHoldAction extends RMActionExecuterAbstractBase /** * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) */ + @SuppressWarnings("deprecation") @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { 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 b5b30458a2..add6985e76 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 @@ -32,6 +32,7 @@ public class UnfreezeAction extends RMActionExecuterAbstractBase /** * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) */ + @SuppressWarnings("deprecation") @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java index ce38003079..dceab388e5 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java @@ -159,4 +159,8 @@ public interface RMPermissionModel String MAP_CLASSIFICATION_GUIDE_METADATA = "MapClassificationGuideMetadata"; String MANAGE_ACCESS_CONTROLS = "ManageAccessControls"; + + final String CREATE_HOLD = "CreateHold"; + final String ADD_TO_HOLD = "AddToHold"; + final String REMOVE_FROM_HOLD = "RemoveFromHold"; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java index 9bbe2150e5..9eeb586982 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java @@ -161,6 +161,10 @@ public class CreateCapability extends DeclarativeCapability { return AccessDecisionVoter.ACCESS_GRANTED; } + if (capabilityService.getCapability(RMPermissionModel.ADD_TO_HOLD).evaluate(destination) == AccessDecisionVoter.ACCESS_GRANTED) + { + return AccessDecisionVoter.ACCESS_GRANTED; + } if (((ChangeOrDeleteReferencesCapability)capabilityService.getCapability(RMPermissionModel.CHANGE_OR_DELETE_REFERENCES)).evaluate(destination, linkee) == AccessDecisionVoter.ACCESS_GRANTED) { return AccessDecisionVoter.ACCESS_GRANTED; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java index b07518d500..e411d87d1c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java @@ -30,7 +30,6 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; @@ -157,14 +156,6 @@ public class FilePlanServiceImpl extends ServiceBaseImpl return (RecordFolderService)applicationContext.getBean("RecordFolderService"); } - /** - * @return freeze service - */ - protected FreezeService getFreezeService() - { - return (FreezeService)applicationContext.getBean("FreezeService"); - } - /** * @return transfer service */ @@ -218,7 +209,7 @@ public class FilePlanServiceImpl extends ServiceBaseImpl { result = FilePlanComponentKind.HOLD_CONTAINER; } - else if (getFreezeService().isHold(nodeRef)) + else if (isHold(nodeRef)) { result = FilePlanComponentKind.HOLD; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/hold/HoldServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/hold/HoldServiceImpl.java deleted file mode 100644 index a855eda2f9..0000000000 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/hold/HoldServiceImpl.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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.fileplan.hold; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -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.fileplan.FilePlanService; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.module.org_alfresco_module_rm.record.RecordService; -import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -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.QName; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.util.ParameterCheck; -import org.apache.commons.collections.ListUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Hold service implementation - * - * @author Tuna Aksoy - * @since 2.2 - */ -public class HoldServiceImpl implements HoldService, RecordsManagementModel -{ - /** Logger */ - private static Log logger = LogFactory.getLog(HoldServiceImpl.class); - - /** File Plan Service */ - private FilePlanService filePlanService; - - /** Node Service */ - private NodeService nodeService; - - /** Record Service */ - private RecordService recordService; - - /** Record Folder Service */ - private RecordFolderService recordFolderService; - - /** - * Set the file plan service - * - * @param filePlanService the file plan service - */ - public void setFilePlanService(FilePlanService filePlanService) - { - this.filePlanService = filePlanService; - } - - /** - * Set the node service - * - * @param nodeService the node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * Set the record service - * - * @param recordService the record service - */ - public void setRecordService(RecordService recordService) - { - this.recordService = recordService; - } - - /** - * Set the record folder service - * - * @param recordFolderService the record folder service - */ - public void setRecordFolderService(RecordFolderService recordFolderService) - { - this.recordFolderService = recordFolderService; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService#getHolds(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public List getHolds(NodeRef filePlan) - { - ParameterCheck.mandatory("filePlan", filePlan); - - NodeRef holdContainer = filePlanService.getHoldContainer(filePlan); - List holdsAssocs = nodeService.getChildAssocs(holdContainer, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); - List holds = new ArrayList(holdsAssocs.size()); - for (ChildAssociationRef holdAssoc : holdsAssocs) - { - holds.add(holdAssoc.getChildRef()); - } - - return holds; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService#getHolds(org.alfresco.service.cmr.repository.NodeRef, boolean) - */ - @Override - public List getHolds(NodeRef nodeRef, boolean includedInHold) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - List result = new ArrayList(); - - List holdsAssocs = nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS); - List holdsNotIncludingNodeRef = new ArrayList(holdsAssocs.size()); - for (ChildAssociationRef holdAssoc : holdsAssocs) - { - holdsNotIncludingNodeRef.add(holdAssoc.getParentRef()); - } - result.addAll(holdsNotIncludingNodeRef); - - if (!includedInHold) - { - NodeRef filePlan = filePlanService.getFilePlan(nodeRef); - List allHolds = getHolds(filePlan); - @SuppressWarnings("unchecked") - List holdsIncludingNodeRef = ListUtils.subtract(allHolds, holdsNotIncludingNodeRef); - result.clear(); - result.addAll(holdsIncludingNodeRef); - } - - return result; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService#addToHoldContainer(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public void addToHoldContainer(NodeRef hold, NodeRef nodeRef) - { - ParameterCheck.mandatory("hold", hold); - ParameterCheck.mandatory("nodeRef", nodeRef); - - List holds = new ArrayList(1); - holds.add(hold); - addToHoldContainers(Collections.unmodifiableList(holds), nodeRef); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService#addToHoldContainers(java.util.List, org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public void addToHoldContainers(List holds, NodeRef nodeRef) - { - ParameterCheck.mandatoryCollection("holds", holds); - ParameterCheck.mandatory("nodeRef", nodeRef); - - for (NodeRef hold : holds) - { - // Link the record to the hold - nodeService.addChild(hold, nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS); - - Map props = new HashMap(2); - // Apply the freeze aspect - props.put(PROP_FROZEN_AT, new Date()); - props.put(PROP_FROZEN_BY, AuthenticationUtil.getFullyAuthenticatedUser()); - - if (!nodeService.hasAspect(nodeRef, ASPECT_FROZEN)) - { - nodeService.addAspect(nodeRef, ASPECT_FROZEN, props); - - 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 (recordFolderService.isRecordFolder(nodeRef)) - { - List records = recordService.getRecords(nodeRef); - for (NodeRef record : records) - { - // no need to freeze if already frozen! - if (!nodeService.hasAspect(record, ASPECT_FROZEN)) - { - 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.fileplan.hold.HoldService#removeFromHoldContainer(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public void removeFromHoldContainer(NodeRef hold, NodeRef nodeRef) - { - ParameterCheck.mandatory("hold", hold); - ParameterCheck.mandatory("nodeRef", nodeRef); - - List holds = new ArrayList(1); - holds.add(hold); - removeFromHoldContainers(Collections.unmodifiableList(holds), nodeRef); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService#removeFromHoldContainers(java.util.List, org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public void removeFromHoldContainers(List holds, NodeRef nodeRef) - { - ParameterCheck.mandatory("holds", holds); - ParameterCheck.mandatory("nodeRef", nodeRef); - - for (NodeRef hold : holds) - { - nodeService.removeChild(hold, nodeRef); - } - - List holdList = getHolds(nodeRef, true); - if (holdList.size() == 0) - { - nodeService.removeAspect(nodeRef, ASPECT_FROZEN); - } - } -} 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 415b821990..23dd11cd02 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 @@ -21,160 +21,118 @@ package org.alfresco.module.org_alfresco_module_rm.freeze; import java.util.Date; import java.util.Set; -import org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.service.cmr.repository.NodeRef; /** * Freeze Service Interface * - * TODO - * Implementation used to consolidate freeze behaviours in 2.0. - * When implementing consider application of freeze to 'any' node references, not just records and record folders. - * (Consider implications for security and capabilities) - * * @author Roy Wetherall * @since 2.0 */ public interface FreezeService { + /** + * Indicates whether the passed node reference is frozen. + * + * @param nodeRef node reference + * @return boolean true if frozen, false otherwise + */ + boolean isFrozen(NodeRef nodeRef); + + /** + * Checks whether or not the given node has frozen children + * + * @param nodeRef The nodeRef for which will be checked if it has frozen children + * @return true if the given nodeRef has frozen children, false otherwise + */ + boolean hasFrozenChildren(NodeRef nodeRef); + + /** + * Gets the date of the freeze for the given node, null if the node is not frozen + * + * @param nodeRef The nodeRef for which the date check will be performed + * @return Date The of the freeze or null + */ + Date getFreezeDate(NodeRef nodeRef); + + /** + * Gets the initiator of the freeze for the given node, null if the node is not frozen + * + * @param nodeRef The nodeRef for which the initiator check will be performed + * @return String The initiator of the freeze or null + */ + String getFreezeInitiator(NodeRef nodeRef); + /** - * Indicates whether the passed node reference is a hold. A hold is a container for a group of frozen object and contains the freeze - * reason. - * - * @param nodeRef hold node reference - * @return boolean true if hold, false otherwise + * @deprecated as of 2.2, use {@link HoldService#isHold(NodeRef)} instead. */ - boolean isHold(NodeRef nodeRef); + @Deprecated + boolean isHold(NodeRef nodeRef); /** - * Indicates whether the passed node reference is frozen. - * - * @param nodeRef node reference - * @return boolean true if frozen, false otherwise - */ - boolean isFrozen(NodeRef nodeRef); - - /** - * Get the 'root' frozen node references in a hold. - * - * @param hold hold node reference - * @return Set frozen node references + * @deprecated as of 2.2, use {@link HoldService#getHeld(NodeRef)} instead. */ + @Deprecated Set getFrozen(NodeRef hold); /** - * Freezes a node with the provided reason, creating a hold node reference. - * - * @param reason freeze reason - * @param nodeRef node reference - * @return NodeRef hold node reference + * @deprecated as of 2.2, use {@link HoldService#createHold(NodeRef, String, String, String)} and {@link HoldService#addToHold(NodeRef, NodeRef)} instead. */ + @Deprecated NodeRef freeze(String reason, NodeRef nodeRef); /** - * Freezes a node, adding it an existing hold. - * - * @param hold hold node reference - * @param nodeRef node reference - * - * @deprecated as of 2.2, use {@link HoldService#addToHoldContainer(NodeRef, NodeRef)} instead + * @deprecated as of 2.2, use {@link HoldService#addToHold(NodeRef, NodeRef)} instead. */ @Deprecated void freeze(NodeRef hold, NodeRef nodeRef); /** - * Freezes a collection of nodes with the given reason, creating a hold. - * - * @param reason freeze reason - * @param nodeRefs set of nodes to freeze - * @return NodeRef hold node reference + * @deprecated as of 2.2, use {@link HoldService#createHold(NodeRef, String, String, String)} and {@link HoldService#addToHold(NodeRef, List)} instead. */ + @Deprecated NodeRef freeze(String reason, Set nodeRefs); /** - * Freeze a collection of nodes, adding them to an existing hold. - * - * @param hold hold node reference - * @param nodeRefs set of nodes to freeze + * @deprecated as of 2.2, use {@link HoldService#addToHold(NodeRef, List)} instead. */ + @Deprecated void freeze(NodeRef hold, Set nodeRefs); /** - * Unfreeze a frozen 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 + * @deprecated as of 2.2, use {@link HoldService#removeFromHold(NodeRef, NodeRef)} instead. */ + @Deprecated void unFreeze(NodeRef nodeRef); /** - * Unfreeze a collection of nodes. - *

- * 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 nodeRefs set of nodes to unfreeze + * @deprecated as of 2.2, use {@link HoldService#removeFromHolds(java.util.List, NodeRef)} instead. */ + @Deprecated void unFreeze(Set nodeRefs); /** - * Unfreezes all nodes within a hold and deletes the hold. - * - * @param hold hold node reference + * @deprecated as of 2.2, use {@link HoldService#deleteHold(NodeRef)} instead. */ + @Deprecated void relinquish(NodeRef hold); /** - * Gets the freeze reason for a hold. - * - * @param hold hold node reference - * @return String freeze reason + * @deprecated as of 2.2, use {@link HoldService#getHoldReason(NodeRef)} instead. */ + @Deprecated String getReason(NodeRef hold); /** - * Updates the freeze reason for a given hold. - * - * @param hold hold node reference - * @param reason updated reason + * @deprecated as of 2.2, use {@link HoldService#setHoldReason(NodeRef, String)} instead. */ + @Deprecated void updateReason(NodeRef hold, String reason); /** - * Gets the hold node references for a given file plan - * or an empty set if there is not any hold node available - * - * @param filePlan file plan for which the hold nodes will be retrieved - * @return Set hold node references - * - * @deprecated as of 2.2, use {@link HoldService#getHolds(NodeRef)} instead + * @deprecated as of 2.2, use {@link HoldService#getHolds(NodeRef)} instead. */ @Deprecated Set getHolds(NodeRef filePlan); - - /** - * Checks whether or not the given node has frozen children - * - * @param nodeRef The nodeRef for which will be checked if it has frozen children - * @return true if the given nodeRef has frozen children, false otherwise - */ - boolean hasFrozenChildren(NodeRef nodeRef); - - /** - * Gets the date of the freeze for the given node, null if the node is not frozen - * - * @param nodeRef The nodeRef for which the date check will be performed - * @return Date The of the freeze or null - */ - Date getFreezeDate(NodeRef nodeRef); - - /** - * Gets the initiator of the freeze for the given node, null if the node is not frozen - * - * @param nodeRef The nodeRef for which the initiator check will be performed - * @return String The initiator of the freeze or null - */ - String getFreezeInitiator(NodeRef nodeRef); } 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 e93cbdbb96..cf8899c0ae 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 @@ -19,25 +19,21 @@ package org.alfresco.module.org_alfresco_module_rm.freeze; import java.io.Serializable; +import java.util.ArrayList; 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.fileplan.FilePlanService; -import org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; 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.alfresco.util.ParameterCheck; import org.apache.commons.lang.StringUtils; @@ -57,15 +53,13 @@ public class FreezeServiceImpl extends ServiceBaseImpl RecordsManagementModel { /** Logger */ + @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(FreezeServiceImpl.class); /** I18N */ - private static final String MSG_FREEZE_ONLY_RECORDS_FOLDERS = "rm.action.freeze-only-records-folders"; + //private static final String MSG_FREEZE_ONLY_RECORDS_FOLDERS = "rm.action.freeze-only-records-folders"; private static final String MSG_HOLD_NAME = "rm.hold.name"; - /** Hold node reference key */ - private static final String KEY_HOLD_NODEREF = "holdNodeRef"; - /** Record service */ protected RecordService recordService; @@ -110,25 +104,6 @@ public class FreezeServiceImpl extends ServiceBaseImpl this.holdService = holdService; } - /** - * @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); - - QName type = nodeService.getType(nodeRef); - if (nodeService.exists(nodeRef) && (TYPE_HOLD.equals(type)) || dictionaryService.isSubClass(type, TYPE_HOLD)) - { - return true; - } - else - { - return false; - } - } - /** * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#isFrozen(org.alfresco.service.cmr.repository.NodeRef) */ @@ -140,250 +115,6 @@ public class FreezeServiceImpl extends ServiceBaseImpl 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); - - // FIXME: Should we consider only records and record folders or 'any' - // node references - // Check if the actionedUponNodeRef is a valid file plan component - boolean isRecord = recordService.isRecord(nodeRef); - boolean isFolder = recordFolderService.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); - - holdService.addToHoldContainer(hold, nodeRef); - } - - /** - * @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.mandatoryCollection("nodeRefs", 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.mandatoryCollection("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 = recordFolderService.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 = recordService.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.mandatoryCollection("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); - - List frozenNodeAssocs = nodeService.getChildAssocs(hold, ASSOC_FROZEN_RECORDS, - RegexQNamePattern.MATCH_ALL); - - if (logger.isDebugEnabled()) - { - StringBuilder msg = new StringBuilder(); - msg.append("Relinquishing hold '").append(hold).append("' which has '").append(frozenNodeAssocs.size()) - .append("' frozen node(s)."); - logger.debug(msg.toString()); - } - - for (ChildAssociationRef assoc : frozenNodeAssocs) - { - // Remove the freeze if this is the only hold that references the - // node - removeFreeze(assoc.getChildRef(), hold); - } - - if (logger.isDebugEnabled()) - { - StringBuilder msg = new StringBuilder(); - msg.append("Deleting hold object '").append(hold).append("' with name '").append( - nodeService.getProperty(hold, ContentModel.PROP_NAME)).append("'."); - logger.debug(msg.toString()); - } - - // Delete the hold node - nodeService.deleteNode(hold); - } - - /** - * @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); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getHold(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public Set getHolds(NodeRef filePlan) - { - ParameterCheck.mandatory("filePlan", filePlan); - - return new HashSet(holdService.getHolds(filePlan)); - } - /** * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef) */ @@ -403,8 +134,8 @@ public class FreezeServiceImpl extends ServiceBaseImpl } return false; - } - + } + /** * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef) */ @@ -438,10 +169,153 @@ public class FreezeServiceImpl extends ServiceBaseImpl return null; } + + /** + * Deprecated Method Implementations + */ /** - * Helper Methods + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFrozen(org.alfresco.service.cmr.repository.NodeRef) */ + @Override + @Deprecated + public Set getFrozen(NodeRef hold) + { + return new HashSet(holdService.getHeld(hold)); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(java.lang.String, + * org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Deprecated + public NodeRef freeze(String reason, NodeRef nodeRef) + { + NodeRef hold = createHold(nodeRef, reason); + holdService.addToHold(hold, nodeRef); + return hold; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(org.alfresco.service.cmr.repository.NodeRef, + * org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Deprecated + public void freeze(NodeRef hold, NodeRef nodeRef) + { + ParameterCheck.mandatory("hold", hold); + ParameterCheck.mandatory("nodeRef", nodeRef); + + holdService.addToHold(hold, nodeRef); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(java.lang.String, + * java.util.Set) + */ + @Override + @Deprecated + public NodeRef freeze(String reason, Set nodeRefs) + { + NodeRef hold = null; + if (!nodeRefs.isEmpty()) + { + List list = new ArrayList(nodeRefs); + hold = createHold(list.get(0), reason); + holdService.addToHold(hold, list); + } + return hold; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#freeze(org.alfresco.service.cmr.repository.NodeRef, + * java.util.Set) + */ + @Override + @Deprecated + public void freeze(NodeRef hold, Set nodeRefs) + { + ParameterCheck.mandatory("hold", hold); + ParameterCheck.mandatoryCollection("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 + @Deprecated + public void unFreeze(NodeRef nodeRef) + { + List holds = holdService.heldBy(nodeRef, true); + for (NodeRef hold : holds) + { + holdService.removeFromHold(hold, nodeRef); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#unFreeze(java.util.Set) + */ + @Override + @Deprecated + public void unFreeze(Set nodeRefs) + { + ParameterCheck.mandatoryCollection("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 + @Deprecated + public void relinquish(NodeRef hold) + { + holdService.deleteHold(hold); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getReason(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Deprecated + public String getReason(NodeRef hold) + { + return holdService.getHoldReason(hold); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#updateReason(org.alfresco.service.cmr.repository.NodeRef, + * java.lang.String) + */ + @Override + @Deprecated + public void updateReason(NodeRef hold, String reason) + { + holdService.setHoldReason(hold, reason); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getHold(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public Set getHolds(NodeRef filePlan) + { + ParameterCheck.mandatory("filePlan", filePlan); + + return new HashSet(holdService.getHolds(filePlan)); + } /** * Creates a hold using the given nodeRef and reason @@ -453,177 +327,14 @@ public class FreezeServiceImpl extends ServiceBaseImpl private NodeRef createHold(NodeRef nodeRef, String reason) { // get the hold container - final NodeRef root = filePlanService.getFilePlan(nodeRef); - NodeRef holdContainer = filePlanService.getHoldContainer(root); + final NodeRef filePlan = filePlanService.getFilePlan(nodeRef); + NodeRef holdContainer = filePlanService.getHoldContainer(filePlan); // calculate the hold name int nextCount = getNextCount(holdContainer); String holdName = I18NUtil.getMessage(MSG_HOLD_NAME) + " " + StringUtils.leftPad(Integer.toString(nextCount), 10, "0"); - // Create the properties for the hold object - Map holdProps = new HashMap(2); - holdProps.put(ContentModel.PROP_NAME, holdName); - holdProps.put(PROP_HOLD_REASON, reason); - - // create the hold object - QName holdQName = QName.createQName(RM_URI, holdName); - final NodeRef holdNodeRef = nodeService.createNode(holdContainer, ContentModel.ASSOC_CONTAINS, holdQName, TYPE_HOLD, holdProps).getChildRef(); - - if (logger.isDebugEnabled()) - { - StringBuilder msg = new StringBuilder(); - msg.append("Created hold object '").append(holdNodeRef).append("' with name '").append(holdQName).append("'."); - 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 '").append(nodeRef).append("' 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 - nodeService.removeAspect(nodeRef, ASPECT_FROZEN); - - if (logger.isDebugEnabled()) - { - StringBuilder msg = new StringBuilder(); - msg.append("Removed frozen aspect from '").append(nodeRef).append("'."); - logger.debug(msg.toString()); - } - } - - /** - * Removes a freeze from a node from the given hold - * - * @param nodeRef node reference - * @param hold hold - */ - private void removeFreeze(NodeRef nodeRef, NodeRef hold) - { - // 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 = 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 (recordService.isRecord(nodeRef)) - { - List parentFolders = recordFolderService.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(hold)) - { - 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 - nodeService.removeAspect(nodeRef, ASPECT_FROZEN); - } - - // Remove the freezes on the child records as long as there is no other - // hold referencing them - if (recordFolderService.isRecordFolder(nodeRef)) - { - if (logger.isDebugEnabled()) - { - StringBuilder msg = new StringBuilder(); - msg.append(nodeRef).append(" is a record folder"); - logger.debug(msg.toString()); - } - for (NodeRef record : recordService.getRecords(nodeRef)) - { - removeFreeze(record, hold); - } - } - } + // create hold + return holdService.createHold(filePlan, holdName, reason, null); + } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/hold/HoldService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldService.java similarity index 56% rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/hold/HoldService.java rename to rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldService.java index 7f1298ecbe..707b30f3f3 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/hold/HoldService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldService.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.fileplan.hold; +package org.alfresco.module.org_alfresco_module_rm.hold; import java.util.List; @@ -30,6 +30,15 @@ import org.alfresco.service.cmr.repository.NodeRef; */ public interface HoldService { + /** + * Indicates whether the passed node reference is a hold. A hold is a container for a group of frozen object and contains the freeze + * reason. + * + * @param nodeRef hold node reference + * @return boolean true if hold, false otherwise + */ + boolean isHold(NodeRef nodeRef); + /** * Gets the list of all the holds within the holds container in the given file plan * @@ -38,6 +47,13 @@ public interface HoldService */ List getHolds(NodeRef filePlan); + /** + * + * @param name + * @return + */ + NodeRef getHold(NodeRef filePlan, String name); + /** * Gets the list of all the holds within the holds container for the given node reference * @@ -46,15 +62,59 @@ public interface HoldService * false to get a list of node references which will not have the given node reference * @return List of hold node references */ - List getHolds(NodeRef nodeRef, boolean includedInHold); - + List heldBy(NodeRef nodeRef, boolean includedInHold); + + /** + * + * @param ndoeRef + * @return + */ + List getHeld(NodeRef hold); + + /** + * + * @param filePlan + * @param name + * @param reason + * @param description + * @return + */ + NodeRef createHold(NodeRef filePlan, String name, String reason, String description); + + /** + * + * @param hold + * @return + */ + String getHoldReason(NodeRef hold); + + /** + * + * @param hold + * @param reason + */ + void setHoldReason(NodeRef hold, String reason); + + /** + * + * @param hold + */ + void deleteHold(NodeRef hold); + /** * Adds the record to the given hold * * @param hold The {@link NodeRef} of the hold * @param nodeRef The {@link NodeRef} of the record / record folder which will be added to the given hold */ - void addToHoldContainer(NodeRef hold, NodeRef nodeRef); + void addToHold(NodeRef hold, NodeRef nodeRef); + + /** + * + * @param hold + * @param nodeRefs + */ + void addToHold(NodeRef hold, List nodeRefs); /** * Adds the record to the given list of holds @@ -62,7 +122,7 @@ public interface HoldService * @param holds The list of {@link NodeRef}s of the holds * @param nodeRef The {@link NodeRef} of the record / record folder which will be added to the given holds */ - void addToHoldContainers(List holds, NodeRef nodeRef); + void addToHolds(List holds, NodeRef nodeRef); /** * Removes the record from the given hold @@ -70,7 +130,14 @@ public interface HoldService * @param hold The {@link NodeRef} of the hold * @param nodeRef The {@link NodeRef} of the record / record folder which will be removed from the given hold */ - void removeFromHoldContainer(NodeRef hold, NodeRef nodeRef); + void removeFromHold(NodeRef hold, NodeRef nodeRef); + + /** + * + * @param hold + * @param nodeRefs + */ + void removeFromHold(NodeRef hold, List nodeRefs); /** * Removes the record from the given list of hold @@ -78,5 +145,17 @@ public interface HoldService * @param holds The list {@link NodeRef}s of the holds * @param nodeRef The {@link NodeRef} of the record / record folder which will be removed from the given holds */ - void removeFromHoldContainers(List holds, NodeRef nodeRef); + void removeFromHolds(List holds, NodeRef nodeRef); + + /** + * + * @param nodeRef + */ + void removeFromAllHolds(NodeRef nodeRef); + + /** + * + * @param nodeRefs + */ + void removeFromAllHolds(List nodeRefs); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java new file mode 100644 index 0000000000..01f9232b41 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java @@ -0,0 +1,558 @@ +/* + * 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.hold; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +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.fileplan.FilePlanService; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; +import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +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.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.collections.ListUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Hold service implementation + * + * @author Tuna Aksoy + * @since 2.2 + */ +@BehaviourBean +public class HoldServiceImpl extends ServiceBaseImpl + implements HoldService, + NodeServicePolicies.BeforeDeleteNodePolicy, + RecordsManagementModel +{ + /** Logger */ + private static Log logger = LogFactory.getLog(HoldServiceImpl.class); + + /** File Plan Service */ + private FilePlanService filePlanService; + + /** Record Service */ + private RecordService recordService; + + /** Record folder service */ + private RecordFolderService recordFolderService; + + /** + * Set the file plan service + * + * @param filePlanService the file plan service + */ + public void setFilePlanService(FilePlanService filePlanService) + { + this.filePlanService = filePlanService; + } + + /** + * Set the node service + * + * @param nodeService the node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * Set the record service + * + * @param recordService the record service + */ + public void setRecordService(RecordService recordService) + { + this.recordService = recordService; + } + + /** + * Set the record folder service + * + * @param recordFolderService the record folder service + */ + public void setRecordFolderService(RecordFolderService recordFolderService) + { + this.recordFolderService = recordFolderService; + } + + /** + * Behaviour unfreezes node's that will no longer he held after delete. + * + * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef) + */ + @Behaviour(kind=BehaviourKind.CLASS, type="rma:hold", notificationFrequency=NotificationFrequency.EVERY_EVENT) + @Override + public void beforeDeleteNode(final NodeRef hold) + { + if (nodeService.exists(hold) && isHold(hold)) + { + RunAsWork work = new RunAsWork() + { + @Override + public Void doWork() + { + List frozenNodes = getHeld(hold); + for (NodeRef frozenNode : frozenNodes) + { + List otherHolds = heldBy(frozenNode, true); + if (otherHolds.size() == 1) + { + // remove the freeze aspect from the node + nodeService.removeAspect(frozenNode, ASPECT_FROZEN); + + if (isRecordFolder(frozenNode)) + { + List records = recordService.getRecords(frozenNode); + for (NodeRef record : records) + { + if (nodeService.hasAspect(record, ASPECT_FROZEN)) + { + List recordsOtherHolds = heldBy(record, true); + if (recordsOtherHolds.size() == 1) + { + // remove the freeze aspect from the node + nodeService.removeAspect(record, ASPECT_FROZEN); + } + } + } + } + } + } + + return null; + } + }; + + // run as system user + runAsSystem(work); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#getHolds(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public List getHolds(NodeRef filePlan) + { + ParameterCheck.mandatory("filePlan", filePlan); + + // get the root hold container + NodeRef holdContainer = filePlanService.getHoldContainer(filePlan); + + // get the children of the root hold container + List holdsAssocs = nodeService.getChildAssocs(holdContainer, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + List holds = new ArrayList(holdsAssocs.size()); + for (ChildAssociationRef holdAssoc : holdsAssocs) + { + NodeRef hold = holdAssoc.getChildRef(); + if (isHold(hold)) + { + // add to list of holds + holds.add(hold); + } + } + + return holds; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#heldBy(org.alfresco.service.cmr.repository.NodeRef, boolean) + */ + @SuppressWarnings("unchecked") + @Override + public List heldBy(NodeRef nodeRef, boolean includedInHold) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + List result = null; + + // get all the immediate parent holds + Set holdsNotIncludingNodeRef = getParentHolds(nodeRef); + + // check whether the record is held by vitue of it's record folder + if (isRecord(nodeRef)) + { + List recordFolders = recordFolderService.getRecordFolders(nodeRef); + for (NodeRef recordFolder : recordFolders) + { + holdsNotIncludingNodeRef.addAll(getParentHolds(recordFolder)); + } + } + + if (!includedInHold) + { + // invert list to get list of holds that do not contain this node + NodeRef filePlan = filePlanService.getFilePlan(nodeRef); + List allHolds = getHolds(filePlan); + result = ListUtils.subtract(allHolds, new ArrayList(holdsNotIncludingNodeRef)); + } + else + { + result = new ArrayList(holdsNotIncludingNodeRef); + } + + return result; + } + + /** + * Helper method to get holds that are direct parents of the given node. + * + * @param nodeRef node reference + * @return Set<{@link NodeRef}> set of parent holds + */ + private Set getParentHolds(NodeRef nodeRef) + { + List holdsAssocs = nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS); + Set holds = new HashSet(holdsAssocs.size()); + for (ChildAssociationRef holdAssoc : holdsAssocs) + { + holds.add(holdAssoc.getParentRef()); + } + + return holds; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#getHold(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) + */ + @Override + public NodeRef getHold(NodeRef filePlan, String name) + { + ParameterCheck.mandatory("filePlan", filePlan); + ParameterCheck.mandatory("name", name); + + // get the root hold container + NodeRef holdContainer = filePlanService.getHoldContainer(filePlan); + + // get the hold by name + NodeRef hold = nodeService.getChildByName(holdContainer, ContentModel.ASSOC_CONTAINS, name); + if (hold != null && !isHold(hold)) + { + throw new AlfrescoRuntimeException("Can not get hold, because the named node reference isn't a hold."); + } + + return hold; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#getHeld(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public List getHeld(NodeRef hold) + { + ParameterCheck.mandatory("hold", hold); + List children = new ArrayList(); + + if (nodeService.exists(hold) && isHold(hold)) + { + List childAssocs = nodeService.getChildAssocs(hold, ASSOC_FROZEN_RECORDS, RegexQNamePattern.MATCH_ALL); + if (childAssocs != null && !childAssocs.isEmpty()) + { + for (ChildAssociationRef childAssociationRef : childAssocs) + { + children.add(childAssociationRef.getChildRef()); + } + } + } + + return children; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#createHold(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public NodeRef createHold(NodeRef filePlan, String name, String reason, String description) + { + ParameterCheck.mandatory("filePlan", filePlan); + ParameterCheck.mandatory("name", name); + ParameterCheck.mandatory("reason", reason); + + // get the root hold container + NodeRef holdContainer = filePlanService.getHoldContainer(filePlan); + + // create map of properties + Map properties = new HashMap(3); + properties.put(ContentModel.PROP_NAME, name); + properties.put(PROP_HOLD_REASON, reason); + if (description != null && !description.isEmpty()) + { + properties.put(ContentModel.PROP_DESCRIPTION, description); + } + + // create assoc name + QName assocName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name); + + // create hold + ChildAssociationRef childAssocRef = nodeService.createNode(holdContainer, ContentModel.ASSOC_CONTAINS, assocName, TYPE_HOLD, properties); + + return childAssocRef.getChildRef(); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#getHoldReason(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public String getHoldReason(NodeRef hold) + { + ParameterCheck.mandatory("hold", hold); + + String reason = null; + + if (nodeService.exists(hold) && isHold(hold)) + { + // get the reason + reason = (String)nodeService.getProperty(hold, PROP_HOLD_REASON); + } + + return reason; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#setHoldReason(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) + */ + @Override + public void setHoldReason(NodeRef hold, String reason) + { + ParameterCheck.mandatory("hold", hold); + ParameterCheck.mandatory("reason", reason); + + if (nodeService.exists(hold) && isHold(hold)) + { + nodeService.setProperty(hold, PROP_HOLD_REASON, reason); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#deleteHold(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void deleteHold(NodeRef hold) + { + ParameterCheck.mandatory("hold", hold); + + if (nodeService.exists(hold) && isHold(hold)) + { + // delete the hold node + nodeService.deleteNode(hold); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#addToHold(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void addToHold(NodeRef hold, NodeRef nodeRef) + { + ParameterCheck.mandatory("hold", hold); + ParameterCheck.mandatory("nodeRef", nodeRef); + + List holds = new ArrayList(1); + holds.add(hold); + addToHolds(Collections.unmodifiableList(holds), nodeRef); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#addToHold(org.alfresco.service.cmr.repository.NodeRef, java.util.List) + */ + @Override + public void addToHold(NodeRef hold, List nodeRefs) + { + ParameterCheck.mandatory("hold", hold); + ParameterCheck.mandatory("nodeRefs", nodeRefs); + + for (NodeRef nodeRef : nodeRefs) + { + addToHold(hold, nodeRef); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#addToHolds(java.util.List, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void addToHolds(List holds, NodeRef nodeRef) + { + ParameterCheck.mandatoryCollection("holds", holds); + ParameterCheck.mandatory("nodeRef", nodeRef); + + for (NodeRef hold : holds) + { + // Link the record to the hold + nodeService.addChild(hold, nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS); + + // gather freeze properties + Map props = new HashMap(2); + props.put(PROP_FROZEN_AT, new Date()); + props.put(PROP_FROZEN_BY, AuthenticationUtil.getFullyAuthenticatedUser()); + + if (!nodeService.hasAspect(nodeRef, ASPECT_FROZEN)) + { + // add freeze aspect + nodeService.addAspect(nodeRef, ASPECT_FROZEN, props); + + 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 (isRecordFolder(nodeRef)) + { + List records = recordService.getRecords(nodeRef); + for (NodeRef record : records) + { + // no need to freeze if already frozen! + if (!nodeService.hasAspect(record, ASPECT_FROZEN)) + { + 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.hold.HoldService#removeFromHold(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void removeFromHold(NodeRef hold, NodeRef nodeRef) + { + ParameterCheck.mandatory("hold", hold); + ParameterCheck.mandatory("nodeRef", nodeRef); + + List holds = new ArrayList(1); + holds.add(hold); + removeFromHolds(Collections.unmodifiableList(holds), nodeRef); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#removeFromHold(org.alfresco.service.cmr.repository.NodeRef, java.util.List) + */ + @Override + public void removeFromHold(NodeRef hold, List nodeRefs) + { + ParameterCheck.mandatory("hold", hold); + ParameterCheck.mandatory("nodeRefs", nodeRefs); + + for (NodeRef nodeRef : nodeRefs) + { + removeFromHold(hold, nodeRef); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#removeFromHolds(java.util.List, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void removeFromHolds(List holds, final NodeRef nodeRef) + { + ParameterCheck.mandatory("holds", holds); + ParameterCheck.mandatory("nodeRef", nodeRef); + + for (NodeRef hold : holds) + { + nodeService.removeChild(hold, nodeRef); + } + + // check to see if this node can be unfrozen + List holdList = heldBy(nodeRef, true); + if (holdList.size() == 0) + { + // run as system as we can't be sure if have remove aspect rights on node + runAsSystem(new RunAsWork() + { + @Override + public Void doWork() + { + // remove frozen aspect + nodeService.removeAspect(nodeRef, ASPECT_FROZEN); + return null; + } + }); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#removeFromAllHolds(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void removeFromAllHolds(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + // remove the node from all the holds it's held by + List holds = heldBy(nodeRef, true); + for (NodeRef hold : holds) + { + // remove node from hold + removeFromHold(hold, nodeRef); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldService#removeFromAllHolds(java.util.List) + */ + @Override + public void removeFromAllHolds(List nodeRefs) + { + ParameterCheck.mandatory("nodeRefs", nodeRefs); + + for (NodeRef nodeRef : nodeRefs) + { + removeFromAllHolds(nodeRef); + } + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordfolder/RecordFolderServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordfolder/RecordFolderServiceImpl.java index b7550c0349..3703420b85 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordfolder/RecordFolderServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordfolder/RecordFolderServiceImpl.java @@ -50,8 +50,7 @@ import org.springframework.extensions.surf.util.I18NUtil; */ public class RecordFolderServiceImpl extends ServiceBaseImpl implements RecordFolderService, - RecordsManagementModel//, - //NodeServicePolicies.OnCreateChildAssociationPolicy + RecordsManagementModel { /** Logger */ private static Log logger = LogFactory.getLog(RecordFolderServiceImpl.class); @@ -113,16 +112,6 @@ public class RecordFolderServiceImpl extends ServiceBaseImpl } } - /** - * @see org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService#isRecordFolder(NodeRef) - */ - @Override - public boolean isRecordFolder(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - return instanceOf(nodeRef, TYPE_RECORD_FOLDER); - } - /** * @see org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService#isRecordFolderDeclared(NodeRef) */ diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHold.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHold.java index 9221866b92..107ea759af 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHold.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHold.java @@ -24,7 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.service.cmr.repository.NodeRef; import org.json.JSONArray; import org.json.JSONException; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPost.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPost.java index c816a76339..997a4d8752 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPost.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPost.java @@ -36,6 +36,6 @@ public class HoldPost extends BaseHold @Override void doAction(List holds, NodeRef nodeRef) { - getHoldService().addToHoldContainers(holds, nodeRef); + getHoldService().addToHolds(holds, nodeRef); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPut.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPut.java index c86368d22c..cb3b38ad43 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPut.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldPut.java @@ -36,6 +36,6 @@ public class HoldPut extends BaseHold @Override void doAction(List holds, NodeRef nodeRef) { - getHoldService().removeFromHoldContainers(holds, nodeRef); + getHoldService().removeFromHolds(holds, nodeRef); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldsGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldsGet.java index 2c67980428..0151b96097 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldsGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/hold/HoldsGet.java @@ -27,7 +27,7 @@ import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; -import org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; @@ -102,7 +102,7 @@ public class HoldsGet extends DeclarativeWebScript else { boolean includedInHold = getIncludedInHold(req); - holds.addAll(holdService.getHolds(itemNodeRef, includedInHold)); + holds.addAll(holdService.heldBy(itemNodeRef, includedInHold)); } List holdObjects = new ArrayList(holds.size()); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java index c21648df45..44f4012f15 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.util; import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; 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; @@ -60,6 +61,20 @@ public class ServiceBaseImpl implements RecordsManagementModel { this.dictionaryService = dictionaryService; } + + /** + * Indicates whether the given node is a record folder or not. + *

+ * Exposed in the RecordFolder service. + * + * @param nodeRef node reference + * @return boolean true if record folder, false otherwise + */ + public boolean isRecordFolder(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + return instanceOf(nodeRef, TYPE_RECORD_FOLDER); + } /** * Indicates whether the given node reference is a record or not. @@ -73,6 +88,28 @@ public class ServiceBaseImpl implements RecordsManagementModel return nodeService.hasAspect(nodeRef, ASPECT_RECORD); } + + /** + * Indicates whether the given node reference is a hold or not. + *

+ * Exposed publically in the {@link HoldService} + * + * @param nodeRef node reference + * @return boolean true if rma:hold or sub-type, false otherwise + */ + public boolean isHold(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + if (nodeService.exists(nodeRef) && instanceOf(nodeRef, TYPE_HOLD)) + { + return true; + } + else + { + return false; + } + } /** * Gets the file plan that a given file plan component resides within. @@ -185,4 +222,30 @@ public class ServiceBaseImpl implements RecordsManagementModel result.add(nodeService.getType(nodeRef)); return result; } + + /** + * Helper method that executed work as system user. + *

+ * Useful when testing using mocks. + * + * @param runAsWork work to execute as system user + * @return + */ + public R runAsSystem(RunAsWork runAsWork) + { + return AuthenticationUtil.runAsSystem(runAsWork); + } + + /** + * Helper method that executed work as given user. + *

+ * Useful when testing using mocks. + * + * @param runAsWork work to execute as given user + * @return + */ + public R runAs(RunAsWork runAsWork, String uid) + { + return AuthenticationUtil.runAs(runAsWork, uid); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java index ce5bd74ca3..66cd005fbf 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java @@ -27,6 +27,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.service.FilePlanPermissio import org.alfresco.module.org_alfresco_module_rm.test.service.FilePlanRoleServiceImplTest; import org.alfresco.module.org_alfresco_module_rm.test.service.FilePlanServiceImplTest; import org.alfresco.module.org_alfresco_module_rm.test.service.FreezeServiceImplTest; +import org.alfresco.module.org_alfresco_module_rm.test.service.HoldServiceImplTest; import org.alfresco.module.org_alfresco_module_rm.test.service.ModelSecurityServiceImplTest; import org.alfresco.module.org_alfresco_module_rm.test.service.RecordServiceImplTest; import org.alfresco.module.org_alfresco_module_rm.test.service.RecordsManagementActionServiceImplTest; @@ -70,7 +71,8 @@ import org.junit.runners.Suite.SuiteClasses; FilePlanServiceImplTest.class, FilePlanPermissionServiceImplTest.class, ReportServiceImplTest.class, - RecordsManagementQueryDAOImplTest.class + RecordsManagementQueryDAOImplTest.class, + HoldServiceImplTest.class }) public class ServicesTestSuite { 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/issue/RM1008Test.java index 2ff2718e1d..4dfb9ca8cd 100644 --- 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/issue/RM1008Test.java @@ -126,9 +126,9 @@ public class RM1008Test extends BaseRMTestCase public NodeRef run() { // create hold object - freezeService.freeze("test", rmFolder); - List holds = holdService.getHolds(filePlan); - return holds.iterator().next(); + NodeRef hold = holdService.createHold(filePlan, "my hold", "my reason", "my description"); + holdService.addToHold(hold, rmFolder); + return hold; } }, rmAdminName); 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/issue/RM1030Test.java index bc4edd702e..b08cd2ec8c 100644 --- 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/issue/RM1030Test.java @@ -51,7 +51,8 @@ public class RM1030Test extends BaseRMTestCase assertEquals(0, holds.size()); // freeze record contained within the record folder - NodeRef hold = freezeService.freeze("in true life for serious", recordOne); + NodeRef hold = holdService.createHold(filePlan, "my hold 2", "in true life for serious", "my decription"); + holdService.addToHold(hold, recordOne); assertNotNull(hold); return hold; @@ -77,7 +78,8 @@ public class RM1030Test extends BaseRMTestCase public NodeRef run() { // freeze the record folder that contains the frozen record - NodeRef folderHold = freezeService.freeze("innit but", rmFolder); + NodeRef folderHold = holdService.createHold(filePlan, "my hold 3", "innit but", "my decription"); + holdService.addToHold(folderHold, rmFolder); assertNotNull(folderHold); return folderHold; @@ -103,7 +105,7 @@ public class RM1030Test extends BaseRMTestCase public Void run() { // relinquish the record folder hold - freezeService.relinquish(recordFolderHold); + holdService.deleteHold(recordFolderHold); return null; } @@ -125,7 +127,7 @@ public class RM1030Test extends BaseRMTestCase public Void run() { // relinquish the record hold - freezeService.relinquish(recordHold); + holdService.deleteHold(recordHold); return null; } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java index 187cc4d326..75036e7a11 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java @@ -18,10 +18,9 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.service; +import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; @@ -61,7 +60,9 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertTrue(filePlanService.isFilePlanComponent(recordFour)); // Freeze a record - freezeService.freeze("FreezeReason", recordOne); + NodeRef hold101 = holdService.createHold(filePlan, "freezename 101", "FreezeReason", null); + assertNotNull(hold101); + holdService.addToHold(hold101, recordOne); assertTrue(freezeService.hasFrozenChildren(rmFolder)); // Check the hold exists @@ -69,9 +70,10 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertNotNull(holdAssocs); assertEquals(1, holdAssocs.size()); NodeRef holdNodeRef = holdAssocs.iterator().next(); - assertTrue(freezeService.isHold(holdNodeRef)); - assertEquals("FreezeReason", freezeService.getReason(holdNodeRef)); - Set frozenNodes = freezeService.getFrozen(holdNodeRef); + assertEquals(holdNodeRef, hold101); + assertTrue(holdService.isHold(holdNodeRef)); + assertEquals("FreezeReason", holdService.getHoldReason(holdNodeRef)); + List frozenNodes = holdService.getHeld(holdNodeRef); assertNotNull(frozenNodes); assertEquals(1, frozenNodes.size()); @@ -83,19 +85,20 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertFalse(freezeService.isFrozen(recordThree)); // Update the freeze reason - freezeService.updateReason(holdNodeRef, "NewFreezeReason"); + holdService.setHoldReason(holdNodeRef, "NewFreezeReason"); // Check the hold has been updated - assertEquals("NewFreezeReason", freezeService.getReason(holdNodeRef)); + assertEquals("NewFreezeReason", holdService.getHoldReason(holdNodeRef)); // Freeze a number of records - Set records = new HashSet(); + List records = new ArrayList(); records.add(recordOne); records.add(recordTwo); records.add(recordThree); - NodeRef newHold = freezeService.freeze("Freeze a set of nodes", records); + NodeRef newHold = holdService.createHold(filePlan, "Hold 102", "Freeze a set of nodes", null); + holdService.addToHold(newHold, records); assertNotNull(newHold); - assertTrue(freezeService.isHold(newHold)); + assertTrue(holdService.isHold(newHold)); // Check the holds exist holdAssocs = holdService.getHolds(filePlan); @@ -103,17 +106,17 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertEquals(2, holdAssocs.size()); for (NodeRef hold : holdAssocs) { - String reason = freezeService.getReason(hold); + String reason = holdService.getHoldReason(hold); if (reason.equals("Freeze a set of nodes")) { assertEquals(newHold, hold); - frozenNodes = freezeService.getFrozen(hold); + frozenNodes = holdService.getHeld(hold); assertNotNull(frozenNodes); assertEquals(3, frozenNodes.size()); } else if (reason.equals("NewFreezeReason")) { - frozenNodes = freezeService.getFrozen(hold); + frozenNodes = holdService.getHeld(hold); assertNotNull(frozenNodes); assertEquals(1, frozenNodes.size()); } @@ -133,7 +136,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase } // Unfreeze a node - freezeService.unFreeze(recordThree); + holdService.removeFromAllHolds(recordThree); // Check the holds holdAssocs = holdService.getHolds(filePlan); @@ -141,16 +144,16 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertEquals(2, holdAssocs.size()); for (NodeRef hold : holdAssocs) { - String reason = freezeService.getReason(hold); + String reason = holdService.getHoldReason(hold); if (reason.equals("Freeze a set of nodes")) { - frozenNodes = freezeService.getFrozen(hold); + frozenNodes = holdService.getHeld(hold); assertNotNull(frozenNodes); assertEquals(2, frozenNodes.size()); } else if (reason.equals("NewFreezeReason")) { - frozenNodes = freezeService.getFrozen(hold); + frozenNodes = holdService.getHeld(hold); assertNotNull(frozenNodes); assertEquals(1, frozenNodes.size()); } @@ -172,7 +175,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase // Relinquish the first hold holdNodeRef = holdAssocs.iterator().next(); - freezeService.relinquish(holdNodeRef); + holdService.deleteHold(holdNodeRef); // Check the existing hold holdAssocs = holdService.getHolds(filePlan); @@ -181,9 +184,14 @@ public class FreezeServiceImplTest extends BaseRMTestCase // Relinquish the second hold holdNodeRef = holdAssocs.iterator().next(); - freezeService.unFreeze(freezeService.getFrozen(holdNodeRef)); + holdService.removeFromAllHolds(holdService.getHeld(holdNodeRef)); - // All holds should be deleted + // hold is not automatically removed + holdAssocs = holdService.getHolds(filePlan); + assertEquals(1, holdAssocs.size()); + + // delete hold + holdService.deleteHold(holdNodeRef); holdAssocs = holdService.getHolds(filePlan); assertEquals(0, holdAssocs.size()); @@ -195,12 +203,13 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertFalse(freezeService.hasFrozenChildren(rmFolder)); // Test freezing nodes, adding them to an existing hold - NodeRef hold = freezeService.freeze("AnotherFreezeReason", recordFour); - holdService.addToHoldContainer(hold, recordOne); - Set nodes = new HashSet(); + NodeRef hold = holdService.createHold(filePlan, "hold 1", "AnotherFreezeReason", "description"); + holdService.addToHold(hold, recordFour); + holdService.addToHold(hold, recordOne); + List nodes = new ArrayList(); nodes.add(recordTwo); nodes.add(recordThree); - freezeService.freeze(hold, nodes); + holdService.addToHold(hold, nodes); assertTrue(freezeService.hasFrozenChildren(rmFolder)); // Check the hold @@ -209,7 +218,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertEquals(1, holdAssocs.size()); // Relinquish the first hold - freezeService.relinquish(holdAssocs.iterator().next()); + holdService.deleteHold(holdAssocs.iterator().next()); // Check the nodes are unfrozen assertFalse(freezeService.isFrozen(recordOne)); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/HoldServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/HoldServiceImplTest.java new file mode 100644 index 0000000000..0413393f26 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/HoldServiceImplTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2005-2012 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.service; + +import java.util.List; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Hold service integration test. + * + * @author Roy Wetherall + * @since 2.2 + */ +public class HoldServiceImplTest extends BaseRMTestCase +{ + @Override + protected boolean isRecordTest() + { + return true; + } + + public void testDeleteHoldBehaviourForRecordFolder() + { + doTestInTransaction(new Test() + { + @Override + public Void run() throws Exception + { + // create test holds + NodeRef hold1 = holdService.createHold(filePlan, "hold one", "I have my reasons", "but I'll not describe them here!"); + assertNotNull(hold1); + + // add the record folder to hold1 + holdService.addToHold(hold1, rmFolder); + + // assert that the folder and records are frozen + assertTrue(freezeService.isFrozen(rmFolder)); + assertTrue(freezeService.isFrozen(recordOne)); + assertTrue(freezeService.isFrozen(recordDeclaredOne)); + + // check the contents of the hold + List frozenNodes = holdService.getHeld(hold1); + assertNotNull(frozenNodes); + assertEquals(1, frozenNodes.size()); + assertEquals(rmFolder, frozenNodes.get(0)); + + // delete the hold + holdService.deleteHold(hold1); + + // assert that the folder and records no longer frozen + assertFalse(freezeService.isFrozen(rmFolder)); + assertFalse(freezeService.isFrozen(recordOne)); + assertFalse(freezeService.isFrozen(recordDeclaredOne)); + + // confirm the hold has been deleted + assertNull(holdService.getHold(filePlan, "hold one")); + + return null; + } + }); + } + + public void testDeleteHoldBehaviourForMultipleHolds() + { + doTestInTransaction(new Test() + { + @Override + public Void run() throws Exception + { + // create test holds + NodeRef hold1 = holdService.createHold(filePlan, "hold one", "I have my reasons", "but I'll not describe them here!"); + assertNotNull(hold1); + NodeRef hold2 = holdService.createHold(filePlan, "hold two", "secrets are everything", "no then! that's just not on!"); + assertNotNull(hold2); + + // add the record folder to hold1 + holdService.addToHold(hold1, rmFolder); + + // assert that the folder and records are frozen + assertTrue(freezeService.isFrozen(rmFolder)); + assertTrue(freezeService.isFrozen(recordOne)); + assertTrue(freezeService.isFrozen(recordDeclaredOne)); + + // check the contents of the hold + List frozenNodes = holdService.getHeld(hold1); + assertNotNull(frozenNodes); + assertEquals(1, frozenNodes.size()); + assertEquals(rmFolder, frozenNodes.get(0)); + + holdService.addToHold(hold2, recordOne); + + // assert that the folder and records are frozen + assertTrue(freezeService.isFrozen(rmFolder)); + assertTrue(freezeService.isFrozen(recordOne)); + assertTrue(freezeService.isFrozen(recordDeclaredOne)); + + // delete the hold + holdService.deleteHold(hold1); + + // assert that the folder and records no longer frozen + assertFalse(freezeService.isFrozen(rmFolder)); + assertTrue(freezeService.isFrozen(recordOne)); + assertFalse(freezeService.isFrozen(recordDeclaredOne)); + + // confirm the hold has been deleted + assertNull(holdService.getHold(filePlan, "hold one")); + + // delete the hold + holdService.deleteHold(hold2); + + // assert that the folder and records no longer frozen + assertFalse(freezeService.isFrozen(rmFolder)); + assertFalse(freezeService.isFrozen(recordOne)); + assertFalse(freezeService.isFrozen(recordDeclaredOne)); + + // confirm the hold has been deleted + assertNull(holdService.getHold(filePlan, "hold two")); + + return null; + } + }); + } + +} 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 db8412fde5..3ef66c4ba1 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 @@ -34,8 +34,8 @@ import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedul import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; -import org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService; import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.rma.type.RmSiteType; @@ -436,7 +436,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase List holds = holdService.getHolds(filePlan); for (NodeRef hold : holds) { - freezeService.relinquish(hold); + holdService.deleteHold(hold); } } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/AllUnitTestSuite.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/AllUnitTestSuite.java index 65c4096843..3f35bfca29 100755 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/AllUnitTestSuite.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/AllUnitTestSuite.java @@ -19,6 +19,7 @@ package org.alfresco.module.org_alfresco_module_rm; import org.alfresco.module.org_alfresco_module_rm.forms.RecordsManagementTypeFormFilterUnitTest; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImplUnitTest; import org.alfresco.module.org_alfresco_module_rm.record.RecordMetadataBootstrapUnitTest; import org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImplUnitTest; import org.junit.runner.RunWith; @@ -36,7 +37,8 @@ import org.junit.runners.Suite.SuiteClasses; { RecordMetadataBootstrapUnitTest.class, RecordServiceImplUnitTest.class, - RecordsManagementTypeFormFilterUnitTest.class + RecordsManagementTypeFormFilterUnitTest.class, + HoldServiceImplUnitTest.class }) public class AllUnitTestSuite { diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/BaseUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/BaseUnitTest.java index 86f50b7b06..e04d0f5590 100755 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/BaseUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/BaseUnitTest.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm; import static org.mockito.Mockito.when; +import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.service.cmr.dictionary.DictionaryService; @@ -41,22 +42,28 @@ import org.mockito.MockitoAnnotations; */ public class BaseUnitTest implements RecordsManagementModel { - protected static NodeRef FILE_PLAN_COMPONENT = generateNodeRef(); - protected static NodeRef FILE_PLAN = generateNodeRef(); + protected NodeRef filePlanComponent; + protected NodeRef filePlan; + /** core service mocks */ @Mock(name="nodeService") protected NodeService mockedNodeService; @Mock(name="dictionaryService") protected DictionaryService mockedDictionaryService; @Mock(name="namespaceService") protected NamespaceService mockedNamespaceService; @Mock(name="identifierService") protected IdentifierService mockedIdentifierService; + /** rm service mocks */ + @Mock(name="filePlanService") protected FilePlanService mockedFilePlanService; + @Before public void before() { MockitoAnnotations.initMocks(this); + filePlanComponent = generateNodeRef(); + filePlan = generateNodeRef(TYPE_FILE_PLAN); + // set-up node service - when(mockedNodeService.getProperty(FILE_PLAN_COMPONENT, PROP_ROOT_NODEREF)).thenReturn(FILE_PLAN); - when(mockedNodeService.getType(FILE_PLAN)).thenReturn(TYPE_FILE_PLAN); + when(mockedNodeService.getProperty(filePlanComponent, PROP_ROOT_NODEREF)).thenReturn(filePlan); // set-up namespace service when(mockedNamespaceService.getNamespaceURI(RM_PREFIX)).thenReturn(RM_URI); @@ -69,8 +76,19 @@ public class BaseUnitTest implements RecordsManagementModel return QName.createQName(RM_URI, GUID.generate()); } - protected static NodeRef generateNodeRef() + protected NodeRef generateNodeRef() { - return new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate()); + return generateNodeRef(null); + } + + protected NodeRef generateNodeRef(QName type) + { + NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate()); + when(mockedNodeService.exists(nodeRef)).thenReturn(true); + if (type != null) + { + when(mockedNodeService.getType(nodeRef)).thenReturn(type); + } + return nodeRef; } } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java new file mode 100644 index 0000000000..c78221ce3e --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java @@ -0,0 +1,312 @@ +/* + * 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.hold; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.doAnswer; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.BaseUnitTest; +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.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Spy; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + + +/** + * Hold service implementation unit test + * + * @author Roy Wetherall + */ +public class HoldServiceImplUnitTest extends BaseUnitTest +{ + /** test values */ + private static final String HOLD_NAME = "holdname"; + private static final String HOLD_REASON = "holdreason"; + private static final String HOLD_DESCRIPTION = "holddescription"; + + protected NodeRef holdContainer; + protected NodeRef hold; + protected NodeRef hold2; + protected NodeRef notHold; + + @Spy @InjectMocks HoldServiceImpl holdService; + + @Before + @Override + public void before() + { + super.before(); + + holdContainer = generateNodeRef(TYPE_HOLD_CONTAINER); + hold = generateNodeRef(TYPE_HOLD); + hold2 = generateNodeRef(TYPE_HOLD); + notHold = generateNodeRef(TYPE_RECORD_CATEGORY); + + when(mockedFilePlanService.getHoldContainer(filePlan)).thenReturn(holdContainer); + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void beforeDeleteNode() + { + doAnswer(new Answer() + { + @Override + public Void answer(InvocationOnMock invocation) throws Exception + { + Object[] args = invocation.getArguments(); + ((RunAsWork)args[0]).doWork(); + return null; + } + }).when(holdService).runAsSystem(any(RunAsWork.class)); + } + + @Test + public void isHold() + { + assertTrue(holdService.isHold(hold)); + assertFalse(holdService.isHold(notHold)); + } + + @Test + public void getHolds() + { + // with no holds + List emptyHoldList = holdService.getHolds(filePlan); + verify(mockedNodeService).getChildAssocs(holdContainer, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + assertNotNull(emptyHoldList); + assertTrue(emptyHoldList.isEmpty()); + + // set up list of two holds + List list = new ArrayList(2); + list.add(new ChildAssociationRef(generateQName(), holdContainer, generateQName(), hold)); + list.add(new ChildAssociationRef(generateQName(), holdContainer, generateQName(), hold2)); + when(mockedNodeService.getChildAssocs(holdContainer, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL)).thenReturn(list); + + // with 2 holds + List holdsList = holdService.getHolds(filePlan); + verify(mockedNodeService, times(2)).getChildAssocs(holdContainer, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + assertNotNull(holdsList); + assertEquals(2, holdsList.size()); + + // check one of the holds + NodeRef holdFromList = holdsList.get(0); + assertEquals(TYPE_HOLD, mockedNodeService.getType(holdFromList)); + + } + + @Test + public void heldBy() + { + // TODO + } + + @Test (expected=AlfrescoRuntimeException.class) + public void getHold() + { + // setup node service interactions + when(mockedNodeService.getChildByName(eq(holdContainer), eq(ContentModel.ASSOC_CONTAINS), anyString())).thenReturn(null) + .thenReturn(hold) + .thenReturn(notHold); + + // no hold + NodeRef noHold = holdService.getHold(filePlan, "notAHold"); + assertNull(noHold); + + // found hold + NodeRef someHold = holdService.getHold(filePlan, "someHold"); + assertNotNull(someHold); + assertEquals(TYPE_HOLD, mockedNodeService.getType(someHold)); + + // ensure runtime exception is thrown + holdService.getHold(filePlan, "notHold"); + } + + @Test + public void getHeld() + { + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void createHold() + { + // setup node service interactions + when(mockedNodeService.createNode(eq(holdContainer), eq(ContentModel.ASSOC_CONTAINS), any(QName.class) , eq(TYPE_HOLD), any(Map.class))) + .thenReturn(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, holdContainer, generateQName(), hold)); + + // create hold + NodeRef newHold = holdService.createHold(filePlan, HOLD_NAME, HOLD_REASON, HOLD_DESCRIPTION); + assertNotNull(newHold); + assertEquals(TYPE_HOLD, mockedNodeService.getType(newHold)); + assertEquals(hold, newHold); + + // check the node service interactions + ArgumentCaptor propertyMapCaptor = ArgumentCaptor.forClass(Map.class); + ArgumentCaptor assocNameCaptor = ArgumentCaptor.forClass(QName.class); + verify(mockedNodeService).createNode(eq(holdContainer), eq(ContentModel.ASSOC_CONTAINS), assocNameCaptor.capture() , eq(TYPE_HOLD), propertyMapCaptor.capture()); + + // check property map + Map propertyMap = (Map)propertyMapCaptor.getValue(); + assertNotNull(propertyMap); + assertEquals(3, propertyMap.size()); + assertTrue(propertyMap.containsKey(ContentModel.PROP_NAME)); + assertEquals(HOLD_NAME, propertyMap.get(ContentModel.PROP_NAME)); + assertTrue(propertyMap.containsKey(ContentModel.PROP_DESCRIPTION)); + assertEquals(HOLD_DESCRIPTION, propertyMap.get(ContentModel.PROP_DESCRIPTION)); + assertTrue(propertyMap.containsKey(PROP_HOLD_REASON)); + assertEquals(HOLD_REASON, propertyMap.get(PROP_HOLD_REASON)); + + // check assoc name + assertNotNull(assocNameCaptor.getValue()); + assertEquals(NamespaceService.CONTENT_MODEL_1_0_URI, assocNameCaptor.getValue().getNamespaceURI()); + assertEquals(HOLD_NAME, assocNameCaptor.getValue().getLocalName()); + } + + @Test + public void getHoldReason() + { + // setup node service interactions + when(mockedNodeService.exists(hold)) + .thenReturn(false) + .thenReturn(true) + .thenReturn(true) + .thenReturn(true); + when(mockedNodeService.getProperty(eq(hold), eq(PROP_HOLD_REASON))) + .thenReturn(null) + .thenReturn(HOLD_REASON); + + // node does not exist + assertNull(holdService.getHoldReason(hold)); + + // node isn't a hold + assertNull(holdService.getHoldReason(notHold)); + + // hold reason isn't set + assertNull(holdService.getHoldReason(hold)); + + // hold reason set + assertEquals(HOLD_REASON, holdService.getHoldReason(hold)); + } + + @Test + public void setHoldReason() + { + // setup node service interactions + when(mockedNodeService.exists(hold)) + .thenReturn(false) + .thenReturn(true) + .thenReturn(true); + + // node does not exist + holdService.setHoldReason(hold, HOLD_REASON); + verify(mockedNodeService, never()).setProperty(hold, PROP_HOLD_REASON, HOLD_REASON); + + // node isn't a hold + holdService.setHoldReason(notHold, HOLD_REASON); + verify(mockedNodeService, never()).setProperty(hold, PROP_HOLD_REASON, HOLD_REASON); + + // set hold reason + holdService.setHoldReason(hold, HOLD_REASON); + verify(mockedNodeService).setProperty(hold, PROP_HOLD_REASON, HOLD_REASON); + } + + @Test + public void deleteHold() + { + // setup node service interactions + when(mockedNodeService.exists(hold)) + .thenReturn(false) + .thenReturn(true) + .thenReturn(true); + + // node does not exist + holdService.deleteHold(hold); + verify(mockedNodeService, never()).deleteNode(hold); + + // node isn't a hold + holdService.deleteHold(notHold); + verify(mockedNodeService, never()).deleteNode(hold); + + // delete hold + holdService.deleteHold(hold); + verify(mockedNodeService).deleteNode(hold); + + // TODO check interactions with policy component!!! + } + + @Test + public void addToHold() + { + // TODO + } + + @Test + public void addToHolds() + { + // TODO + } + + @Test + public void removeFromHold() + { + // TODO + } + + @Test + public void removeFromHolds() + { + // TODO + } + + @Test + public void removeFromAllHolds() + { + + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java index ac41a2bb45..29bd736996 100755 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java @@ -41,8 +41,8 @@ import org.mockito.InjectMocks; */ public class RecordServiceImplUnitTest extends BaseUnitTest { - private static NodeRef NON_STANDARD_FILE_PLAN_COMPONENT = generateNodeRef(); - private static NodeRef NON_STANDARD_FILE_PLAN = generateNodeRef(); + private NodeRef nonStandardFilePlanComponent; + private NodeRef nonStandardFilePlan; private static QName TYPE_MY_FILE_PLAN = generateQName(); private static QName ASPECT_FOR_FILE_PLAN = generateQName(); @@ -58,9 +58,11 @@ public class RecordServiceImplUnitTest extends BaseUnitTest { super.before(); + nonStandardFilePlanComponent = generateNodeRef(); + nonStandardFilePlan = generateNodeRef(TYPE_MY_FILE_PLAN); + // set-up node service - when(mockedNodeService.getProperty(NON_STANDARD_FILE_PLAN_COMPONENT, PROP_ROOT_NODEREF)).thenReturn(NON_STANDARD_FILE_PLAN); - when(mockedNodeService.getType(NON_STANDARD_FILE_PLAN)).thenReturn(TYPE_MY_FILE_PLAN); + when(mockedNodeService.getProperty(nonStandardFilePlanComponent, PROP_ROOT_NODEREF)).thenReturn(nonStandardFilePlan); // set-up dictionary service when(mockedDictionaryService.getAllAspects()).thenReturn(CollectionUtils.EMPTY_COLLECTION); @@ -90,13 +92,13 @@ public class RecordServiceImplUnitTest extends BaseUnitTest recordService.registerRecordMetadataAspect(ASPECT_FOR_BOTH, TYPE_FILE_PLAN); recordService.registerRecordMetadataAspect(ASPECT_FOR_BOTH, TYPE_MY_FILE_PLAN); - Set set = recordService.getRecordMetadataAspects(FILE_PLAN_COMPONENT); + Set set = recordService.getRecordMetadataAspects(filePlanComponent); assertNotNull(set); assertEquals(2, set.size()); assertTrue(set.contains(ASPECT_FOR_FILE_PLAN)); assertTrue(set.contains(ASPECT_FOR_BOTH)); - set = recordService.getRecordMetadataAspects(NON_STANDARD_FILE_PLAN_COMPONENT); + set = recordService.getRecordMetadataAspects(nonStandardFilePlanComponent); assertNotNull(set); assertEquals(2, set.size()); assertTrue(set.contains(ASPECT_FOR_MY_FILE_PLAN));