Hold Service Improvements:

* HoldService API explanded beyound immediate use case needs to form a more complete API, plus some tweaks to method names
 * unit test (via Mockito) added .. still some todo's (see RM-1326)
 * integration test added .. to test behaviour interactions (see RM-1326)
 * method level permissions added to Hold service .. should see filtering of results based on permissions
 * added behaviour to HoldService to unfreeze records and record folders when hold is deleted (same as old relinquish action)
 * deprecation of dupliacte methods found in FreezeService
 * fix up use of deprecated methods throughout code .. note that warnings have only been hidden in actions that are soon to be deprecated too



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@64834 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2014-03-19 05:02:04 +00:00
parent e6f1c48f53
commit e0cdb0d2d0
30 changed files with 1495 additions and 894 deletions

View File

@@ -77,6 +77,7 @@
<property name="permission" value="AddToHold" />
<property name="kinds">
<list>
<value>HOLD</value>
<value>RECORD_FOLDER</value>
<value>RECORD</value>
</list>
@@ -96,6 +97,7 @@
<property name="permission" value="RemoveFromHold" />
<property name="kinds">
<list>
<value>HOLD</value>
<value>RECORD_FOLDER</value>
<value>RECORD</value>
</list>

View File

@@ -1639,9 +1639,9 @@
<!-- Hold Service -->
<bean id="holdService"
class="org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldServiceImpl">
parent="baseService"
class="org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImpl">
<property name="filePlanService" ref="FilePlanService" />
<property name="nodeService" ref="nodeService" />
<property name="recordService" ref="RecordService" />
<property name="recordFolderService" ref="RecordFolderService" />
</bean>
@@ -1649,7 +1649,7 @@
<bean id="HoldService"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService</value>
<value>org.alfresco.module.org_alfresco_module_rm.hold.HoldService</value>
</property>
<property name="target">
<ref bean="holdService"/>
@@ -1669,12 +1669,21 @@
<property name="objectDefinitionSource">
<value>
<![CDATA[
org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService.getHolds=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService.addToHoldContainer=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService.addToHoldContainers=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService.removeFromHoldContainer=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService.removeFromHoldContainers=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.fileplan.hold.HoldService.*=RM_DENY
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.isHold=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHolds=RM.Read.0,AFTER_RM.FilterNode
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHold=RM.Read.0,AFTER_RM.FilterNode
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.heldBy=RM.Read.0,AFTER_RM.FilterNode
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHeld=RM.Read.0,AFTER_RM.FilterNode
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.createHold=RM.Read.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHoldReason=RM.Read.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.setHoldReason=RM.Write.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.deleteHold=RM.Write.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHold=RM.Write.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHolds=RM.Write.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromHold=RM.Write.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromHolds=RM.Write.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromAllHolds=RM.Write.0
org.alfresco.module.org_alfresco_module_rm.hold.HoldService.*=RM_DENY
]]>
</value>
</property>

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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";
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<NodeRef> getHolds(NodeRef filePlan)
{
ParameterCheck.mandatory("filePlan", filePlan);
NodeRef holdContainer = filePlanService.getHoldContainer(filePlan);
List<ChildAssociationRef> holdsAssocs = nodeService.getChildAssocs(holdContainer, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
List<NodeRef> holds = new ArrayList<NodeRef>(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<NodeRef> getHolds(NodeRef nodeRef, boolean includedInHold)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
List<NodeRef> result = new ArrayList<NodeRef>();
List<ChildAssociationRef> holdsAssocs = nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
List<NodeRef> holdsNotIncludingNodeRef = new ArrayList<NodeRef>(holdsAssocs.size());
for (ChildAssociationRef holdAssoc : holdsAssocs)
{
holdsNotIncludingNodeRef.add(holdAssoc.getParentRef());
}
result.addAll(holdsNotIncludingNodeRef);
if (!includedInHold)
{
NodeRef filePlan = filePlanService.getFilePlan(nodeRef);
List<NodeRef> allHolds = getHolds(filePlan);
@SuppressWarnings("unchecked")
List<NodeRef> 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<NodeRef> holds = new ArrayList<NodeRef>(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<NodeRef> 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<QName, Serializable> props = new HashMap<QName, Serializable>(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<NodeRef> 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<NodeRef> holds = new ArrayList<NodeRef>(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<NodeRef> holds, NodeRef nodeRef)
{
ParameterCheck.mandatory("holds", holds);
ParameterCheck.mandatory("nodeRef", nodeRef);
for (NodeRef hold : holds)
{
nodeService.removeChild(hold, nodeRef);
}
List<NodeRef> holdList = getHolds(nodeRef, true);
if (holdList.size() == 0)
{
nodeService.removeAspect(nodeRef, ASPECT_FROZEN);
}
}
}

View File

@@ -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.
*/
@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<NodeRef> frozen node references
* @deprecated as of 2.2, use {@link HoldService#getHeld(NodeRef)} instead.
*/
@Deprecated
Set<NodeRef> 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<NodeRef>)} instead.
*/
@Deprecated
NodeRef freeze(String reason, Set<NodeRef> 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<NodeRef>)} instead.
*/
@Deprecated
void freeze(NodeRef hold, Set<NodeRef> nodeRefs);
/**
* Unfreeze a frozen node.
* <p>
* 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.
* <p>
* 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<NodeRef> 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<NodeRef> 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<NodeRef> 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);
}

View File

@@ -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<NodeRef> getFrozen(NodeRef hold)
{
ParameterCheck.mandatory("hold", hold);
Set<NodeRef> frozenNodes = new HashSet<NodeRef>();
List<ChildAssociationRef> 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<NodeRef> 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<NodeRef> 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<NodeRef> 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<NodeRef> 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<ChildAssociationRef> 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<NodeRef> getHolds(NodeRef filePlan)
{
ParameterCheck.mandatory("filePlan", filePlan);
return new HashSet<NodeRef>(holdService.getHolds(filePlan));
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -440,9 +171,152 @@ public class FreezeServiceImpl extends ServiceBaseImpl
}
/**
* Helper Methods
* Deprecated Method Implementations
*/
/**
* @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFrozen(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
@Deprecated
public Set<NodeRef> getFrozen(NodeRef hold)
{
return new HashSet<NodeRef>(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<NodeRef> nodeRefs)
{
NodeRef hold = null;
if (!nodeRefs.isEmpty())
{
List<NodeRef> list = new ArrayList<NodeRef>(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<NodeRef> 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<NodeRef> 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<NodeRef> 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<NodeRef> getHolds(NodeRef filePlan)
{
ParameterCheck.mandatory("filePlan", filePlan);
return new HashSet<NodeRef>(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<QName, Serializable> holdProps = new HashMap<QName, Serializable>(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<ChildAssociationRef> 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<ChildAssociationRef> 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<ChildAssociationRef> 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<NodeRef> parentFolders = recordFolderService.getRecordFolders(nodeRef);
for (NodeRef folder : parentFolders)
{
List<ChildAssociationRef> 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);
}
}

View File

@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
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<NodeRef> 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,7 +62,44 @@ public interface HoldService
* <code>false</code> to get a list of node references which will not have the given node reference
* @return List of hold node references
*/
List<NodeRef> getHolds(NodeRef nodeRef, boolean includedInHold);
List<NodeRef> heldBy(NodeRef nodeRef, boolean includedInHold);
/**
*
* @param ndoeRef
* @return
*/
List<NodeRef> 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
@@ -54,7 +107,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 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<NodeRef> 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<NodeRef> holds, NodeRef nodeRef);
void addToHolds(List<NodeRef> 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<NodeRef> 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<NodeRef> holds, NodeRef nodeRef);
void removeFromHolds(List<NodeRef> holds, NodeRef nodeRef);
/**
*
* @param nodeRef
*/
void removeFromAllHolds(NodeRef nodeRef);
/**
*
* @param nodeRefs
*/
void removeFromAllHolds(List<NodeRef> nodeRefs);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<Void> work = new RunAsWork<Void>()
{
@Override
public Void doWork()
{
List<NodeRef> frozenNodes = getHeld(hold);
for (NodeRef frozenNode : frozenNodes)
{
List<NodeRef> otherHolds = heldBy(frozenNode, true);
if (otherHolds.size() == 1)
{
// remove the freeze aspect from the node
nodeService.removeAspect(frozenNode, ASPECT_FROZEN);
if (isRecordFolder(frozenNode))
{
List<NodeRef> records = recordService.getRecords(frozenNode);
for (NodeRef record : records)
{
if (nodeService.hasAspect(record, ASPECT_FROZEN))
{
List<NodeRef> 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<NodeRef> 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<ChildAssociationRef> holdsAssocs = nodeService.getChildAssocs(holdContainer, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
List<NodeRef> holds = new ArrayList<NodeRef>(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<NodeRef> heldBy(NodeRef nodeRef, boolean includedInHold)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
List<NodeRef> result = null;
// get all the immediate parent holds
Set<NodeRef> holdsNotIncludingNodeRef = getParentHolds(nodeRef);
// check whether the record is held by vitue of it's record folder
if (isRecord(nodeRef))
{
List<NodeRef> 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<NodeRef> allHolds = getHolds(filePlan);
result = ListUtils.subtract(allHolds, new ArrayList<NodeRef>(holdsNotIncludingNodeRef));
}
else
{
result = new ArrayList<NodeRef>(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<NodeRef> getParentHolds(NodeRef nodeRef)
{
List<ChildAssociationRef> holdsAssocs = nodeService.getParentAssocs(nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS);
Set<NodeRef> holds = new HashSet<NodeRef>(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<NodeRef> getHeld(NodeRef hold)
{
ParameterCheck.mandatory("hold", hold);
List<NodeRef> children = new ArrayList<NodeRef>();
if (nodeService.exists(hold) && isHold(hold))
{
List<ChildAssociationRef> 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<QName, Serializable> properties = new HashMap<QName, Serializable>(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<NodeRef> holds = new ArrayList<NodeRef>(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<NodeRef> 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<NodeRef> 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<QName, Serializable> props = new HashMap<QName, Serializable>(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<NodeRef> 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<NodeRef> holds = new ArrayList<NodeRef>(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<NodeRef> 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<NodeRef> 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<NodeRef> 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<Void>()
{
@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<NodeRef> 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<NodeRef> nodeRefs)
{
ParameterCheck.mandatory("nodeRefs", nodeRefs);
for (NodeRef nodeRef : nodeRefs)
{
removeFromAllHolds(nodeRef);
}
}
}

View File

@@ -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)
*/

View File

@@ -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;

View File

@@ -36,6 +36,6 @@ public class HoldPost extends BaseHold
@Override
void doAction(List<NodeRef> holds, NodeRef nodeRef)
{
getHoldService().addToHoldContainers(holds, nodeRef);
getHoldService().addToHolds(holds, nodeRef);
}
}

View File

@@ -36,6 +36,6 @@ public class HoldPut extends BaseHold
@Override
void doAction(List<NodeRef> holds, NodeRef nodeRef)
{
getHoldService().removeFromHoldContainers(holds, nodeRef);
getHoldService().removeFromHolds(holds, nodeRef);
}
}

View File

@@ -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<Hold> holdObjects = new ArrayList<Hold>(holds.size());

View File

@@ -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;
@@ -61,6 +62,20 @@ public class ServiceBaseImpl implements RecordsManagementModel
this.dictionaryService = dictionaryService;
}
/**
* Indicates whether the given node is a record folder or not.
* <p>
* 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.
*
@@ -74,6 +89,28 @@ public class ServiceBaseImpl implements RecordsManagementModel
return nodeService.hasAspect(nodeRef, ASPECT_RECORD);
}
/**
* Indicates whether the given node reference is a hold or not.
* <p>
* 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.
* <p>
* Useful when testing using mocks.
*
* @param runAsWork work to execute as system user
* @return
*/
public <R> R runAsSystem(RunAsWork<R> runAsWork)
{
return AuthenticationUtil.runAsSystem(runAsWork);
}
/**
* Helper method that executed work as given user.
* <p>
* Useful when testing using mocks.
*
* @param runAsWork work to execute as given user
* @return
*/
public <R> R runAs(RunAsWork<R> runAsWork, String uid)
{
return AuthenticationUtil.runAs(runAsWork, uid);
}
}

View File

@@ -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
{

View File

@@ -126,9 +126,9 @@ public class RM1008Test extends BaseRMTestCase
public NodeRef run()
{
// create hold object
freezeService.freeze("test", rmFolder);
List<NodeRef> 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);

View File

@@ -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;
}

View File

@@ -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<NodeRef> frozenNodes = freezeService.getFrozen(holdNodeRef);
assertEquals(holdNodeRef, hold101);
assertTrue(holdService.isHold(holdNodeRef));
assertEquals("FreezeReason", holdService.getHoldReason(holdNodeRef));
List<NodeRef> 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<NodeRef> records = new HashSet<NodeRef>();
List<NodeRef> records = new ArrayList<NodeRef>();
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<NodeRef> nodes = new HashSet<NodeRef>();
NodeRef hold = holdService.createHold(filePlan, "hold 1", "AnotherFreezeReason", "description");
holdService.addToHold(hold, recordFour);
holdService.addToHold(hold, recordOne);
List<NodeRef> nodes = new ArrayList<NodeRef>();
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));

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<Void>()
{
@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<NodeRef> 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<Void>()
{
@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<NodeRef> 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;
}
});
}
}

View File

@@ -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<NodeRef> holds = holdService.getHolds(filePlan);
for (NodeRef hold : holds)
{
freezeService.relinquish(hold);
holdService.deleteHold(hold);
}
}

View File

@@ -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
{

View File

@@ -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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<Void>()
{
@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<NodeRef> 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<ChildAssociationRef> list = new ArrayList<ChildAssociationRef>(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<NodeRef> 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<Map> propertyMapCaptor = ArgumentCaptor.forClass(Map.class);
ArgumentCaptor<QName> 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<QName, Serializable> propertyMap = (Map<QName, Serializable>)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()
{
}
}

View File

@@ -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<QName> set = recordService.getRecordMetadataAspects(FILE_PLAN_COMPONENT);
Set<QName> 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));