diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml
index 7a6053d037..d1dda0a2e9 100644
--- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml
+++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml
@@ -16,16 +16,13 @@
-
-
-
{http://www.alfresco.org/model/content/1.0}content
-
+
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java
index 086883657e..5ee4cff8b6 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java
@@ -29,24 +29,14 @@ package org.alfresco.module.org_alfresco_module_rm.action.dm;
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.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.repo.action.ParameterDefinitionImpl;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
-import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.repository.NodeService;
-import org.alfresco.service.namespace.QName;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
/**
* Creates a new record from an existing content object.
@@ -58,9 +48,6 @@ import org.apache.commons.logging.LogFactory;
public class CreateRecordAction extends AuditableActionExecuterAbstractBase
implements RecordsManagementModel
{
- /** Logger */
- private static Log logger = LogFactory.getLog(CreateRecordAction.class);
-
/** Action name */
public static final String NAME = "create-record";
@@ -68,23 +55,9 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase
public static final String PARAM_FILE_PLAN = "file-plan";
public static final String PARAM_HIDE_RECORD = "hide-record";
- /** Sync Model URI */
- static final String SYNC_MODEL_1_0_URI = "http://www.alfresco.org/model/sync/1.0";
- /** Synced aspect */
- static final QName ASPECT_SYNCED = QName.createQName(SYNC_MODEL_1_0_URI, "synced");
-
/** Record service */
private RecordService recordService;
- /** Node service */
- private NodeService nodeService;
-
- /** File plan service */
- private FilePlanService filePlanService;
-
- /** Dictionary service */
- private DictionaryService dictionaryService;
-
/**
* @param recordService record service
*/
@@ -93,138 +66,26 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase
this.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 dictionaryService dictionary service
- */
- public void setDictionaryService(DictionaryService dictionaryService)
- {
- this.dictionaryService = dictionaryService;
- }
-
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(final Action action, final NodeRef actionedUponNodeRef)
{
+ NodeRef filePlan = (NodeRef) action.getParameterValue(PARAM_FILE_PLAN);
- if (!nodeService.exists(actionedUponNodeRef))
+ // indicate whether the record should be hidden or not (default not)
+ boolean hideRecord = false;
+ Boolean hideRecordValue = ((Boolean) action.getParameterValue(PARAM_HIDE_RECORD));
+ if (hideRecordValue != null)
{
- // do not create record if the actioned upon node does not exist!
- if (logger.isDebugEnabled())
- {
- logger.debug("Can not create record, because " + actionedUponNodeRef.toString() + " does not exist.");
- }
+ hideRecord = hideRecordValue.booleanValue();
}
- else if (!dictionaryService.isSubClass(nodeService.getType(actionedUponNodeRef), ContentModel.TYPE_CONTENT))
- {
- // TODO eventually we should support other types .. either as record folders or as composite records
- if (logger.isDebugEnabled())
- {
- logger.debug("Can not create record, because " + actionedUponNodeRef.toString() + " is not a supported type.");
- }
- }
- else if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_RECORD))
- {
- // Do not create record if the actioned upon node is already a record!
- if (logger.isDebugEnabled())
- {
- logger.debug("Can not create record, because " + actionedUponNodeRef.toString() + " is already a record.");
- }
- }
- else if (nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_WORKING_COPY))
- {
- // We can not create records from working copies
- if (logger.isDebugEnabled())
- {
- logger.debug("Can node create record, because " + actionedUponNodeRef.toString() + " is a working copy.");
- }
- }
- else if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_RECORD_REJECTION_DETAILS))
+ synchronized (this)
{
- // can not create a record from a previously rejected one
- if (logger.isDebugEnabled())
- {
- logger.debug("Can not create record, because " + actionedUponNodeRef.toString() + " has previously been rejected.");
- }
- }
- else if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_SYNCED))
- {
- // can't declare the record if the node is sync'ed
- if (logger.isDebugEnabled())
- {
- logger.debug("Can't declare as record, because " + actionedUponNodeRef.toString() + " is synched content.");
- }
- }
- else
- {
- NodeRef filePlan = (NodeRef)action.getParameterValue(PARAM_FILE_PLAN);
- if (filePlan == null)
- {
- // TODO .. eventually make the file plan parameter required
-
- filePlan = AuthenticationUtil.runAs(new RunAsWork()
- {
- @Override
- public NodeRef doWork()
- {
- return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
- }
- }, AuthenticationUtil.getAdminUserName());
-
- // if the file plan is still null, raise an exception
- if (filePlan == null)
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Can not create record, because the default file plan can not be determined. Make sure at least one file plan has been created.");
- }
- throw new AlfrescoRuntimeException("Can not create record, because the default file plan can not be determined.");
- }
- }
- else
- {
- // verify that the provided file plan is actually a file plan
- if (!filePlanService.isFilePlan(filePlan))
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Can not create record, because the provided file plan node reference is not a file plan.");
- }
- throw new AlfrescoRuntimeException("Can not create record, because the provided file plan node reference is not a file plan.");
- }
- }
-
- // indicate whether the record should be hidden or not (default not)
- boolean hideRecord = false;
- Boolean hideRecordValue = ((Boolean)action.getParameterValue(PARAM_HIDE_RECORD));
- if (hideRecordValue != null)
- {
- hideRecord = hideRecordValue.booleanValue();
- }
-
- synchronized (this)
- {
- // create record from existing document
- recordService.createRecord(filePlan, actionedUponNodeRef, !hideRecord);
- }
+ // create record from existing document
+ recordService.createRecord(filePlan, actionedUponNodeRef, !hideRecord);
}
}
@@ -238,5 +99,4 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase
//params.add(new ParameterDefinitionImpl(PARAM_FILE_PLAN, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_FILE_PLAN)));
params.add(new ParameterDefinitionImpl(PARAM_HIDE_RECORD, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_HIDE_RECORD)));
}
-
}
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java
index 0d049b6598..52c2711314 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java
@@ -165,7 +165,7 @@ public interface RecordService
* 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
+ * @param filePlan The filePlan in which the record should be placed. filePlan can be null
in this case the default RM site will be used.
* @param nodeRef The node from which the record will be created
* @param isLinked indicates if the newly created record is linked to it's original location or not.
*/
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
index fc5491a03c..2f6459ff9f 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
@@ -135,6 +135,13 @@ public class RecordServiceImpl extends BaseBehaviourBean
/** Logger */
private static Log logger = LogFactory.getLog(RecordServiceImpl.class);
+
+ /** Sync Model URI */
+ private static final String SYNC_MODEL_1_0_URI = "http://www.alfresco.org/model/sync/1.0";
+
+ /** Synced aspect */
+ private static final QName ASPECT_SYNCED = QName.createQName(SYNC_MODEL_1_0_URI, "synced");
+
/** transation data key */
private static final String KEY_IGNORE_ON_UPDATE = "ignoreOnUpdate";
private static final String KEY_PENDING_FILLING = "pendingFilling";
@@ -238,10 +245,10 @@ public class RecordServiceImpl extends BaseBehaviourBean
/** records management container type */
private RecordsManagementContainerType recordsManagementContainerType;
-
+
/** recordable version service */
private RecordableVersionService recordableVersionService;
-
+
/** list of available record meta-data aspects and the file plan types the are applicable to */
private Map> recordMetaDataAspects;
@@ -390,7 +397,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
{
this.recordsManagementContainerType = recordsManagementContainerType;
}
-
+
/**
* @param recordableVersionService recordable version service
*/
@@ -398,7 +405,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
{
this.recordableVersionService = recordableVersionService;
}
-
+
/**
* Init method
*/
@@ -854,19 +861,12 @@ public class RecordServiceImpl extends BaseBehaviourBean
@Override
public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final boolean isLinked)
{
- ParameterCheck.mandatory("filePlan", filePlan);
+ // filePlan can be null. In this case the default RM site will be used.
ParameterCheck.mandatory("nodeRef", nodeRef);
ParameterCheck.mandatory("isLinked", isLinked);
- // first we do a sanity check to ensure that the user has at least write permissions on the document
- if (extendedPermissionService.hasPermission(nodeRef, PermissionService.WRITE) != AccessStatus.ALLOWED)
- {
- throw new AccessDeniedException("Can not create record from document, because the user " +
- AuthenticationUtil.getRunAsUser() +
- " does not have Write permissions on the doucment " +
- nodeRef.toString());
- }
-
+ recordCreationSanityCheckOnNode(nodeRef);
+ recordCreationSanityCheckOnFilePlan(filePlan);
// do the work of creating the record as the system user
AuthenticationUtil.runAsSystem(new RunAsWork()
@@ -961,6 +961,158 @@ public class RecordServiceImpl extends BaseBehaviourBean
});
}
+ /**
+ * Helper method to check the given file plan before trying to determine the unfiled records container.
+ *
+ * @param filePlan The reference of the file plan node
+ */
+ private void recordCreationSanityCheckOnFilePlan(NodeRef filePlan)
+ {
+ if (filePlan == null)
+ {
+ // TODO .. eventually make the file plan parameter required
+
+ filePlan = AuthenticationUtil.runAs(new RunAsWork()
+ {
+ @Override
+ public NodeRef doWork()
+ {
+ return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
+ }
+ }, AuthenticationUtil.getAdminUserName());
+
+ // if the file plan is still null, raise an exception
+ if (filePlan == null)
+ {
+ String msg = "Can not create record, because the default file plan can not be determined. Make sure at least one file plan has been created.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+ }
+ else
+ {
+ // verify that the provided file plan is actually a file plan
+ if (!filePlanService.isFilePlan(filePlan))
+ {
+ String msg = "Can not create record, because the provided file plan node reference is not a file plan.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+ }
+ }
+
+ /**
+ * Helper method to check the given node before trying to declare it as record
+ *
+ * @param nodeRef The reference of the node which will be declared as record
+ */
+ private void recordCreationSanityCheckOnNode(NodeRef nodeRef)
+ {
+ // first we do a sanity check to ensure that the user has at least write permissions on the document
+ if (extendedPermissionService.hasPermission(nodeRef, PermissionService.WRITE) != AccessStatus.ALLOWED)
+ {
+ String msg = "Can not create record from document, because the user " +
+ AuthenticationUtil.getRunAsUser() +
+ " does not have Write permissions on the doucment " +
+ nodeRef.toString();
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AccessDeniedException(msg);
+ }
+
+ // do not create record if the node does not exist!
+ if (!nodeService.exists(nodeRef))
+ {
+ String msg = "Can not create record, because " + nodeRef.toString() + " does not exist.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+
+ // TODO eventually we should support other types .. either as record folders or as composite records
+ if (!dictionaryService.isSubClass(nodeService.getType(nodeRef), ContentModel.TYPE_CONTENT))
+ {
+ String msg = "Can not create record, because " + nodeRef.toString() + " is not a supported type.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+
+ // Do not create record if the node is already a record!
+ if (nodeService.hasAspect(nodeRef, ASPECT_RECORD))
+ {
+ String msg = "Can not create record, because " + nodeRef.toString() + " is already a record.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+
+ // We can not create records from working copies
+ if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY))
+ {
+ String msg = "Can node create record, because " + nodeRef.toString() + " is a working copy.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+
+ // can not create a record from a previously rejected one
+ if (nodeService.hasAspect(nodeRef, ASPECT_RECORD_REJECTION_DETAILS))
+ {
+ String msg = "Can not create record, because " + nodeRef.toString() + " has previously been rejected.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+
+ // can't declare the record if the node is sync'ed
+ if (nodeService.hasAspect(nodeRef, ASPECT_SYNCED))
+ {
+ String msg = "Can't declare as record, because " + nodeRef.toString() + " is synched content.";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug(msg);
+ }
+
+ throw new AlfrescoRuntimeException(msg);
+ }
+ }
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecordFromCopy(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -999,7 +1151,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
{
recordsManagementContainerType.enable();
}
-
+
// if versionable, then remove without destroying version history,
// because it is being shared with the originating document
behaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
@@ -1011,7 +1163,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
{
behaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE);
}
-
+
// make record
makeRecord(record);
@@ -1060,8 +1212,8 @@ public class RecordServiceImpl extends BaseBehaviourBean
private NodeRef getLatestVersionRecord(NodeRef nodeRef)
{
NodeRef versionRecord = null;
-
-
+
+
recordableVersionService.createSnapshotVersion(nodeRef);
// wire record up to previous record
VersionHistory versionHistory = versionService.getVersionHistory(nodeRef);
@@ -1739,7 +1891,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
record,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name));
-
+
// recalculate disposition schedule for the record when linking it
dispositionService.recalculateNextDispositionStep(record);
}
@@ -1758,10 +1910,10 @@ public class RecordServiceImpl extends BaseBehaviourBean
private void validateLinkConditions(NodeRef record, NodeRef recordFolder)
{
// ensure that the linking record folders have compatible disposition schedules
-
+
// get the origin disposition schedule for the record, not the calculated one
DispositionSchedule recordDispositionSchedule = dispositionService.getOriginDispositionSchedule(record);
-
+
if (recordDispositionSchedule != null)
{
DispositionSchedule recordFolderDispositionSchedule = dispositionService.getDispositionSchedule(recordFolder);
@@ -1798,7 +1950,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
// remove the link
nodeService.removeChild(recordFolder, record);
-
+
// recalculate disposition schedule for record after unlinking it
dispositionService.recalculateNextDispositionStep(record);
}
@@ -1807,5 +1959,5 @@ public class RecordServiceImpl extends BaseBehaviourBean
// can only unlink a record from a record folder
throw new RecordLinkRuntimeException("Can only unlink a record from a record folder.");
}
- }
+ }
}