mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge branch 'feature/RM-6792_AddLocnParamToDeclareAsRec' into 'master'
RM-6792 Optional Record Locn See merge request records-management/records-management!1168
This commit is contained in:
@@ -18,6 +18,9 @@
|
|||||||
<!-- TODO rename -->
|
<!-- TODO rename -->
|
||||||
<bean id="create-record" parent="action-executer" class="org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction">
|
<bean id="create-record" parent="action-executer" class="org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction">
|
||||||
<property name="recordService" ref="RecordService" />
|
<property name="recordService" ref="RecordService" />
|
||||||
|
<property name="authenticationUtil" ref="rm.authenticationUtil" />
|
||||||
|
<property name="filePlanService" ref="FilePlanService" />
|
||||||
|
<property name="nodeService" ref="NodeService" />
|
||||||
<property name="applicableTypes">
|
<property name="applicableTypes">
|
||||||
<list>
|
<list>
|
||||||
<value>{http://www.alfresco.org/model/content/1.0}content</value>
|
<value>{http://www.alfresco.org/model/content/1.0}content</value>
|
||||||
|
@@ -48,9 +48,10 @@ isRecordType.description=Records have a specified record type
|
|||||||
#
|
#
|
||||||
# Declare As Record
|
# Declare As Record
|
||||||
create-record.title=Declare as Record
|
create-record.title=Declare as Record
|
||||||
create-record.description=Declares file as a record
|
create-record.description=Declares file as a record and optionally files it
|
||||||
create-record.file-plan.display-label=File Plan
|
create-record.file-plan.display-label=File Plan
|
||||||
create-record.hide-record.display-label=Hide Record
|
create-record.hide-record.display-label=Hide Record
|
||||||
|
create-record.path.display-label=Destination Record Folder Path
|
||||||
# Declare As Version Record
|
# Declare As Version Record
|
||||||
declare-as-version-record.title=Declare Version as Record
|
declare-as-version-record.title=Declare Version as Record
|
||||||
declare-as-version-record.description=Declares this version of the file as a record
|
declare-as-version-record.description=Declares this version of the file as a record
|
||||||
|
@@ -27,16 +27,27 @@
|
|||||||
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.action.dm;
|
package org.alfresco.module.org_alfresco_module_rm.action.dm;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.action.AuditableActionExecuterAbstractBase;
|
import org.alfresco.module.org_alfresco_module_rm.action.AuditableActionExecuterAbstractBase;
|
||||||
|
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.model.RecordsManagementModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
|
||||||
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new record from an existing content object.
|
* Creates a new record from an existing content object.
|
||||||
@@ -48,16 +59,53 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
public class CreateRecordAction extends AuditableActionExecuterAbstractBase
|
public class CreateRecordAction extends AuditableActionExecuterAbstractBase
|
||||||
implements RecordsManagementModel
|
implements RecordsManagementModel
|
||||||
{
|
{
|
||||||
|
/** Logger */
|
||||||
|
private static final Log LOGGER = LogFactory.getLog(CreateRecordAction.class);
|
||||||
|
|
||||||
/** Action name */
|
/** Action name */
|
||||||
public static final String NAME = "create-record";
|
public static final String NAME = "create-record";
|
||||||
|
|
||||||
/** Parameter names */
|
/** Parameter names */
|
||||||
public static final String PARAM_FILE_PLAN = "file-plan";
|
public static final String PARAM_FILE_PLAN = "file-plan";
|
||||||
public static final String PARAM_HIDE_RECORD = "hide-record";
|
public static final String PARAM_HIDE_RECORD = "hide-record";
|
||||||
|
public static final String PARAM_PATH = "path";
|
||||||
|
|
||||||
|
/** Node service */
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
/** File plan service */
|
||||||
|
private FilePlanService filePlanService;
|
||||||
|
|
||||||
|
/** Authentication util */
|
||||||
|
private AuthenticationUtil authenticationUtil;
|
||||||
|
|
||||||
/** Record service */
|
/** Record service */
|
||||||
private RecordService recordService;
|
private RecordService recordService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param nodeService node service
|
||||||
|
*/
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param filePlanService file plan service
|
||||||
|
*/
|
||||||
|
public void setFilePlanService(FilePlanService filePlanService)
|
||||||
|
{
|
||||||
|
this.filePlanService = filePlanService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param authenticationUtil authentication util
|
||||||
|
*/
|
||||||
|
public void setAuthenticationUtil(AuthenticationUtil authenticationUtil)
|
||||||
|
{
|
||||||
|
this.authenticationUtil = authenticationUtil;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param recordService record service
|
* @param recordService record service
|
||||||
*/
|
*/
|
||||||
@@ -74,6 +122,14 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase
|
|||||||
{
|
{
|
||||||
NodeRef filePlan = (NodeRef) action.getParameterValue(PARAM_FILE_PLAN);
|
NodeRef filePlan = (NodeRef) action.getParameterValue(PARAM_FILE_PLAN);
|
||||||
|
|
||||||
|
// resolve destination record folder if path supplied
|
||||||
|
NodeRef destinationRecordFolder = null;
|
||||||
|
String pathParameter = (String) action.getParameterValue(PARAM_PATH);
|
||||||
|
if (pathParameter != null && !pathParameter.isEmpty())
|
||||||
|
{
|
||||||
|
destinationRecordFolder = resolvePath(filePlan, pathParameter);
|
||||||
|
}
|
||||||
|
|
||||||
// indicate whether the record should be hidden or not (default not)
|
// indicate whether the record should be hidden or not (default not)
|
||||||
boolean hideRecord = false;
|
boolean hideRecord = false;
|
||||||
Boolean hideRecordValue = ((Boolean) action.getParameterValue(PARAM_HIDE_RECORD));
|
Boolean hideRecordValue = ((Boolean) action.getParameterValue(PARAM_HIDE_RECORD));
|
||||||
@@ -85,7 +141,12 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase
|
|||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
// create record from existing document
|
// create record from existing document
|
||||||
recordService.createRecord(filePlan, actionedUponNodeRef, !hideRecord);
|
recordService.createRecord(filePlan, actionedUponNodeRef, destinationRecordFolder, !hideRecord);
|
||||||
|
|
||||||
|
if (destinationRecordFolder != null)
|
||||||
|
{
|
||||||
|
recordService.file(actionedUponNodeRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +158,105 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase
|
|||||||
{
|
{
|
||||||
// NOTE: commented out for now so that it doesn't appear in the UI ... enable later when multi-file plan support is added
|
// NOTE: commented out for now so that it doesn't appear in the UI ... enable later when multi-file plan support is added
|
||||||
//params.add(new ParameterDefinitionImpl(PARAM_FILE_PLAN, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_FILE_PLAN)));
|
//params.add(new ParameterDefinitionImpl(PARAM_FILE_PLAN, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_FILE_PLAN)));
|
||||||
|
params.add(new ParameterDefinitionImpl(PARAM_PATH, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_PATH)));
|
||||||
params.add(new ParameterDefinitionImpl(PARAM_HIDE_RECORD, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_HIDE_RECORD)));
|
params.add(new ParameterDefinitionImpl(PARAM_HIDE_RECORD, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_HIDE_RECORD)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get the target record folder node reference from the action path parameter
|
||||||
|
*
|
||||||
|
* @param filePlan The filePlan containing the path
|
||||||
|
* @param pathParameter The path
|
||||||
|
* @return The NodeRef of the resolved path
|
||||||
|
*/
|
||||||
|
private NodeRef resolvePath(NodeRef filePlan, final String pathParameter)
|
||||||
|
{
|
||||||
|
NodeRef destinationFolder;
|
||||||
|
|
||||||
|
if (filePlan == null)
|
||||||
|
{
|
||||||
|
filePlan = getDefaultFilePlan();
|
||||||
|
}
|
||||||
|
|
||||||
|
final String[] pathElementsArray = StringUtils.tokenizeToStringArray(pathParameter, "/", false, true);
|
||||||
|
if ((pathElementsArray != null) && (pathElementsArray.length > 0))
|
||||||
|
{
|
||||||
|
destinationFolder = resolvePath(filePlan, Arrays.asList(pathElementsArray));
|
||||||
|
|
||||||
|
// destination must be a record folder
|
||||||
|
QName nodeType = nodeService.getType(destinationFolder);
|
||||||
|
if (!nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER))
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path is not a record folder.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path could not be found.");
|
||||||
|
}
|
||||||
|
return destinationFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to recursively get the next path element node reference from the action path parameter
|
||||||
|
*
|
||||||
|
* @param parent The parent of the path elements
|
||||||
|
* @param pathElements The path elements still to be resolved
|
||||||
|
* @return The NodeRef of the resolved path element
|
||||||
|
*/
|
||||||
|
private NodeRef resolvePath(NodeRef parent, List<String> pathElements)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef;
|
||||||
|
String childName = pathElements.get(0);
|
||||||
|
|
||||||
|
nodeRef = nodeService.getChildByName(parent, ContentModel.ASSOC_CONTAINS, childName);
|
||||||
|
|
||||||
|
if (nodeRef == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path could not be found.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QName nodeType = nodeService.getType(nodeRef);
|
||||||
|
if (nodeType.equals(RecordsManagementModel.TYPE_HOLD_CONTAINER) ||
|
||||||
|
nodeType.equals(RecordsManagementModel.TYPE_TRANSFER_CONTAINER) ||
|
||||||
|
nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER))
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path is invalid.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pathElements.size() > 1)
|
||||||
|
{
|
||||||
|
nodeRef = resolvePath(nodeRef, pathElements.subList(1, pathElements.size()));
|
||||||
|
}
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get the default RM filePlan
|
||||||
|
*
|
||||||
|
* @return The NodeRef of the default RM filePlan
|
||||||
|
*/
|
||||||
|
private NodeRef getDefaultFilePlan()
|
||||||
|
{
|
||||||
|
NodeRef filePlan = authenticationUtil.runAsSystem(new org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork<NodeRef>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public NodeRef doWork()
|
||||||
|
{
|
||||||
|
return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// if the file plan is still null, raise an exception
|
||||||
|
if (filePlan == null)
|
||||||
|
{
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
|
{
|
||||||
|
LOGGER.debug("Unable to execute " + NAME + " action, because the fileplan path could not be determined. Make sure at least one file plan has been created.");
|
||||||
|
throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the fileplan path could not be determined.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filePlan;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -159,6 +159,31 @@ public interface RecordService
|
|||||||
*/
|
*/
|
||||||
boolean isDeclared(NodeRef nodeRef);
|
boolean isDeclared(NodeRef nodeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new record from an existing node and files it into the specified location.
|
||||||
|
* <p>
|
||||||
|
* Note that the node reference of the record will be the same as the original
|
||||||
|
* document.
|
||||||
|
*
|
||||||
|
* @param filePlan The filePlan in which the record should be placed. filePlan can be <code>null</code> in this case the default RM site will be used.
|
||||||
|
* @param nodeRef The node from which the record will be created
|
||||||
|
* @param locationNodeRef The container in which the record will be created
|
||||||
|
* @param isLinked indicates if the newly created record is linked to it's original location or not.
|
||||||
|
*/
|
||||||
|
void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef locationNodeRef, final boolean isLinked);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new record from an existing node and files it into the specified location.
|
||||||
|
* <p>
|
||||||
|
* Note that the node reference of the record will be the same as the original
|
||||||
|
* document.
|
||||||
|
*
|
||||||
|
* @param filePlan The filePlan in which the record should be placed. filePlan can be <code>null</code> in this case the default RM site will be used.
|
||||||
|
* @param nodeRef The node from which the record will be created
|
||||||
|
* @param locationNodeRef The container in which the record will be created
|
||||||
|
*/
|
||||||
|
void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef locationNodeRef);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new unfiled record from an existing node.
|
* Creates a new unfiled record from an existing node.
|
||||||
* <p>
|
* <p>
|
||||||
|
@@ -861,8 +861,27 @@ public class RecordServiceImpl extends BaseBehaviourBean
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final boolean isLinked)
|
public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final boolean isLinked)
|
||||||
|
{
|
||||||
|
createRecord(filePlan, nodeRef, null, isLinked);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef destinationNodeRef)
|
||||||
|
{
|
||||||
|
createRecord(filePlan, nodeRef, destinationNodeRef, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, boolean)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef destinationNodeRef, final boolean isLinked)
|
||||||
{
|
{
|
||||||
// filePlan can be null. In this case the default RM site will be used.
|
// filePlan can be null. In this case the default RM site will be used.
|
||||||
|
// destinationNodeRef can be null. In this case the unfiled record container will be used
|
||||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
ParameterCheck.mandatory("isLinked", isLinked);
|
ParameterCheck.mandatory("isLinked", isLinked);
|
||||||
|
|
||||||
@@ -882,11 +901,33 @@ public class RecordServiceImpl extends BaseBehaviourBean
|
|||||||
ruleService.disableRuleType("outbound");
|
ruleService.disableRuleType("outbound");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// get the new record container for the file plan
|
NodeRef newRecordContainer = destinationNodeRef;
|
||||||
NodeRef newRecordContainer = filePlanService.getUnfiledContainer(checkedFilePlan);
|
// if optional location not specified, use the unfiledContainer
|
||||||
if (newRecordContainer == null)
|
if (newRecordContainer == null)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found.");
|
// get the unfiled record container node for the file plan
|
||||||
|
newRecordContainer = filePlanService.getUnfiledContainer(checkedFilePlan);
|
||||||
|
if (newRecordContainer == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to create record, because record container could not be found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if optional location supplied, check that it is a valid record folder, unfiled record container or folder
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final QName nodeType = nodeService.getType(newRecordContainer);
|
||||||
|
if(!(nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER) ||
|
||||||
|
nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER) ||
|
||||||
|
nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER)))
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to create record, because container is not a valid type for new record.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean isClosed = (Boolean) nodeService.getProperty(newRecordContainer, PROP_IS_CLOSED);
|
||||||
|
if (isClosed != null && isClosed)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to create record, because container is closed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the documents readers and writers
|
// get the documents readers and writers
|
||||||
|
@@ -31,6 +31,7 @@ import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction;
|
|||||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,6 +53,13 @@ public class CreateRecordActionTest extends BaseRMTestCase
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test create record action
|
||||||
|
*
|
||||||
|
* Given a collaboration site document
|
||||||
|
* When the create record action is executed for that document
|
||||||
|
* Then a record is created for it
|
||||||
|
*/
|
||||||
public void testCreateRecordAction()
|
public void testCreateRecordAction()
|
||||||
{
|
{
|
||||||
doTestInTransaction(new Test<Void>()
|
doTestInTransaction(new Test<Void>()
|
||||||
@@ -75,8 +83,38 @@ public class CreateRecordActionTest extends BaseRMTestCase
|
|||||||
|
|
||||||
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(dmDocument, RMPermissionModel.READ_RECORDS));
|
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(dmDocument, RMPermissionModel.READ_RECORDS));
|
||||||
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS));
|
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS));
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
dmCollaborator);
|
dmCollaborator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCreateRecordActionWithLocation()
|
||||||
|
{
|
||||||
|
doTestInTransaction(new Test<Void>()
|
||||||
|
{
|
||||||
|
public Void run()
|
||||||
|
{
|
||||||
|
assertFalse(recordService.isRecord(dmDocument1));
|
||||||
|
|
||||||
|
Action action = actionService.createAction(CreateRecordAction.NAME);
|
||||||
|
action.setParameterValue(CreateRecordAction.PARAM_HIDE_RECORD, false);
|
||||||
|
action.setParameterValue(CreateRecordAction.PARAM_FILE_PLAN, filePlan);
|
||||||
|
action.setParameterValue(CreateRecordAction.PARAM_PATH, "rmContainer/rmFolder");
|
||||||
|
actionService.executeAction(action, dmDocument1);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test(Void result) throws Exception
|
||||||
|
{
|
||||||
|
assertTrue(recordService.isRecord(dmDocument1));
|
||||||
|
assertTrue(recordService.isFiled(dmDocument1));
|
||||||
|
|
||||||
|
// is the record folder the primary parent of the filed record
|
||||||
|
NodeRef parent = nodeService.getPrimaryParent(dmDocument1).getParentRef();
|
||||||
|
assertEquals(rmFolder, parent);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ADMIN_USER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -123,6 +123,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
|
|
||||||
/** test data */
|
/** test data */
|
||||||
protected String NAME_DM_DOCUMENT = "collabDocument.txt";
|
protected String NAME_DM_DOCUMENT = "collabDocument.txt";
|
||||||
|
protected String NAME_DM_DOCUMENT1 = "collabDocument1.txt";
|
||||||
|
|
||||||
/** admin user */
|
/** admin user */
|
||||||
protected static final String ADMIN_USER = "admin";
|
protected static final String ADMIN_USER = "admin";
|
||||||
@@ -273,7 +274,9 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
protected SiteInfo collaborationSite;
|
protected SiteInfo collaborationSite;
|
||||||
protected NodeRef documentLibrary;
|
protected NodeRef documentLibrary;
|
||||||
protected NodeRef dmFolder;
|
protected NodeRef dmFolder;
|
||||||
|
protected NodeRef dmFolder1;
|
||||||
protected NodeRef dmDocument;
|
protected NodeRef dmDocument;
|
||||||
|
protected NodeRef dmDocument1;
|
||||||
|
|
||||||
/** collaboration site users */
|
/** collaboration site users */
|
||||||
protected String dmConsumer;
|
protected String dmConsumer;
|
||||||
@@ -779,6 +782,8 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
// create a folder and documents
|
// create a folder and documents
|
||||||
dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef();
|
dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef();
|
||||||
dmDocument = fileFolderService.create(dmFolder, NAME_DM_DOCUMENT, ContentModel.TYPE_CONTENT).getNodeRef();
|
dmDocument = fileFolderService.create(dmFolder, NAME_DM_DOCUMENT, ContentModel.TYPE_CONTENT).getNodeRef();
|
||||||
|
dmFolder1 = fileFolderService.create(documentLibrary, "collabFolder1", ContentModel.TYPE_FOLDER).getNodeRef();
|
||||||
|
dmDocument1 = fileFolderService.create(dmFolder1, NAME_DM_DOCUMENT1, ContentModel.TYPE_CONTENT).getNodeRef();
|
||||||
|
|
||||||
dmConsumer = GUID.generate();
|
dmConsumer = GUID.generate();
|
||||||
dmConsumerNodeRef = createPerson(dmConsumer);
|
dmConsumerNodeRef = createPerson(dmConsumer);
|
||||||
|
@@ -45,12 +45,15 @@ import java.util.HashSet;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
|
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||||
import org.alfresco.repo.policy.Behaviour;
|
import org.alfresco.repo.policy.Behaviour;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
@@ -69,6 +72,10 @@ public class RecordServiceImplUnitTest extends BaseUnitTest
|
|||||||
{
|
{
|
||||||
private NodeRef nonStandardFilePlanComponent;
|
private NodeRef nonStandardFilePlanComponent;
|
||||||
private NodeRef nonStandardFilePlan;
|
private NodeRef nonStandardFilePlan;
|
||||||
|
private NodeRef dmNodeRef;
|
||||||
|
private NodeRef unfiledRecordContainer;
|
||||||
|
private NodeRef unfiledRecordFolder;
|
||||||
|
private ChildAssociationRef parentAssoc;
|
||||||
|
|
||||||
private static QName TYPE_MY_FILE_PLAN = generateQName();
|
private static QName TYPE_MY_FILE_PLAN = generateQName();
|
||||||
private static QName ASPECT_FOR_FILE_PLAN = generateQName();
|
private static QName ASPECT_FOR_FILE_PLAN = generateQName();
|
||||||
@@ -84,6 +91,10 @@ public class RecordServiceImplUnitTest extends BaseUnitTest
|
|||||||
|
|
||||||
nonStandardFilePlanComponent = generateNodeRef(TYPE_RECORD_CATEGORY);
|
nonStandardFilePlanComponent = generateNodeRef(TYPE_RECORD_CATEGORY);
|
||||||
nonStandardFilePlan = generateNodeRef(TYPE_MY_FILE_PLAN);
|
nonStandardFilePlan = generateNodeRef(TYPE_MY_FILE_PLAN);
|
||||||
|
dmNodeRef = generateNodeRef(TYPE_CONTENT);
|
||||||
|
unfiledRecordContainer = generateNodeRef(TYPE_UNFILED_RECORD_CONTAINER);
|
||||||
|
unfiledRecordFolder = generateNodeRef(TYPE_UNFILED_RECORD_FOLDER);
|
||||||
|
parentAssoc = mock(ChildAssociationRef.class);
|
||||||
|
|
||||||
// set-up node service
|
// set-up node service
|
||||||
when(mockedNodeService.getProperty(nonStandardFilePlanComponent, PROP_ROOT_NODEREF)).thenReturn(nonStandardFilePlan);
|
when(mockedNodeService.getProperty(nonStandardFilePlanComponent, PROP_ROOT_NODEREF)).thenReturn(nonStandardFilePlan);
|
||||||
@@ -462,4 +473,103 @@ public class RecordServiceImplUnitTest extends BaseUnitTest
|
|||||||
// verify
|
// verify
|
||||||
verify(values, never()).add(nodeRef);
|
verify(values, never()).add(nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a file that is not yet a record
|
||||||
|
* When I create the record without specifying a location
|
||||||
|
* Then the record is created in the unfiled record container
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void createRecordIntoUnfiledRecordContainer()
|
||||||
|
{
|
||||||
|
mocksForRecordCreation();
|
||||||
|
|
||||||
|
// create the record
|
||||||
|
recordService.createRecord(filePlan, dmNodeRef);
|
||||||
|
|
||||||
|
// verify record was created in unfiled record container
|
||||||
|
verify(mockedNodeService, times(1)).moveNode(
|
||||||
|
dmNodeRef,
|
||||||
|
unfiledRecordContainer,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
parentAssoc.getQName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a file that is not yet a record
|
||||||
|
* When I create the record specifying the unfiled record container
|
||||||
|
* Then the record is created in the unfiled record container
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void createRecordIntoSpecifiedUnfiledRecordContainer()
|
||||||
|
{
|
||||||
|
mocksForRecordCreation();
|
||||||
|
|
||||||
|
// create the record
|
||||||
|
recordService.createRecord(filePlan, dmNodeRef, unfiledRecordContainer);
|
||||||
|
|
||||||
|
// verify record was created in specified unfiled record container
|
||||||
|
verify(mockedNodeService, times(1)).moveNode(
|
||||||
|
dmNodeRef,
|
||||||
|
unfiledRecordContainer,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
parentAssoc.getQName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a file that is not yet a record
|
||||||
|
* When I create the record specifying a location
|
||||||
|
* Then the record is created in the specified record folder
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void createRecordIntoSpecifiedRecordFolder()
|
||||||
|
{
|
||||||
|
mocksForRecordCreation();
|
||||||
|
|
||||||
|
// create the record
|
||||||
|
recordService.createRecord(filePlan, dmNodeRef, recordFolder);
|
||||||
|
|
||||||
|
// verify record was created in specified record folder
|
||||||
|
verify(mockedNodeService, times(1)).moveNode(
|
||||||
|
dmNodeRef,
|
||||||
|
recordFolder,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
parentAssoc.getQName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a file that is not yet a record
|
||||||
|
* When I create the record specifying an invalid location
|
||||||
|
* Then an exception is thrown
|
||||||
|
*/
|
||||||
|
@Test(expected=AlfrescoRuntimeException.class)
|
||||||
|
public void createRecordIntoInvalidRecordFolder()
|
||||||
|
{
|
||||||
|
mocksForRecordCreation();
|
||||||
|
NodeRef recordCategory = generateNodeRef(TYPE_RECORD_CATEGORY);
|
||||||
|
|
||||||
|
// create the record
|
||||||
|
recordService.createRecord(filePlan, dmNodeRef, recordCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper method to set up the mocks for record creation */
|
||||||
|
private void mocksForRecordCreation()
|
||||||
|
{
|
||||||
|
when(mockedNodeService.getPrimaryParent(dmNodeRef))
|
||||||
|
.thenReturn(parentAssoc);
|
||||||
|
when(parentAssoc.getQName()).thenReturn(generateQName());
|
||||||
|
|
||||||
|
// mocks for sanity checks on node and fileplan
|
||||||
|
when(mockedExtendedPermissionService.hasPermission(dmNodeRef, PermissionService.WRITE)).thenReturn(AccessStatus.ALLOWED);
|
||||||
|
when(mockedDictionaryService.isSubClass(mockedNodeService.getType(dmNodeRef), ContentModel.TYPE_CONTENT)).thenReturn(true);
|
||||||
|
when(mockedFilePlanService.isFilePlan(nonStandardFilePlan)).thenReturn(true);
|
||||||
|
|
||||||
|
// mocks for policies
|
||||||
|
doNothing().when(recordService).invokeBeforeRecordDeclaration(dmNodeRef);
|
||||||
|
doNothing().when(recordService).invokeOnRecordDeclaration(dmNodeRef);
|
||||||
|
|
||||||
|
when(mockedFilePlanService.getUnfiledContainer(filePlan)).thenReturn(unfiledRecordContainer);
|
||||||
|
|
||||||
|
when(mockedVersionService.getVersionHistory(dmNodeRef)).thenReturn(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -72,10 +72,12 @@ import org.alfresco.service.cmr.repository.CopyService;
|
|||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.rule.RuleService;
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.cmr.security.AuthorityService;
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.cmr.security.OwnableService;
|
import org.alfresco.service.cmr.security.OwnableService;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.cmr.version.VersionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.QNamePattern;
|
import org.alfresco.service.namespace.QNamePattern;
|
||||||
@@ -122,6 +124,8 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
|||||||
@Mock(name="copyService") protected CopyService mockedCopyService;
|
@Mock(name="copyService") protected CopyService mockedCopyService;
|
||||||
@Mock(name="fileFolderService") protected FileFolderService mockedFileFolderService;
|
@Mock(name="fileFolderService") protected FileFolderService mockedFileFolderService;
|
||||||
@Mock(name="modelSecurityService") protected ModelSecurityService mockedModelSecurityService;
|
@Mock(name="modelSecurityService") protected ModelSecurityService mockedModelSecurityService;
|
||||||
|
@Mock(name="ruleService") protected RuleService mockedRuleService;
|
||||||
|
@Mock(name="versionService") protected VersionService mockedVersionService;
|
||||||
|
|
||||||
/** rm service mocks */
|
/** rm service mocks */
|
||||||
@Mock(name="filePlanService") protected FilePlanService mockedFilePlanService;
|
@Mock(name="filePlanService") protected FilePlanService mockedFilePlanService;
|
||||||
|
Reference in New Issue
Block a user