diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml index 29e46aefb2..d0103fb842 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml @@ -702,6 +702,13 @@ true false + + + Record Component Identifier Temporarily Editable Indicator + d:boolean + true + false + rma:filePlanComponent diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java index d0380b5994..a99f75cbab 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java @@ -126,6 +126,7 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel QName ASPECT_RECORD_COMPONENT_ID = QName.createQName(RM_URI, "recordComponentIdentifier"); QName PROP_IDENTIFIER = QName.createQName(RM_URI, "identifier"); QName PROP_DB_UNIQUENESS_ID = QName.createQName(RM_URI, "dbUniquenessId"); + QName PROP_ID_IS_TEMPORARILY_EDITABLE = QName.createQName(RM_URI, "idIsTemporarilyEditable"); // Vital record definition aspect QName ASPECT_VITAL_RECORD_DEFINITION = QName.createQName(RM_URI, "vitalRecordDefinition"); diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java index 70b7d096b0..f87f573162 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java @@ -47,6 +47,7 @@ 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.attributes.AttributeService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.springframework.extensions.surf.util.I18NUtil; @@ -64,6 +65,7 @@ import org.springframework.extensions.surf.util.I18NUtil; public class RecordComponentIdentifierAspect extends BaseBehaviourBean implements NodeServicePolicies.OnUpdatePropertiesPolicy, NodeServicePolicies.BeforeDeleteNodePolicy, + NodeServicePolicies.OnCreateNodePolicy, CopyServicePolicies.OnCopyCompletePolicy { /** I18N */ @@ -127,7 +129,7 @@ public class RecordComponentIdentifierAspect extends BaseBehaviourBean if (newIdValue != null) { String oldIdValue = (String)before.get(PROP_IDENTIFIER); - if (oldIdValue != null && !oldIdValue.equals(newIdValue)) + if (oldIdValue != null && !oldIdValue.equals(newIdValue) && !isRecordIdentifierEditable(nodeRef)) { throw new IntegrityException(I18NUtil.getMessage(MSG_SET_ID, nodeRef.toString()), null); } @@ -140,6 +142,17 @@ public class RecordComponentIdentifierAspect extends BaseBehaviourBean }, AuthenticationUtil.getSystemUserName()); } + /** + * Utility method that checks if a record's identifier is temporarily editable + * @param record the record to check + * @return true if it is editable false otherwise + */ + private boolean isRecordIdentifierEditable(NodeRef record) + { + Boolean isEditableProperty = (Boolean)nodeService.getProperty(record, RecordsManagementModel.PROP_ID_IS_TEMPORARILY_EDITABLE); + return isEditableProperty == null ? false : isEditableProperty; + } + /** * Cleans up the {@link RecordsManagementModel#PROP_IDENTIFIER rma:identifier} property unique triplet. * @@ -238,4 +251,30 @@ public class RecordComponentIdentifierAspect extends BaseBehaviourBean CONTEXT_VALUE, contextNodeRef, afterId); } } + + @Behaviour + ( + kind = BehaviourKind.CLASS, + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + ) + @Override + public void onCreateNode(final ChildAssociationRef childAssocRef) + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + public Object doWork() + { + /* + * When creating a new record the identifier is writable to allow the upload in multiple steps. + * On transaction commit make the identifier read only (remove the editable aspect). + */ + NodeRef newNode = childAssocRef.getChildRef(); + if(nodeService.exists(newNode)) + { + nodeService.setProperty(newNode, RecordsManagementModel.PROP_ID_IS_TEMPORARILY_EDITABLE, false); + } + return null; + } + }); + } } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java index 8276307e1c..ff282ac258 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java @@ -122,7 +122,8 @@ public class RecordsManagementContainerType extends BaseBehaviourBean @Behaviour ( kind = BehaviourKind.ASSOCIATION, - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT, + // Execute on first event to make all type conversions and set all the properties before transaction ends and response is returned + notificationFrequency = NotificationFrequency.EVERY_EVENT, name = BEHAVIOUR_NAME ) public void onCreateChildAssociation(final ChildAssociationRef childAssocRef, boolean isNewNode) @@ -195,8 +196,10 @@ public class RecordsManagementContainerType extends BaseBehaviourBean if (nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT) && nodeService.getProperty(nodeRef, PROP_IDENTIFIER) == null) { + // Generate identifier and leave it editable until the transaction ends String id = identifierService.generateIdentifier(nodeRef); nodeService.setProperty(nodeRef, RecordsManagementModel.PROP_IDENTIFIER, id); + nodeService.setProperty(nodeRef, RecordsManagementModel.PROP_ID_IS_TEMPORARILY_EDITABLE, true); } return null; } diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ReportServiceImplTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ReportServiceImplTest.java index 13a4fc31f5..aa4c854a1b 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ReportServiceImplTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ReportServiceImplTest.java @@ -218,10 +218,6 @@ public class ReportServiceImplTest extends BaseRMTestCase implements ReportModel NodeRef recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); - // Set the record folder identifier - String identifier = identifierService.generateIdentifier(TYPE_RECORD_FOLDER, recordCategory); - nodeService.setProperty(recordFolder, PROP_IDENTIFIER, identifier); - // Complete event Map params = new HashMap(1); params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME);