From c3879ad56fce62ed191e06c7abccde2ff0755ea0 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 8 May 2012 11:37:46 +0000 Subject: [PATCH] RM Form Refactor/Bug Fixes: * Updated implementation of form filters to include custom properties and custom record aspect properties * Overide FormUIGet web script implementation to include custom properties (and custom record meta-data aspects) despite now using a 'show' strategy for the form defintions. * Added a RM 'kind' config evaluator. This allows us to provide a form definition for the different 'kinds' of RM artifacts which are automatically merged with the core form related to the content type. This is especially useful for records as we can now support the correct display of extended content types and content with additional aspects. * Added rm metadata web script to support the kind config evaluator. * Re-factored all form definitions into 'kinds' and core types where appropriate ... means implementors can extend our core RM types and still have the correct Rm information displayed whilst defining their own forms for their new types. * Separated out the DOD specific form parts for the record kind. * Non-electronic document form added (and auto-includes record kind form) * relates to RM-269 and RM-137 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@36154 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- rm-server/.classpath | 20 +- .../model/recordsModel.xml | 2 +- .../org_alfresco_module_rm/module.properties | 2 +- .../rm-service-context.xml | 1 + .../rm-webscript-context.xml | 8 + .../slingshot/forms/metadata.get.desc.xml | 8 + .../slingshot/forms/metadata.get.json.ftl | 3 + .../RecordsManagementService.java | 16 +- .../RecordsManagementServiceImpl.java | 45 +++ .../forms/RecordsManagementFormFilter.java | 46 ++- .../RecordsManagementNodeFormFilter.java | 298 +++++------------- .../RecordsManagementTypeFormFilter.java | 108 ++----- .../script/slingshot/forms/RMMetaDataGet.java | 118 +++++++ 13 files changed, 361 insertions(+), 314 deletions(-) create mode 100644 rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.desc.xml create mode 100644 rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.json.ftl create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/forms/RMMetaDataGet.java diff --git a/rm-server/.classpath b/rm-server/.classpath index e2ff39fa0f..a600d64633 100644 --- a/rm-server/.classpath +++ b/rm-server/.classpath @@ -19,17 +19,8 @@ - - - - - - - - - @@ -279,5 +270,16 @@ + + + + + + + + + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml index 139e1dbe3d..0be4c0dee8 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml @@ -922,7 +922,7 @@ - TransferringS + Transferring diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index c5dde346e8..57dcc7aa7b 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -8,4 +8,4 @@ module.title=Records Management module.description=Alfresco Record Management Extension module.version=2.0 -module.repo.version.min=4.0 \ No newline at end of file +module.repo.version.min=4.0.1 \ No newline at end of file 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 f52e7a188d..b79e0f3e54 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 @@ -66,6 +66,7 @@ + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.desc.xml b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.desc.xml new file mode 100644 index 0000000000..7a6af06ac1 --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.desc.xml @@ -0,0 +1,8 @@ + + RM node metadata retrieval service + Used by the extended RM forms service to retrieve RM node metadata. + /api/rmmetadata?noderef={noderef?}&type={type?} + + user + required + \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.json.ftl b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.json.ftl new file mode 100644 index 0000000000..644dea3b4d --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/slingshot/forms/metadata.get.json.ftl @@ -0,0 +1,3 @@ +{ + "kind" : ${kind} +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java index 76a0f62af9..7776375050 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementService.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; @@ -48,18 +47,31 @@ public interface RecordsManagementService /** * Returns the 'kind' of file plan component the node reference is. + *

* Returns null if the given node reference is not a * file plan component. * * @param nodeRef node reference * @return FilePlanComponentKind the kind of file plan component the * node is - * kind * * @since 2.0 */ FilePlanComponentKind getFilePlanComponentKind(NodeRef nodeRef); + /** + * Returns the file plan component 'kind' that relates to the passed + * content type. + *

+ * Returns null if the type does not relate to a file plan component. + * + * @param type qualified name of content type + * @return FilePlanComponentKind the kind relating to the passed type + * + * @since 2.0 + */ + FilePlanComponentKind getFilePlanComponentKindFromType(QName type); + /** * Indicates whether the given node is file plan node or not. * diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java index 520cebc015..27c93456c8 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementServiceImpl.java @@ -472,6 +472,51 @@ public class RecordsManagementServiceImpl implements RecordsManagementService, return result; } + /** + * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementService#getFilePlanComponentKindFromType(org.alfresco.service.namespace.QName) + */ + @Override + public FilePlanComponentKind getFilePlanComponentKindFromType(QName type) + { + FilePlanComponentKind result = null; + + if (ASPECT_FILE_PLAN_COMPONENT.equals(type) == true) + { + result = FilePlanComponentKind.FILE_PLAN_COMPONENT; + } + else if (dictionaryService.isSubClass(type, ASPECT_RECORD) == true) + { + result = FilePlanComponentKind.RECORD; + } + else if (dictionaryService.isSubClass(type, TYPE_FILE_PLAN) == true) + { + result = FilePlanComponentKind.FILE_PLAN; + } + else if (dictionaryService.isSubClass(type, TYPE_RECORD_CATEGORY) == true) + { + result = FilePlanComponentKind.RECORD_CATEGORY; + } + else if (dictionaryService.isSubClass(type, TYPE_RECORD_FOLDER) == true) + { + result = FilePlanComponentKind.RECORD_FOLDER; + } + else if (dictionaryService.isSubClass(type, TYPE_HOLD) == true) + { + result = FilePlanComponentKind.HOLD; + } + else if (dictionaryService.isSubClass(type, TYPE_TRANSFER) == true) + { + result = FilePlanComponentKind.TRANSFER; + } + else if (dictionaryService.isSubClass(type, TYPE_DISPOSITION_SCHEDULE) == true || + dictionaryService.isSubClass(type, TYPE_DISPOSITION_ACTION_DEFINITION) == true) + { + result = FilePlanComponentKind.DISPOSITION_SCHEDULE; + } + + return result; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementService#isRecordCategory(org.alfresco.service.cmr.repository.NodeRef) */ diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementFormFilter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementFormFilter.java index 9dddf5557d..7b6579f5d8 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementFormFilter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementFormFilter.java @@ -18,20 +18,24 @@ */ package org.alfresco.module.org_alfresco_module_rm.forms; +import java.io.Serializable; import java.util.List; import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry; -import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model; +import org.alfresco.repo.forms.Field; import org.alfresco.repo.forms.FieldGroup; import org.alfresco.repo.forms.Form; import org.alfresco.repo.forms.FormData; import org.alfresco.repo.forms.processor.AbstractFilter; +import org.alfresco.repo.forms.processor.node.FieldUtils; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -44,13 +48,10 @@ import org.apache.commons.logging.LogFactory; public abstract class RecordsManagementFormFilter extends AbstractFilter { /** Logger */ - @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(RecordsManagementFormFilter.class); public static final String CUSTOM_RM_FIELD_GROUP_ID = "rm-custom"; - - protected static final FieldGroup CUSTOM_RM_FIELD_GROUP = new FieldGroup(CUSTOM_RM_FIELD_GROUP_ID, null, false, - false, null); + public static final String RM_METADATA_PREFIX = "rm-metadata-"; protected NamespaceService namespaceService; protected NodeService nodeService; @@ -97,7 +98,7 @@ public abstract class RecordsManagementFormFilter extends AbstractFilt { this.rmService = rmService; } - + /** * Sets the RecordsManagementAdminService instance * @@ -107,6 +108,39 @@ public abstract class RecordsManagementFormFilter extends AbstractFilt { this.rmAdminService = rmAdminService; } + + /** + * Add property fields to group + * + * @param form + * @param props + * @param setId + */ + protected void addPropertyFieldsToGroup(Form form, Map props, String setId) + { + if (props != null) + { + for (Map.Entry entry : props.entrySet()) + { + PropertyDefinition prop = entry.getValue(); + + String id = form.getItem().getId(); + id = id.replaceFirst("/", "://"); + NodeRef nodeRef = new NodeRef(id); + Serializable value = nodeService.getProperty(nodeRef, entry.getKey()); + + FieldGroup group = new FieldGroup(setId, null, false, false, null); + Field field = FieldUtils.makePropertyField(prop, value, group, namespaceService); + + form.addField(field); + + if (logger.isDebugEnabled() == true) + { + logger.debug("Adding custom property .. " + prop.getName().toString() + " .. with value " + value + ".. to group .. " + setId); + } + } + } + } /** * @see diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementNodeFormFilter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementNodeFormFilter.java index b0a73bffda..a2a78c185e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementNodeFormFilter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementNodeFormFilter.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import org.alfresco.model.ImapModel; +import org.alfresco.module.org_alfresco_module_rm.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionScheduleImpl; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; @@ -59,7 +60,6 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter private static Log logger = LogFactory.getLog(RecordsManagementNodeFormFilter.class); protected static final String TRANSIENT_DECLARED = "rmDeclared"; - protected static final String TRANSIENT_RECORD_TYPE = "rmRecordType"; protected static final String TRANSIENT_CATEGORY_ID = "rmCategoryIdentifier"; protected static final String TRANSIENT_DISPOSITION_INSTRUCTIONS = "rmDispositionInstructions"; @@ -92,29 +92,29 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter /* * @see org.alfresco.repo.forms.processor.Filter#afterGenerate(java.lang.Object, java.util.List, java.util.List, org.alfresco.repo.forms.Form, java.util.Map) */ - public void afterGenerate(NodeRef nodeRef, List fields, List forcedFields, Form form, - Map context) + public void afterGenerate( + NodeRef nodeRef, + List fields, + List forcedFields, + Form form, + Map context) { - // TODO this needs a massive refactor inorder to support any custom type or aspect .... - - // if the node has the RM marker aspect look for the custom properties - // for the type - if (this.nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT)) - { - // Make sure any customisable types or aspects present of the node have their properties included - // in the custom group - showCustomProperties(nodeRef, form); + if (rmService.isFilePlanComponent(nodeRef) == true) + { + // add all the custom properties + addCustomPropertyFieldsToGroup(form, nodeRef); - if (this.nodeService.hasAspect(nodeRef, ASPECT_RECORD)) + FilePlanComponentKind kind = rmService.getFilePlanComponentKind(nodeRef); + if (FilePlanComponentKind.RECORD.equals(kind) == true) { - // force the "supplementalMarkingList" property to be present - forceSupplementalMarkingListProperty(form, nodeRef); + // add all the record meta-data aspect properties + addRecordMetadataPropertyFieldsToGroup(form, nodeRef); - // generate property definitions for the 'transient' properties - generateDeclaredPropertyField(form, nodeRef); - generateRecordTypePropertyField(form, nodeRef); - generateCategoryIdentifierPropertyField(form, nodeRef); - generateDispositionInstructionsPropertyField(form, nodeRef); + // add required transient properties + addTransientProperties(form, nodeRef); + + // add the supplemental marking list property + forceSupplementalMarkingListProperty(form, nodeRef); // if the record is the result of an email we need to 'protect' some fields if (this.nodeService.hasAspect(nodeRef, ImapModel.ASPECT_IMAP_CONTENT)) @@ -122,69 +122,48 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter protectEmailExtractedFields(form, nodeRef); } } - else + else if (FilePlanComponentKind.RECORD_FOLDER.equals(kind) == true) { - QName type = this.nodeService.getType(nodeRef); - if (TYPE_RECORD_FOLDER.equals(type)) - { - // force the "supplementalMarkingList" property to be present - forceSupplementalMarkingListProperty(form, nodeRef); - } - else if (TYPE_DISPOSITION_SCHEDULE.equals(type)) - { - // use the same mechanism used to determine whether steps can be removed from the - // schedule to determine whether the disposition level can be changed i.e. record - // level or folder level. - DispositionSchedule schedule = new DispositionScheduleImpl(this.rmServiceRegistry, this.nodeService, nodeRef); - if (dispositionService.hasDisposableItems(schedule) == true) - { - protectRecordLevelDispositionPropertyField(form); - } - } + // add the supplemental marking list property + forceSupplementalMarkingListProperty(form, nodeRef); + + // add required transient properties + addTransientProperties(form, nodeRef); } + else if (FilePlanComponentKind.DISPOSITION_SCHEDULE.equals(kind) == true) + { + // use the same mechanism used to determine whether steps can be removed from the + // schedule to determine whether the disposition level can be changed i.e. record + // level or folder level. + DispositionSchedule schedule = new DispositionScheduleImpl(this.rmServiceRegistry, this.nodeService, nodeRef); + if (dispositionService.hasDisposableItems(schedule) == true) + { + protectRecordLevelDispositionPropertyField(form); + } + } + } } - /** - * Show the custom properties if any are present. - * - * @param nodeRef node reference - * @param form form - */ - protected void showCustomProperties(NodeRef nodeRef, Form form) + protected void addCustomPropertyFieldsToGroup(Form form, NodeRef nodeRef) { - Set customClasses = rmAdminService.getCustomisable(nodeRef); - if (customClasses.isEmpty() == false) + Set customisables = rmAdminService.getCustomisable(nodeRef); + for (QName customisable : customisables) { - // add the 'rm-custom' field group - addCustomRMGroup(form); - } + addPropertyFieldsToGroup(form, rmAdminService.getCustomPropertyDefinitions(customisable), CUSTOM_RM_FIELD_GROUP_ID); + } } - - /** - * Adds the Custom RM field group (id 'rm-custom') to all the field - * definitions representing RM custom properties. - * - * @param form The form holding the field definitions - */ - protected void addCustomRMGroup(Form form) + + protected void addRecordMetadataPropertyFieldsToGroup(Form form, NodeRef nodeRef) { - // iterate round existing fields and set group on each custom - // RM field - List fieldDefs = form.getFieldDefinitions(); - for (FieldDefinition fieldDef : fieldDefs) + Set aspects = rmService.getRecordMetaDataAspects(); + for (QName aspect : aspects) { - if (fieldDef.getName().startsWith(RM_CUSTOM_PREFIX) && - !fieldDef.getName().equals(PROP_SUPPLEMENTAL_MARKING_LIST.toPrefixString(this.namespaceService))) + if (nodeService.hasAspect(nodeRef, aspect) == true) { - // only add custom RM properties, not associations/references - if (fieldDef instanceof PropertyFieldDefinition) - { - fieldDef.setGroup(CUSTOM_RM_FIELD_GROUP); - - if (logger.isDebugEnabled()) - logger.debug("Added \"" + fieldDef.getName() + "\" to RM custom field group"); - } + String aspectName = aspect.getPrefixedQName(namespaceService).toPrefixString().replace(":", "-"); + String setId = RM_METADATA_PREFIX + aspectName; + addPropertyFieldsToGroup(form, dictionaryService.getPropertyDefs(aspect), setId); } } } @@ -218,142 +197,46 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter } } } + - /** - * Generates the field definition for the transient rmDeclared - * property. - * - * @param form The Form instance to add the property to - * @param nodeRef The node the form is being generated for - */ - protected void generateDeclaredPropertyField(Form form, NodeRef nodeRef) + protected void addTransientProperties(Form form, NodeRef nodeRef) { - // TODO should this be done using a new FieldProcessor? - String dataKeyName = FormFieldConstants.PROP_DATA_PREFIX + TRANSIENT_DECLARED; - PropertyFieldDefinition declaredField = new PropertyFieldDefinition(TRANSIENT_DECLARED, - DataTypeDefinition.BOOLEAN.getLocalName()); - declaredField.setLabel(TRANSIENT_DECLARED); - declaredField.setDescription(TRANSIENT_DECLARED); - declaredField.setProtectedField(true); - declaredField.setDataKeyName(dataKeyName); - form.addFieldDefinition(declaredField); - form.addData(dataKeyName, this.nodeService.hasAspect(nodeRef, ASPECT_DECLARED_RECORD)); - } - - /** - * Generates the field definition for the transient - * rmRecordType property - * - * @param form The Form instance to add the property to - * @param nodeRef The node the form is being generated for - */ - protected void generateRecordTypePropertyField(Form form, NodeRef nodeRef) - { - String dataKeyName = FormFieldConstants.PROP_DATA_PREFIX + TRANSIENT_RECORD_TYPE; - PropertyFieldDefinition recordTypeField = new PropertyFieldDefinition(TRANSIENT_RECORD_TYPE, - DataTypeDefinition.TEXT.getLocalName()); - recordTypeField.setLabel(TRANSIENT_RECORD_TYPE); - recordTypeField.setDescription(TRANSIENT_RECORD_TYPE); - recordTypeField.setProtectedField(true); - recordTypeField.setDataKeyName(dataKeyName); - form.addFieldDefinition(recordTypeField); - - // determine what record type value to return, use aspect/type title - // from model - String recordType = null; - QName type = this.nodeService.getType(nodeRef); - if (TYPE_NON_ELECTRONIC_DOCUMENT.equals(type)) + if (rmService.isRecord(nodeRef) == true) { - // get the non-electronic type title - recordType = dictionaryService.getType(TYPE_NON_ELECTRONIC_DOCUMENT).getTitle(); + addTransientPropertyField(form, TRANSIENT_DECLARED, DataTypeDefinition.BOOLEAN, rmService.isRecordDeclared(nodeRef)); } - else - { - // the aspect applied to record determines it's type - if (nodeService.hasAspect(nodeRef, ASPECT_PDF_RECORD)) - { - recordType = dictionaryService.getAspect(ASPECT_PDF_RECORD).getTitle(); - } - else if (nodeService.hasAspect(nodeRef, ASPECT_WEB_RECORD)) - { - recordType = dictionaryService.getAspect(ASPECT_WEB_RECORD).getTitle(); - } - else if (nodeService.hasAspect(nodeRef, ASPECT_SCANNED_RECORD)) - { - recordType = dictionaryService.getAspect(ASPECT_SCANNED_RECORD).getTitle(); - } - else if (nodeService.hasAspect(nodeRef, ASPECT_DIGITAL_PHOTOGRAPH_RECORD)) - { - recordType = dictionaryService.getAspect(ASPECT_DIGITAL_PHOTOGRAPH_RECORD).getTitle(); - } - else - { - // no specific aspect applied so default to just "Record" - recordType = dictionaryService.getAspect(ASPECT_RECORD).getTitle(); - } - } - - form.addData(dataKeyName, recordType); - } - - /** - * Generates the field definition for the transient rmCategoryIdentifier - * property - * - * @param form The Form instance to add the property to - * @param nodeRef The node the form is being generated for - */ - protected void generateDispositionInstructionsPropertyField(Form form, NodeRef nodeRef) - { - String dataKeyName = FormFieldConstants.PROP_DATA_PREFIX + TRANSIENT_DISPOSITION_INSTRUCTIONS; - PropertyFieldDefinition dispInstructionsField = new PropertyFieldDefinition(TRANSIENT_DISPOSITION_INSTRUCTIONS, - DataTypeDefinition.TEXT.getLocalName()); - dispInstructionsField.setLabel(TRANSIENT_DISPOSITION_INSTRUCTIONS); - dispInstructionsField.setDescription(TRANSIENT_DISPOSITION_INSTRUCTIONS); - dispInstructionsField.setProtectedField(true); - dispInstructionsField.setDataKeyName(dataKeyName); - form.addFieldDefinition(dispInstructionsField); - // use RMService to get disposition instructions DispositionSchedule ds = dispositionService.getDispositionSchedule(nodeRef); if (ds != null) { String instructions = ds.getDispositionInstructions(); if (instructions != null) { - form.addData(dataKeyName, instructions); + addTransientPropertyField(form, TRANSIENT_DISPOSITION_INSTRUCTIONS, DataTypeDefinition.TEXT, instructions); } - } + + NodeRef recordCategory = dispositionService.getAssociatedRecordsManagementContainer(ds); + if (recordCategory != null) + { + String categoryId = (String)nodeService.getProperty(recordCategory, PROP_IDENTIFIER); + if (categoryId != null) + { + addTransientPropertyField(form, TRANSIENT_CATEGORY_ID, DataTypeDefinition.TEXT, categoryId); + } + } + } } - /** - * Generates the field definition for the transient rmCategoryIdentifier - * property - * - * @param form The Form instance to add the property to - * @param nodeRef The node the form is being generated for - */ - protected void generateCategoryIdentifierPropertyField(Form form, NodeRef nodeRef) + protected void addTransientPropertyField(Form form, String name, QName type, Object value) { - String dataKeyName = FormFieldConstants.PROP_DATA_PREFIX + TRANSIENT_CATEGORY_ID; - PropertyFieldDefinition categoryIdField = new PropertyFieldDefinition(TRANSIENT_CATEGORY_ID, - DataTypeDefinition.TEXT.getLocalName()); - categoryIdField.setLabel(TRANSIENT_CATEGORY_ID); - categoryIdField.setDescription(TRANSIENT_CATEGORY_ID); - categoryIdField.setProtectedField(true); - categoryIdField.setDataKeyName(dataKeyName); - form.addFieldDefinition(categoryIdField); - - // get the category id from the appropriate parent node - NodeRef category = getRecordCategory(nodeRef); - if (category != null) - { - String categoryId = (String)nodeService.getProperty(category, PROP_IDENTIFIER); - if (categoryId != null) - { - form.addData(dataKeyName, categoryId); - } - } + String dataKeyName = FormFieldConstants.PROP_DATA_PREFIX + name; + PropertyFieldDefinition declaredField = new PropertyFieldDefinition(name, type.getLocalName()); + declaredField.setLabel(name); + declaredField.setDescription(name); + declaredField.setProtectedField(true); + declaredField.setDataKeyName(dataKeyName); + form.addFieldDefinition(declaredField); + form.addData(dataKeyName, value); } /** @@ -392,7 +275,6 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter */ protected void protectRecordLevelDispositionPropertyField(Form form) { - // iterate round existing fields and set email fields as protected List fieldDefs = form.getFieldDefinitions(); for (FieldDefinition fieldDef : fieldDefs) { @@ -407,32 +289,4 @@ public class RecordsManagementNodeFormFilter extends RecordsManagementFormFilter if (logger.isDebugEnabled()) logger.debug("Set 'rma:recordLevelDisposition' field to be protected as record folders or records are present"); } - - /** - * Retrieves the record category the given record belongs to or - * null if the record category can not be found - * - * @param record NodeRef representing the record - * @return NodeRef of the record's category - */ - protected NodeRef getRecordCategory(NodeRef record) - { - NodeRef result = null; - - NodeRef parent = this.nodeService.getPrimaryParent(record).getParentRef(); - if (parent != null) - { - QName nodeType = this.nodeService.getType(parent); - if (this.dictionaryService.isSubClass(nodeType, TYPE_RECORD_CATEGORY)) - { - result = parent; - } - else - { - result = getRecordCategory(parent); - } - } - - return result; - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java index b586652f4a..28aa892093 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java @@ -23,17 +23,13 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.forms.Field; -import org.alfresco.repo.forms.FieldDefinition; import org.alfresco.repo.forms.FieldGroup; import org.alfresco.repo.forms.Form; import org.alfresco.repo.forms.FormData; import org.alfresco.repo.forms.processor.node.FieldUtils; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; @@ -108,7 +104,7 @@ public class RecordsManagementTypeFormFilter extends RecordsManagementFormFilter } // Group fields - groupFields(form); + // groupFields(form); } /** @@ -135,7 +131,8 @@ public class RecordsManagementTypeFormFilter extends RecordsManagementFormFilter // setup field definition for each custom property Collection properties = customProps.values(); - List fields = FieldUtils.makePropertyFields(properties, CUSTOM_RM_FIELD_GROUP, namespaceService); + FieldGroup group = new FieldGroup(CUSTOM_RM_FIELD_GROUP_ID, null, false, false, null); + List fields = FieldUtils.makePropertyFields(properties, group, namespaceService); form.addFields(fields); } } @@ -146,77 +143,42 @@ public class RecordsManagementTypeFormFilter extends RecordsManagementFormFilter public void afterPersist(TypeDefinition item, FormData data, final NodeRef nodeRef) { } - - /** - * Generates a unique identifier for the given node (based on the dbid). - * - * @param nodeRef The NodeRef to generate a unique id for - * @return The identifier - */ - protected String generateIdentifier(NodeRef nodeRef) - { - String identifier = identifierService.generateIdentifier(nodeRef); - if (logger.isDebugEnabled() == true) - { - logger.debug("Generated '" + identifier + "' for unique identifier"); - } - return identifier; - } - - /** - * Function to pad a string with zero '0' characters to the required length - * - * @param s String to pad with leading zero '0' characters - * @param len Length to pad to - * @return padded string or the original if already at >=len characters - */ - protected String padString(String s, int len) - { - String result = s; - - for (int i = 0; i < (len - s.length()); i++) - { - result = "0" + result; - } - - return result; - } /** * Puts all fields in a group to workaround ALF-6089. * * @param form The form being generated */ - protected void groupFields(Form form) - { - // to control the order of the fields add the name, title and description fields to - // a field group containing just that field, all other fields that are not already - // in a group go into an "other" field group. The client config can then declare a - // client side set with the same id and order them correctly. - - List fieldDefs = form.getFieldDefinitions(); - for (FieldDefinition fieldDef : fieldDefs) - { - FieldGroup group = fieldDef.getGroup(); - if (group == null) - { - if (fieldDef.getName().equals(ContentModel.PROP_NAME.toPrefixString(this.namespaceService))) - { - fieldDef.setGroup(NAME_FIELD_GROUP); - } - else if (fieldDef.getName().equals(ContentModel.PROP_TITLE.toPrefixString(this.namespaceService))) - { - fieldDef.setGroup(TITLE_FIELD_GROUP); - } - else if (fieldDef.getName().equals(ContentModel.PROP_DESCRIPTION.toPrefixString(this.namespaceService))) - { - fieldDef.setGroup(DESC_FIELD_GROUP); - } - else - { - fieldDef.setGroup(OTHER_FIELD_GROUP); - } - } - } - } +// protected void groupFields(Form form) +// { +// // to control the order of the fields add the name, title and description fields to +// // a field group containing just that field, all other fields that are not already +// // in a group go into an "other" field group. The client config can then declare a +// // client side set with the same id and order them correctly. +// +// List fieldDefs = form.getFieldDefinitions(); +// for (FieldDefinition fieldDef : fieldDefs) +// { +// FieldGroup group = fieldDef.getGroup(); +// if (group == null) +// { +// if (fieldDef.getName().equals(ContentModel.PROP_NAME.toPrefixString(this.namespaceService))) +// { +// fieldDef.setGroup(NAME_FIELD_GROUP); +// } +// else if (fieldDef.getName().equals(ContentModel.PROP_TITLE.toPrefixString(this.namespaceService))) +// { +// fieldDef.setGroup(TITLE_FIELD_GROUP); +// } +// else if (fieldDef.getName().equals(ContentModel.PROP_DESCRIPTION.toPrefixString(this.namespaceService))) +// { +// fieldDef.setGroup(DESC_FIELD_GROUP); +// } +// else +// { +// fieldDef.setGroup(OTHER_FIELD_GROUP); +// } +// } +// } +// } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/forms/RMMetaDataGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/forms/RMMetaDataGet.java new file mode 100644 index 0000000000..579ca58592 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/forms/RMMetaDataGet.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.script.slingshot.forms; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.alfresco.module.org_alfresco_module_rm.FilePlanComponentKind; +import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.DeclarativeWebScript; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * RM metadata used by form extension + * + * @author Roy Wetherall + */ +public class RMMetaDataGet extends DeclarativeWebScript +{ + /** Query parameters */ + private static final String PARAM_NODEREF = "noderef"; + private static final String PARAM_TYPE = "type"; + + /** NodeRef pattern */ + private static final Pattern nodeRefPattern = Pattern.compile(".+://.+/.+"); + + /** Records management service */ + private RecordsManagementService rmService; + + /** Namespace service */ + private NamespaceService namespaceService; + + /** + * @param rmService records management service + */ + public void setRecordsManagementService(RecordsManagementService rmService) + { + this.rmService = rmService; + } + + /** + * @param namespaceService namespace service + */ + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + /* + * @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status, org.alfresco.web.scripts.Cache) + */ + @Override + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + // create model object with the lists model + Map model = new HashMap(1); + + String result = "NONE"; + + // Get the nodeRef and confirm it is valid + String nodeRef = req.getParameter(PARAM_NODEREF); + if (nodeRef == null || nodeRef.length() == 0) + { + String type = req.getParameter(PARAM_TYPE); + if (type != null && type.length() != 0) + { + QName qname = QName.createQName(type, namespaceService); + FilePlanComponentKind kind = rmService.getFilePlanComponentKindFromType(qname); + if (kind != null) + { + result = kind.toString(); + } + } + } + else + { + // quick test before running slow match for full NodeRef pattern + if (nodeRef.indexOf(':') != -1) + { + Matcher m = nodeRefPattern.matcher(nodeRef); + if (m.matches()) + { + FilePlanComponentKind kind = rmService.getFilePlanComponentKind(new NodeRef(nodeRef)); + if (kind != null) + { + result = kind.toString(); + } + } + } + } + + model.put("kind", result); + return model; + } +} \ No newline at end of file