diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml index 501c4d11a8..5a4e3964eb 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml @@ -32,6 +32,7 @@ RECORD_CATEGORY RECORD_FOLDER + UNFILED_RECORD_CONTAINER @@ -66,14 +67,14 @@ - + - + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml index afc16a7923..806aafd6b0 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml @@ -48,37 +48,38 @@ - + - + - + - + + - + - - - + + + - + - - - + + + - + - - - - + + + + @@ -89,51 +90,51 @@ - + - + - - - + + + - + - - - + + + - - + + - + - + - + - + - + - + - + - + - + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 589a4d6eea..2a92236494 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -1240,6 +1240,7 @@ org.alfresco.module.org_alfresco_module_rm.record.RecordService.isPropertyEditable=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.record.RecordService.isMetadataStub=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.record.RecordService.getRecords=RM.Read.0,AFTER_RM.FilterNode + org.alfresco.module.org_alfresco_module_rm.record.RecordService.makeRecord=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.*=RM_DENY ]]> @@ -1383,8 +1384,8 @@ - diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml index e93bccb8e6..9f59ba76d3 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml @@ -317,6 +317,7 @@ RECORD_FOLDER + UNFILED_RECORD_CONTAINER @@ -573,6 +574,7 @@ RECORD_CATEGORY + UNFILED_RECORD_CONTAINER diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/rm-filters.lib.js b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/rm-filters.lib.js index 700e3655a2..e43b5a60bc 100644 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/rm-filters.lib.js +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/rm-filters.lib.js @@ -165,7 +165,14 @@ Filters.getFilterParams = function RecordsManagementFilter_getFilterParams(filte case "unfiledRecords": filterParams.variablePath = false; - filterParams.query = ""; + if (filterData == null) + { + filterParams.query = ""; + } + else + { + filterParams.query = "+PARENT:\"" + filterData + "\""; + } break; default: diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java index d64dfdf2c3..c58f983423 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java @@ -27,6 +27,7 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.namespace.QName; @@ -155,6 +156,9 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC rmNodeValues.put("type", useShortQName ? type.toPrefixString(namespaceService) : type.toString()); } + // Find out if it is an unfiled record container child + rmNodeValues.put("isUnfileRecordContainerChild", isUnfileRecordContainerChild(nodeRef)); + // Set the indicators array setIndicators(rmNodeValues, nodeRef); @@ -164,6 +168,25 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC return rmNodeValues; } + private boolean isUnfileRecordContainerChild(NodeRef nodeRef) + { + boolean isUnfileRecordContainerChild = false; + + List parentAssocs = nodeService.getParentAssocs(nodeRef); + if (parentAssocs.size() == 1) + { + NodeRef parentNodeRef = parentAssocs.iterator().next().getParentRef(); + FilePlanComponentKind filePlanComponentKind = filePlanService.getFilePlanComponentKind(parentNodeRef); + + if (filePlanComponentKind != null && filePlanComponentKind.equals(FilePlanComponentKind.RECORD_CATEGORY) == false) + { + isUnfileRecordContainerChild = true; + } + } + + return isUnfileRecordContainerChild; + } + @SuppressWarnings("unchecked") private void setIndicators(JSONObject rmNodeValues, NodeRef nodeRef) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java index 0c7e16033c..eb3f41292e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java @@ -22,7 +22,6 @@ import java.io.Serializable; import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RecordsManagementSearchBehaviour; @@ -47,7 +46,7 @@ import org.apache.commons.lang.ArrayUtils; /** * rma:recordFolder behaviour bean - * + * * @author Roy Wetherall * @since 2.2 */ @@ -58,27 +57,27 @@ import org.apache.commons.lang.ArrayUtils; public class RecordFolderType extends BaseBehaviourBean implements NodeServicePolicies.OnMoveNodePolicy, NodeServicePolicies.OnCreateChildAssociationPolicy -{ +{ /** unwanted aspects */ - private QName[] unwantedAspects = + private QName[] unwantedAspects = { - ASPECT_VITAL_RECORD, - ASPECT_DISPOSITION_LIFECYCLE, + ASPECT_VITAL_RECORD, + ASPECT_DISPOSITION_LIFECYCLE, RecordsManagementSearchBehaviour.ASPECT_RM_SEARCH }; - + /** record service */ private RecordService recordService; - + /** record folder service */ private RecordFolderService recordFolderService; - + /** disposition service */ private DispositionService dispositionService; - + /** vital record service */ protected VitalRecordService vitalRecordService; - + /** * @param recordService record service */ @@ -86,7 +85,7 @@ public class RecordFolderType extends BaseBehaviourBean { this.recordService = recordService; } - + /** * @param recordFolderService record folder service */ @@ -94,7 +93,7 @@ public class RecordFolderType extends BaseBehaviourBean { this.recordFolderService = recordFolderService; } - + /** * @param dispositionService disposition service */ @@ -102,7 +101,7 @@ public class RecordFolderType extends BaseBehaviourBean { this.dispositionService = dispositionService; } - + /** * @param vitalRecordService vital record service */ @@ -110,10 +109,10 @@ public class RecordFolderType extends BaseBehaviourBean { this.vitalRecordService = vitalRecordService; } - + /** * Record folder move behaviour - * + * * @see org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy#onMoveNode(org.alfresco.service.cmr.repository.ChildAssociationRef, org.alfresco.service.cmr.repository.ChildAssociationRef) */ @Override @@ -172,7 +171,7 @@ public class RecordFolderType extends BaseBehaviourBean throw new UnsupportedOperationException("Cannot move record folder into another record folder."); } } - + /** * Record folder copy callback */ @@ -216,7 +215,7 @@ public class RecordFolderType extends BaseBehaviourBean result = false; } else if (ArrayUtils.contains(unwantedAspects, classQName) == true) - { + { result = false; } @@ -224,7 +223,7 @@ public class RecordFolderType extends BaseBehaviourBean } }; } - + /** * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean) */ @@ -239,12 +238,6 @@ public class RecordFolderType extends BaseBehaviourBean NodeRef nodeRef = childAssocRef.getChildRef(); if (nodeService.exists(nodeRef) == true) { - // ensure folders are never added to a record folder - if (instanceOf(nodeRef, ContentModel.TYPE_FOLDER) == true) - { - throw new AlfrescoRuntimeException("You can't create a folder within an exisiting record folder."); - } - // ensure nothing is being added to a closed record folder NodeRef recordFolder = childAssocRef.getParentRef(); Boolean isClosed = (Boolean) nodeService.getProperty(recordFolder, PROP_IS_CLOSED); @@ -254,10 +247,10 @@ public class RecordFolderType extends BaseBehaviourBean } } } - + /** * On transaction commit - * + * * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean) */ @Behaviour @@ -269,7 +262,7 @@ public class RecordFolderType extends BaseBehaviourBean public void onCreateChildAssociationOnCommit(ChildAssociationRef childAssocRef, boolean bNew) { final NodeRef recordFolder = childAssocRef.getChildRef(); - + behaviourFilter.disableBehaviour(); try { @@ -288,9 +281,9 @@ public class RecordFolderType extends BaseBehaviourBean finally { behaviourFilter.enableBehaviour(); - } + } } - + /** * Removes unwanted aspects * diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java index 5b3da151b4..49e4a4699d 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java @@ -22,6 +22,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.annotation.Behaviour; @@ -35,7 +36,7 @@ import org.alfresco.service.namespace.QName; /** * rma:recordsManagementContainer behaviour bean. - * + * * @author Roy Wetherall * @since 2.2 */ @@ -48,7 +49,10 @@ public class RecordsManagementContainerType extends BaseBehaviourBean { /** identifier service */ protected IdentifierService identifierService; - + + /** record service */ + protected RecordService recordService; + /** * @param identifierService identifier service */ @@ -56,7 +60,15 @@ public class RecordsManagementContainerType extends BaseBehaviourBean { this.identifierService = identifierService; } - + + /** + * @param recordService record service + */ + public void setRecordService(RecordService recordService) + { + this.recordService = recordService; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.model.BaseTypeBehaviour#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean) */ @@ -66,7 +78,7 @@ public class RecordsManagementContainerType extends BaseBehaviourBean notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT ) public void onCreateChildAssociation(final ChildAssociationRef childAssocRef, boolean isNewNode) - { + { AuthenticationUtil.runAsSystem(new RunAsWork() { @Override @@ -77,53 +89,71 @@ public class RecordsManagementContainerType extends BaseBehaviourBean if (nodeService.exists(child) == true) { QName childType = nodeService.getType(child); - + // We only care about "folder" or sub-types if (dictionaryService.isSubClass(childType, ContentModel.TYPE_FOLDER) == true) - { + { if (dictionaryService.isSubClass(childType, ContentModel.TYPE_SYSTEM_FOLDER) == true) { // this is a rule container, make sure it is an file plan component nodeService.addAspect(child, ASPECT_FILE_PLAN_COMPONENT, null); } else - { + { // We need to automatically cast the created folder to RM type if it is a plain folder // This occurs if the RM folder has been created via IMap, WebDav, etc if (nodeService.hasAspect(child, ASPECT_FILE_PLAN_COMPONENT) == false) - { - // TODO it may not always be a record folder ... perhaps if the current user is a admin it would be a record category?? - + { + // TODO it may not always be a record folder ... perhaps if the current user is a admin it would be a record category?? + // Assume any created folder is a rma:recordFolder - nodeService.setType(child, TYPE_RECORD_FOLDER); - } - + nodeService.setType(child, TYPE_RECORD_FOLDER); + } + // Catch all to generate the rm id (assuming it doesn't already have one!) setIdenifierProperty(child); - } + } + } + else + { + NodeRef parentRef = childAssocRef.getParentRef(); + QName parentType = nodeService.getType(parentRef); + boolean isContentSubType = dictionaryService.isSubClass(childType, ContentModel.TYPE_CONTENT); + boolean isUnfiledRecordContainerSubType = dictionaryService.isSubClass(parentType, RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER); + if (isContentSubType == true && isUnfiledRecordContainerSubType == true) + { + if (nodeService.hasAspect(child, ASPECT_FILE_PLAN_COMPONENT) == false) + { + nodeService.addAspect(child, ASPECT_FILE_PLAN_COMPONENT, null); + } + if (nodeService.hasAspect(child, ASPECT_RECORD) == false) + { + recordService.makeRecord(child); + } + } } } - + return null; - } + } }); - + } - + /** - * + * * @param nodeRef */ protected void setIdenifierProperty(final NodeRef nodeRef) { AuthenticationUtil.runAsSystem(new RunAsWork() { - public Object doWork() throws Exception + public Object doWork() throws Exception { - if (nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT) == true && + if (nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT) == true && nodeService.getProperty(nodeRef, PROP_IDENTIFIER) == null) { - String id = identifierService.generateIdentifier(nodeRef); + String id = identifierService.generateIdentifier(nodeRef); nodeService.setProperty(nodeRef, RecordsManagementModel.PROP_IDENTIFIER, id); } return null; 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 f4e2d515cf..1a97f5479e 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 @@ -161,4 +161,11 @@ public interface RecordService * @param typeQName Type to add */ void addRecordType(NodeRef nodeRef, QName typeQName); + + /** + * Creates a record from the given document + * + * @param nodeRef The document node reference from which a record will be created + */ + void makeRecord(NodeRef nodeRef); } 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 a9cb8fa136..bb77919e8b 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 @@ -196,7 +196,7 @@ public class RecordServiceImpl implements RecordService, /** Permission service */ private PermissionService permissionService; - + /** Record aspect */ private RecordAspect recordAspect; @@ -348,7 +348,7 @@ public class RecordServiceImpl implements RecordService, { this.permissionService = permissionService; } - + /** * @param recordAspect record aspect */ @@ -367,7 +367,7 @@ public class RecordServiceImpl implements RecordService, TYPE_RECORD_FOLDER, ContentModel.ASSOC_CONTAINS, onCreateChildAssociation); - + policyComponent.bindAssociationBehaviour( NodeServicePolicies.BeforeDeleteChildAssociationPolicy.QNAME, ContentModel.TYPE_FOLDER, @@ -426,44 +426,44 @@ public class RecordServiceImpl implements RecordService, * Helper method to switch the name of the record around. Used to support record creation via * file protocols. * - * @param nodeRef node reference (record) + * @param nodeRef node reference (record) */ private void switchNames(NodeRef nodeRef) { - try - { - if (nodeService.hasAspect(nodeRef, ASPECT_RECORD) == true) - { - String origionalName = (String)nodeService.getProperty(nodeRef, PROP_ORIGIONAL_NAME); - if (origionalName != null) - { - String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); - fileFolderService.rename(nodeRef, origionalName); - nodeService.setProperty(nodeRef, PROP_ORIGIONAL_NAME, name); - } - } - } - catch (FileExistsException e) - { - if (logger.isDebugEnabled() == true) - { - logger.debug(e.getMessage()); - } - } - catch (InvalidNodeRefException e) - { + try + { + if (nodeService.hasAspect(nodeRef, ASPECT_RECORD) == true) + { + String origionalName = (String)nodeService.getProperty(nodeRef, PROP_ORIGIONAL_NAME); + if (origionalName != null) + { + String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); + fileFolderService.rename(nodeRef, origionalName); + nodeService.setProperty(nodeRef, PROP_ORIGIONAL_NAME, name); + } + } + } + catch (FileExistsException e) + { if (logger.isDebugEnabled() == true) { logger.debug(e.getMessage()); } - } - catch (FileNotFoundException e) - { + } + catch (InvalidNodeRefException e) + { if (logger.isDebugEnabled() == true) { logger.debug(e.getMessage()); } - } + } + catch (FileNotFoundException e) + { + if (logger.isDebugEnabled() == true) + { + logger.debug(e.getMessage()); + } + } } /** @@ -774,12 +774,15 @@ public class RecordServiceImpl implements RecordService, * * @param document the document from which a record will be created */ - private void makeRecord(NodeRef document) + @Override + public void makeRecord(NodeRef document) { + ParameterCheck.mandatory("document", document); + ruleService.disableRules(); try { - // get the record id + // get the record id String recordId = identifierService.generateIdentifier(ASPECT_RECORD, nodeService.getPrimaryParent(document).getParentRef());