()
@@ -119,19 +120,23 @@ public abstract class CopyMoveFileToBaseAction extends RMActionExecuterAbstractB
{
try
{
- if(mode == CopyMoveFileToActionMode.MOVE)
+ if(mode == CopyMoveLinkFileToActionMode.MOVE)
{
fileFolderService.move(actionedUponNodeRef, finalRecordFolder, null);
}
- else
+ else if(mode == CopyMoveLinkFileToActionMode.COPY)
{
fileFolderService.copy(actionedUponNodeRef, finalRecordFolder, null);
}
+ else if(mode == CopyMoveLinkFileToActionMode.LINK)
+ {
+ recordService.link(actionedUponNodeRef, finalRecordFolder);
+ }
}
catch (FileNotFoundException fileNotFound)
{
throw new AlfrescoRuntimeException(
- "Unable to execute file to action, because the " + (mode == CopyMoveFileToActionMode.MOVE ? "move" : "copy") + " operation failed.",
+ "Unable to execute file to action, because the " + (mode == CopyMoveLinkFileToActionMode.MOVE ? "move" : "copy") + " operation failed.",
fileNotFound
);
}
@@ -142,6 +147,83 @@ public abstract class CopyMoveFileToBaseAction extends RMActionExecuterAbstractB
}
}
+ /**
+ * Return true if the passed parameters to the action are valid for the given action
+ *
+ * @param actionedUponNodeRef
+ * @param actionName
+ * @return
+ */
+ private boolean isOkToProceedWithAction(NodeRef actionedUponNodeRef, String actionName)
+ {
+ // Check that the incoming parameters are valid prior to performing any action
+ boolean okToProceed = false;
+ if(nodeService.exists(actionedUponNodeRef) && !freezeService.isFrozen(actionedUponNodeRef))
+ {
+ QName actionedUponType = nodeService.getType(actionedUponNodeRef);
+ if(ACTION_FILETO.equals(actionName))
+ {
+ // file to action can only be performed on unfiled records
+ okToProceed = !recordService.isFiled(actionedUponNodeRef) && dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT);
+ if(!okToProceed && logger.isDebugEnabled())
+ {
+ logger.debug("Unable to run " + actionName + " action on a node that isn't unfiled and a sub-class of content type");
+ }
+ }
+ else if(ACTION_LINKTO.equals(actionName))
+ {
+ // link to action can only be performed on filed records
+ okToProceed = recordService.isFiled(actionedUponNodeRef) && dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT);
+ if(!okToProceed && logger.isDebugEnabled())
+ {
+ logger.debug("Unable to run " + actionName + " action on a node that isn't filed and a sub-class of content type");
+ }
+ }
+ else
+ {
+ okToProceed = true;
+ }
+ }
+ return okToProceed;
+ }
+
+ /**
+ * Do a final validation for the parameters and the resolve target path
+ *
+ * @param actionedUponNodeRef
+ * @param target
+ * @param actionName
+ * @param targetIsUnfiledRecords
+ */
+ private void validateActionPostPathResolution(NodeRef actionedUponNodeRef, NodeRef target, String actionName, boolean targetIsUnfiledRecords)
+ {
+ QName actionedUponType = nodeService.getType(actionedUponNodeRef);
+ // now we have the reference to the target folder we can do some final checks to see if the action is valid
+ if (target == null)
+ {
+ throw new AlfrescoRuntimeException("Unable to run " + actionName + " action, because the destination record folder could not be determined.");
+ }
+ if(targetIsUnfiledRecords)
+ {
+ QName targetFolderType = nodeService.getType(target);
+ if(!TYPE_UNFILED_RECORD_CONTAINER.equals(targetFolderType) && !TYPE_UNFILED_RECORD_FOLDER.equals(targetFolderType))
+ {
+ throw new AlfrescoRuntimeException("Unable to run " + actionName + " action, because the destination record folder is an inappropriate type.");
+ }
+ }
+ else
+ {
+ if(recordFolderService.isRecordFolder(target) && !dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT) && (recordFolderService.isRecordFolder(actionedUponNodeRef) || filePlanService.isRecordCategory(actionedUponNodeRef)))
+ {
+ throw new AlfrescoRuntimeException("Unable to run " + actionName + " action, because the destination record folder is an inappropriate type. A record folder cannot contain another folder or a category");
+ }
+ else if(filePlanService.isRecordCategory(target) && dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT))
+ {
+ throw new AlfrescoRuntimeException("Unable to run " + actionName + " action, because the destination record folder is an inappropriate type. A record category cannot contain a record");
+ }
+ }
+ }
+
/**
* Create or resolve the path specified in the action's path parameter
*
@@ -197,12 +279,8 @@ public abstract class CopyMoveFileToBaseAction extends RMActionExecuterAbstractB
if(create)
{
creating = true;
- nodeRef = createChild(
- action,
- parent,
- childName,
- targetisUnfiledRecords,
- lastPathElement && (ContentModel.TYPE_CONTENT.equals(nodeService.getType(actionedUponNodeRef)) || RecordsManagementModel.TYPE_NON_ELECTRONIC_DOCUMENT.equals(nodeService.getType(actionedUponNodeRef))));
+ boolean lastAsFolder = lastPathElement && (ContentModel.TYPE_CONTENT.equals(nodeService.getType(actionedUponNodeRef)) || RecordsManagementModel.TYPE_NON_ELECTRONIC_DOCUMENT.equals(nodeService.getType(actionedUponNodeRef)));
+ nodeRef = createChild(action, parent, childName, targetisUnfiledRecords, lastAsFolder);
}
else
{
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyToAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyToAction.java
index 23da848210..11d2a1653d 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyToAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyToAction.java
@@ -7,7 +7,7 @@ package org.alfresco.module.org_alfresco_module_rm.action.impl;
* @author Mark Hibbins
* @since 2.2
*/
-public class CopyToAction extends CopyMoveFileToBaseAction
+public class CopyToAction extends CopyMoveLinkFileToBaseAction
{
/** action name */
public static final String NAME = "copyTo";
@@ -16,6 +16,6 @@ public class CopyToAction extends CopyMoveFileToBaseAction
public void init()
{
super.init();
- this.mode = CopyMoveFileToActionMode.COPY;
+ this.mode = CopyMoveLinkFileToActionMode.COPY;
}
}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java
index fe365d48da..3f6e61ee15 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java
@@ -7,7 +7,7 @@ package org.alfresco.module.org_alfresco_module_rm.action.impl;
* @author Roy Wetherall
* @since 2.1
*/
-public class FileToAction extends CopyMoveFileToBaseAction
+public class FileToAction extends CopyMoveLinkFileToBaseAction
{
/** action name */
public static final String NAME = "fileTo";
@@ -16,6 +16,6 @@ public class FileToAction extends CopyMoveFileToBaseAction
public void init()
{
super.init();
- this.mode = CopyMoveFileToActionMode.MOVE;
+ this.mode = CopyMoveLinkFileToActionMode.MOVE;
}
}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/LinkToAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/LinkToAction.java
new file mode 100644
index 0000000000..707e7295c6
--- /dev/null
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/LinkToAction.java
@@ -0,0 +1,21 @@
+package org.alfresco.module.org_alfresco_module_rm.action.impl;
+
+
+/**
+ * Link To action implementation.
+ *
+ * @author Mark Hibbins
+ * @since 2.2
+ */
+public class LinkToAction extends CopyMoveLinkFileToBaseAction
+{
+ /** action name */
+ public static final String NAME = "linkTo";
+
+ @Override
+ public void init()
+ {
+ super.init();
+ this.mode = CopyMoveLinkFileToActionMode.LINK;
+ }
+}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/MoveToAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/MoveToAction.java
index 114cd099f0..429c6353d8 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/MoveToAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/MoveToAction.java
@@ -7,7 +7,7 @@ package org.alfresco.module.org_alfresco_module_rm.action.impl;
* @author Mark Hibbins
* @since 2.2
*/
-public class MoveToAction extends CopyMoveFileToBaseAction
+public class MoveToAction extends CopyMoveLinkFileToBaseAction
{
/** action name */
public static final String NAME = "moveTo";
@@ -16,6 +16,6 @@ public class MoveToAction extends CopyMoveFileToBaseAction
public void init()
{
super.init();
- this.mode = CopyMoveFileToActionMode.MOVE;
+ this.mode = CopyMoveLinkFileToActionMode.MOVE;
}
}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java
index 45a1d392a3..6603a813b4 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java
@@ -39,19 +39,19 @@ public interface RecordService
/**
* Register a record metadata aspect.
*
- * The file plan type indicates which file plan type the aspect applied to. Null indicates that
+ * The file plan type indicates which file plan type the aspect applied to. Null indicates that
* the aspect applies to rma:filePlan.
*
- * A record metadata aspect can be registered more than once if it applies to more than one
+ * A record metadata aspect can be registered more than once if it applies to more than one
* file plan type.
- *
+ *
* @param recordMetadataAspect record metadata aspect qualified name
* @param filePlanType file plan type
- *
+ *
* @since 2.2
*/
void registerRecordMetadataAspect(QName recordMetadataAspect, QName filePlanType);
-
+
/**
* Disables the property editable check.
*/
@@ -66,35 +66,35 @@ public interface RecordService
* Gets a list of all the record meta-data aspects
*
* @return {@link Set}<{@link QName}> list of record meta-data aspects
- *
+ *
* @deprecated since 2.2, file plan component required to provide context
*/
@Deprecated
Set getRecordMetaDataAspects();
-
+
/**
* Gets a list of all the record metadata aspects relevant to the file plan type of the
* file plan component provided.
*
- * If a null context is provided all record meta-data aspects are returned, but this is not
+ * If a null context is provided all record meta-data aspects are returned, but this is not
* recommended.
*
* @param nodeRef node reference to file plan component providing context
* @return {@link Set}<{@link QName}> list of record meta-data aspects
- *
+ *
* @since 2.2
*/
Set getRecordMetadataAspects(NodeRef nodeRef);
-
+
/**
* Gets a list of all the record metadata aspect that relate to the provided file plan type.
*
- * If null is provided for the file plan type then record metadata aspects for the default
+ * If null is provided for the file plan type then record metadata aspects for the default
* file plan type (rma:filePlan) are returned.
- *
+ *
* @param filePlanType file plan type
* @return{@link Set}<{@link QName}> list of record meta-data aspects
- *
+ *
* @since 2.2
*/
Set getRecordMetadataAspects(QName filePlanType);
@@ -214,4 +214,12 @@ public interface RecordService
* @param nodeRef The document node reference from which a record will be created
*/
void makeRecord(NodeRef nodeRef);
+
+ /**
+ * Creates a link for the specified document in target
+ *
+ * @param nodeRef The document node reference for which a link will be created
+ * @param folder The folder in which the link will be created
+ */
+ void link(NodeRef nodeRef, NodeRef folder);
}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
index 46bb53f4ca..48f0f987ae 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java
@@ -635,7 +635,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
if (getRecordMetadataAspectsMap().containsKey(recordMetadataAspect))
{
// get the current set of file plan types for this aspect
- filePlanTypes = (Set)getRecordMetadataAspectsMap().get(recordMetadataAspect);
+ filePlanTypes = getRecordMetadataAspectsMap().get(recordMetadataAspect);
}
else
{
@@ -717,6 +717,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
/**
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, boolean)
*/
+ @Override
public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final boolean isLinked)
{
ParameterCheck.mandatory("filePlan", filePlan);
@@ -773,7 +774,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
// save the information about the originating details
Map aspectProperties = new HashMap(3);
- aspectProperties.put(PROP_RECORD_ORIGINATING_LOCATION, (Serializable) parentAssoc.getParentRef());
+ aspectProperties.put(PROP_RECORD_ORIGINATING_LOCATION, parentAssoc.getParentRef());
aspectProperties.put(PROP_RECORD_ORIGINATING_USER_ID, userId);
aspectProperties.put(PROP_RECORD_ORIGINATING_CREATION_DATE, new Date());
nodeService.addAspect(nodeRef, ASPECT_RECORD_ORIGINATING_DETAILS, aspectProperties);
@@ -1391,4 +1392,19 @@ public class RecordServiceImpl extends BaseBehaviourBean
logger.info(I18NUtil.getMessage(MSG_NODE_HAS_ASPECT, nodeRef.toString(), typeQName.toString()));
}
}
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#link(NodeRef, NodeRef)
+ */
+ @Override
+ public void link(NodeRef nodeRef, NodeRef folder)
+ {
+ ParameterCheck.mandatory("nodeRef", nodeRef);
+ ParameterCheck.mandatory("folder", folder);
+
+ if(isRecord(nodeRef) && isRecordFolder(folder))
+ {
+ nodeService.addChild(folder, nodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, nodeService.getProperty(nodeRef, ContentModel.PROP_NAME).toString()));
+ }
+ }
}