From 829a135988aeb693ed26974f576c04fb6196844b Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Wed, 1 Oct 2014 15:42:47 +0000 Subject: [PATCH] RM-1641 (Create Relationship Service) * Deprecated methods in RecordsManagementAdminService git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@86172 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../messages/admin-service.properties | 5 - .../org_alfresco_module_rm/module-context.xml | 1 - .../rm-action-context.xml | 1 + .../rm-service-context.xml | 45 +- .../rm-webscript-context.xml | 2 + .../action/impl/SplitEmailAction.java | 56 +- .../admin/RecordsManagementAdminBase.java | 376 ++++++ .../admin/RecordsManagementAdminService.java | 14 + .../RecordsManagementAdminServiceImpl.java | 1151 ++++++----------- .../event/OnReferencedRecordActionedUpon.java | 16 +- .../relationship/RelationshipDisplayName.java | 74 +- .../relationship/RelationshipService.java | 2 +- .../relationship/RelationshipServiceImpl.java | 597 +++++++-- .../script/ApplyDodCertModelFixesGet.java | 15 +- .../script/ApplyFixMob1573Get.java | 16 +- .../script/CustomReferenceDefinitionBase.java | 20 +- .../script/CustomReferenceDefinitionPut.java | 2 +- .../script/CustomReferenceDefinitionsGet.java | 2 +- .../script/CustomReferenceType.java | 11 +- .../script/CustomRefsGet.java | 2 +- ...RecordsManagementAdminServiceImplTest.java | 67 +- .../test/legacy/webscript/RmRestApiTest.java | 58 +- .../test/util/BaseRMTestCase.java | 3 + 23 files changed, 1434 insertions(+), 1102 deletions(-) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service.properties index d4fc6badd4..2e837c01a4 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service.properties @@ -6,11 +6,6 @@ rm.admin.cannot-apply-constraint=Cannot apply constraint {0} to property {1} wit rm.admin.prop-exist=The custom property {0} can't be found. rm.admin.custom-prop-exist=The custom model does not contain the property {0}. rm.admin.unknown-aspect=Unknown aspect {0}. -rm.admin.ref-exist=The custom reference {0} can't be found. -rm.admin.ref-label-in-use=The reference label {0} is already in use. -rm.admin.assoc-exists=The association {0} already exists. -rm.admin.child-assoc-exists=the child association {0} already exists. -rm.admin.cannot-find-assoc-def=The association definition {0} can't be found. rm.admin.constraint-exists=The constraint {0} already exists. rm.admin.contraint-cannot-find=The definition for constraint {0} can't be found. rm.admin.unexpected_type_constraint=Unexpected type {0} for constraint {1}. The expected is {2}. diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml index f5661c5a1a..e17a8c3935 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml @@ -143,7 +143,6 @@ - diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml index f8db542201..8824e6275c 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml @@ -678,6 +678,7 @@ + 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 b3526fb18b..3e810cbf49 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 @@ -753,24 +753,27 @@ - + + + + + + + - - - - - - - - - - rma:recordCategory - rma:recordFolder - rma:record - rma:nonElectronicDocument - - - + + + + + + + rma:recordCategory + rma:recordFolder + rma:record + rma:nonElectronicDocument + + + @@ -1526,10 +1529,8 @@ - - - - + + @@ -1566,7 +1567,7 @@ org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.getRelationshipDefinitions=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.getRelationshipDefinition=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.createRelationshipDefinition=RM_ALLOW - org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.updateReleationshipDefinition=RM_ALLOW + org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.updateRelationshipDefinition=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.removeRelationshipDefinition=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.existsRelationshipDefinition=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService.getRelationshipsFrom=RM_ALLOW diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml index c3512e1aab..9ceeb3a195 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml @@ -420,6 +420,7 @@ class="org.alfresco.module.org_alfresco_module_rm.script.ApplyDodCertModelFixesGet" parent="webscript"> + @@ -428,6 +429,7 @@ class="org.alfresco.module.org_alfresco_module_rm.script.ApplyFixMob1573Get" parent="webscript"> + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java index f585c68b5d..6d8a13861e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.action.impl; +import static org.apache.commons.lang.StringUtils.isBlank; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -26,6 +28,7 @@ import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import javax.mail.MessagingException; import javax.mail.Multipart; @@ -38,10 +41,12 @@ import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.ImapModel; import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDefinition; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; 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.dictionary.AssociationDefinition; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentReader; @@ -75,25 +80,52 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase /** Logger */ private static Log logger = LogFactory.getLog(SplitEmailAction.class); - private QName relationshipQName; + /** Relationship service */ + private RelationshipService relationshipService; + + /** + * Gets the relationship service instance + * + * @return The relationship service instance + */ + protected RelationshipService getRelationshipService() + { + return this.relationshipService; + } + + /** + * Sets the relationship service instance + * + * @param relationshipService The relationship service instance + */ + public void setRelationshipService(RelationshipService relationshipService) + { + this.relationshipService = relationshipService; + } + + /** Unique name of the relationship definition */ + private String relationshipUniqueName; public void bootstrap() { - String compoundId = recordsManagementAdminService.getCompoundIdFor(REL_FROM, REL_TO); - - Map map = recordsManagementAdminService.getCustomReferenceDefinitions(); - for (Map.Entry entry : map.entrySet()) + Set relationshipDefinitions = getRelationshipService().getRelationshipDefinitions(); + for (RelationshipDefinition relationshipDefinition : relationshipDefinitions) { - if (compoundId.equals(entry.getValue().getTitle(dictionaryService))) + RelationshipDisplayName displayName = relationshipDefinition.getDisplayName(); + String sourceText = displayName.getSourceText(); + String targetText = displayName.getTargetText(); + + if (sourceText.equals(REL_FROM) && targetText.equals(REL_TO)) { - relationshipQName = entry.getKey(); - break; + relationshipUniqueName = relationshipDefinition.getUniqueName(); } } - if (relationshipQName == null) + if (isBlank(relationshipUniqueName)) { - relationshipQName = recordsManagementAdminService.addCustomChildAssocDefinition(REL_FROM, REL_TO); + RelationshipDisplayName displayName = new RelationshipDisplayName(REL_FROM, REL_TO); + RelationshipDefinition relationshipDefinition = getRelationshipService().createRelationshipDefinition(displayName); + relationshipUniqueName = relationshipDefinition.getUniqueName(); } } @@ -246,7 +278,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase public Void doWork() { // add the relationship - recordsManagementAdminService.addCustomReference(parentRef, childRef, relationshipQName); + getRelationshipService().addRelationship(relationshipUniqueName, parentRef, childRef); // add the IMAP attachment aspect nodeService.createAssociation( diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java new file mode 100644 index 0000000000..f2b18f844e --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2005-2014 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.admin; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.dictionary.DictionaryRepositoryBootstrap; +import org.alfresco.repo.dictionary.M2Model; +import org.alfresco.repo.dictionary.M2Namespace; +import org.alfresco.service.cmr.dictionary.AspectDefinition; +import org.alfresco.service.cmr.dictionary.AssociationDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryException; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.extensions.surf.util.I18NUtil; + +/** + * Base class for RM admin services + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RecordsManagementAdminBase implements RecordsManagementCustomModel +{ + /** Logger */ + protected Log logger = LogFactory.getLog(this.getClass()); + + /** Constants */ + private static final String SOURCE_TARGET_ID_SEPARATOR = "__"; + private static final NodeRef RM_CUSTOM_MODEL_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "records_management_custom_model"); + + /** I18N */ + private static final String MSG_CUSTOM_MODEL_NOT_FOUND = "rm.admin.custom-model-not-found"; + private static final String MSG_CUSTOM_MODEL_NO_CONTENT = "rm.admin.custom-model-no-content"; + private static final String MSG_ERROR_WRITE_CUSTOM_MODEL = "rm.admin.error-write-custom-model"; + private static final String MSG_ERROR_SPLIT_ID = "rm.admin.error-split-id"; + + /** Dictionary service */ + private DictionaryService dictionaryService; + + /** Node service */ + private NodeService nodeService; + + /** Content service */ + private ContentService contentService; + + /** Namespace service */ + private NamespaceService namespaceService; + + /** Dictionary repository bootstrap */ + private DictionaryRepositoryBootstrap dictionaryRepositoryBootstrap; + + /** + * Gets the dictionary service instance + * + * @return The dictionary service instance + */ + protected DictionaryService getDictionaryService() + { + return this.dictionaryService; + } + + /** + * Gets the node service instance + * + * @return The node service instance + */ + protected NodeService getNodeService() + { + return this.nodeService; + } + + /** + * Gets the content service instance + * + * @return The content service instance + */ + protected ContentService getContentService() + { + return this.contentService; + } + + /** + * Gets the namespace service instance + * + * @return The namespace service instance + */ + protected NamespaceService getNamespaceService() + { + return this.namespaceService; + } + + /** + * Gets the dictionary repository bootstrap instance + * + * @return The dictionary repository bootstrap instance + */ + protected DictionaryRepositoryBootstrap getDictionaryRepositoryBootstrap() + { + return this.dictionaryRepositoryBootstrap; + } + + /** + * Sets the dictionary service instance + * + * @param dictionaryService The dictionary service instance + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * Sets the node service instance + * + * @param nodeService The node service instance + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * Sets the content service instance + * + * @param contentService The content service instance + */ + public void setContentService(ContentService contentService) + { + this.contentService = contentService; + } + + /** + * Sets the namespace service instance + * + * @param namespaceService The namespace service instance + */ + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + /** + * Sets the dictionary repository bootstrap instance + * + * @param dictionaryRepositoryBootstrap The dictionary repository bootstrap instance + */ + public void setDictionaryRepositoryBootstrap(DictionaryRepositoryBootstrap dictionaryRepositoryBootstrap) + { + this.dictionaryRepositoryBootstrap = dictionaryRepositoryBootstrap; + } + + /** + * Gets all the custom associations + * + * @return All custom associations + */ + protected Map getCustomAssociations() + { + Map customAssociations = new HashMap(); + + AspectDefinition aspectDefn = getDictionaryService().getAspect(ASPECT_CUSTOM_ASSOCIATIONS); + if (aspectDefn != null) + { + customAssociations.putAll(aspectDefn.getAssociations()); + } + + return customAssociations; + } + + /** + * Gets the node reference of the custom model + * + * @param uri The URI of the model namespace + * @return The node reference of the custom model + */ + protected NodeRef getCustomModelRef(String uri) + { + if ((uri.equals("")) || (uri.equals(RecordsManagementModel.RM_CUSTOM_URI))) + { + // note: short-cut for "rmc" currently assumes that RM custom model does not define additional namespaces + return RM_CUSTOM_MODEL_NODE_REF; + } + else + { + // ALF-5875 + List modelRefs = getDictionaryRepositoryBootstrap().getModelRefs(); + + for (NodeRef modelRef : modelRefs) + { + try + { + M2Model model = readCustomContentModel(modelRef); + + for (M2Namespace namespace : model.getNamespaces()) + { + if (namespace.getUri().equals(uri)) + { + return modelRef; + } + } + } + catch (DictionaryException de) + { + logger.warn("readCustomContentModel: skip model ("+modelRef+") whilst searching for uri ("+uri+"): "+de); + } + } + + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CUSTOM_MODEL_NOT_FOUND, uri)); + } + } + + /** + * Gets the deserialized model + * + * @param modelNodeRef The node reference of the model + * @return The deserialized model + */ + protected M2Model readCustomContentModel(NodeRef modelNodeRef) + { + ContentReader reader = getContentService().getReader(modelNodeRef, ContentModel.TYPE_CONTENT); + if (!reader.exists()) + { + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CUSTOM_MODEL_NO_CONTENT, modelNodeRef.toString())); + } + + InputStream contentIn = null; + M2Model deserializedModel = null; + + try + { + contentIn = reader.getContentInputStream(); + deserializedModel = M2Model.createModel(contentIn); + } + finally + { + try + { + if (contentIn != null) + { + contentIn.close(); + } + } + catch (IOException ignored) + { + // Intentionally empty. + } + } + + return deserializedModel; + } + + /** + * Updates the content of the custom model + * + * @param modelRef The node reference of the model + * @param deserializedModel The deserialized model + */ + protected void writeCustomContentModel(NodeRef modelRef, M2Model deserializedModel) + { + ContentWriter writer = getContentService().getWriter(modelRef, ContentModel.TYPE_CONTENT, true); + writer.setMimetype(MimetypeMap.MIMETYPE_XML); + writer.setEncoding("UTF-8"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + deserializedModel.toXML(baos); + + String updatedModelXml; + try + { + updatedModelXml = baos.toString("UTF-8"); + writer.putContent(updatedModelXml); + // putContent closes all resources. + // so we don't have to. + } + catch (UnsupportedEncodingException uex) + { + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_ERROR_WRITE_CUSTOM_MODEL, modelRef.toString()), uex); + } + } + + /** + * Checks if the given association definition title exists + * + * @param associationDefinitionTitle The association definition title + * @return true if the association definition title exists, false otherwise + */ + protected boolean existsTitle(String associationDefinitionTitle) + { + boolean existsLabel = false; + Collection associationDefinitions = getCustomAssociations().values(); + for (AssociationDefinition associationDefinition : associationDefinitions) + { + if (associationDefinition.getTitle(getDictionaryService()).equalsIgnoreCase(associationDefinitionTitle)) + { + existsLabel = true; + } + } + return existsLabel; + } + + /** + * Splits the association definition title into source text and target text + * + * @param sourceTargetText The text to split into source text and target text + * @return Splited association definition title which includes source text and target text + */ + protected String[] splitAssociationDefinitionTitle(String sourceTargetText) + { + if (!sourceTargetText.contains(SOURCE_TARGET_ID_SEPARATOR)) + { + throw new IllegalArgumentException(I18NUtil.getMessage(MSG_ERROR_SPLIT_ID, sourceTargetText, SOURCE_TARGET_ID_SEPARATOR)); + } + + return sourceTargetText.split(SOURCE_TARGET_ID_SEPARATOR); + } + + /** + * Creates the association definition title form the source text and target text + * + * @param sourceText The source text + * @param targetText The target text + * @return The association definition title created from the source text and target text + */ + protected String composeAssociationDefinitionTitle(String sourceText, String targetText) + { + if (sourceText.contains(SOURCE_TARGET_ID_SEPARATOR)) + { + throw new IllegalArgumentException("sourceId cannot contain '" + SOURCE_TARGET_ID_SEPARATOR + "': " + sourceText); + } + + StringBuilder sb = new StringBuilder(); + sb.append(sourceText) + .append(SOURCE_TARGET_ID_SEPARATOR) + .append(targetText); + + return sb.toString(); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminService.java index c91264641f..63ea8da6c8 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminService.java @@ -24,13 +24,16 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.MatchLogic; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.ConstraintDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; /** * Records management custom model service interface. Implementations of this class are responsible @@ -231,6 +234,7 @@ public interface RecordsManagementAdminService * in the results. * * @return The Map of custom references (both parent-child and standard). + * @deprecated as of RM 2.3, please use {@link RelationshipService#getRelationshipDefinitions()} instead. */ Map getCustomReferenceDefinitions(); @@ -239,6 +243,7 @@ public interface RecordsManagementAdminService * * @param node the node from which the associations start. * @return a List of associations. + * @deprecated as of RM 2.3, please use {@link NodeService#getTargetAssocs(NodeRef, RegexQNamePattern.MATCH_ALL)} instead. */ List getCustomReferencesFrom(NodeRef node); @@ -248,6 +253,7 @@ public interface RecordsManagementAdminService * * @param node * @return + * @deprecated as of RM 2.3, please use {@link NodeService#getChildAssocs(NodeRef)} instead. */ List getCustomChildReferences(NodeRef node); @@ -256,6 +262,7 @@ public interface RecordsManagementAdminService * * @param node the node to which the associations point. * @return a List of associations. + * @deprecated as of RM 2.3, please use {@link NodeService#getSourceAssocs(NodeRef, RegexQNamePattern.MATCH_ALL)} instead. */ List getCustomReferencesTo(NodeRef node); @@ -264,6 +271,7 @@ public interface RecordsManagementAdminService * * @param node * @return + * @deprecated as of RM 2.3, please use {@link NodeService#getParentAssocs(NodeRef)} instead. */ List getCustomParentReferences(NodeRef node); @@ -277,6 +285,7 @@ public interface RecordsManagementAdminService * @param assocId the server-side qname e.g. {http://www.alfresco.org/model/rmcustom/1.0}abcd-12-efgh-4567 * @throws AlfrescoRuntimeException if an instance of the specified reference type * already exists from fromNode to toNode. + * @deprecated as of RM 2.3, please use {@link RelationshipService#addRelationship(String, NodeRef, NodeRef)} instead. */ void addCustomReference(NodeRef fromNode, NodeRef toNode, QName assocId); @@ -286,6 +295,7 @@ public interface RecordsManagementAdminService * @param fromNode * @param toNode * @param assocId the server-side qname e.g. {http://www.alfresco.org/model/rmcustom/1.0}abcd-12-efgh-4567 + * @deprecated as of RM 2.3, please use {@link RelationshipService#removeRelationship(String, NodeRef, NodeRef)} instead. */ void removeCustomReference(NodeRef fromNode, NodeRef toNode, QName assocId); @@ -294,6 +304,7 @@ public interface RecordsManagementAdminService * * @param label the title of the association definition * @return the QName of the newly-created association. + * @deprecated as of RM 2.3, please use {@link RelationshipService#createRelationshipDefinition(org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName)} instead. */ QName addCustomAssocDefinition(String label); @@ -304,6 +315,7 @@ public interface RecordsManagementAdminService * @param source * @param target * @return the QName of the newly-created association. + * @deprecated as of RM 2.3, please use {@link RelationshipService#createRelationshipDefinition(org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName)} instead. */ QName addCustomChildAssocDefinition(String source, String target); @@ -317,6 +329,7 @@ public interface RecordsManagementAdminService * @param newTarget the new value for the target field. * @see #getCompoundIdFor(String, String) * @see #splitSourceTargetId(String) + * @deprecated as of RM 2.3, please use {@link RelationshipService#updateRelationshipDefinition(String, org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName)} instead. */ QName updateCustomChildAssocDefinition(QName refQName, String newSource, String newTarget); @@ -327,6 +340,7 @@ public interface RecordsManagementAdminService * * @param refQName qname of the child association. * @param newLabel the new value for the label field. + * @deprecated as of RM 2.3, please use {@link RelationshipService#updateRelationshipDefinition(String, org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName)} instead. */ QName updateCustomAssocDefinition(QName refQName, String newLabel); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java index 2a35b12038..9110b7a391 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java @@ -18,10 +18,9 @@ */ package org.alfresco.module.org_alfresco_module_rm.admin; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; +import static org.springframework.extensions.surf.util.ParameterCheck.mandatory; +import static org.springframework.extensions.surf.util.ParameterCheck.mandatoryString; + import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; @@ -33,31 +32,21 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.BeforeCreateReference; -import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.BeforeRemoveReference; -import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnCreateReference; -import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnRemoveReference; import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint; import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.MatchLogic; import org.alfresco.module.org_alfresco_module_rm.compatibility.CompatibilityModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.module.org_alfresco_module_rm.util.PoliciesUtil; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.dictionary.DictionaryRepositoryBootstrap; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDefinition; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; import org.alfresco.repo.dictionary.IndexTokenisationMode; import org.alfresco.repo.dictionary.M2Aspect; -import org.alfresco.repo.dictionary.M2Association; -import org.alfresco.repo.dictionary.M2ChildAssociation; -import org.alfresco.repo.dictionary.M2ClassAssociation; import org.alfresco.repo.dictionary.M2Constraint; import org.alfresco.repo.dictionary.M2Model; -import org.alfresco.repo.dictionary.M2Namespace; import org.alfresco.repo.dictionary.M2Property; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; -import org.alfresco.repo.policy.ClassPolicyDelegate; -import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.BehaviourBean; import org.alfresco.repo.policy.annotation.BehaviourKind; @@ -68,26 +57,15 @@ import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.Constraint; import org.alfresco.service.cmr.dictionary.ConstraintDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryException; -import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.GUID; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.extensions.surf.util.I18NUtil; -import org.springframework.extensions.surf.util.ParameterCheck; import org.springframework.extensions.surf.util.URLDecoder; /** @@ -96,197 +74,53 @@ import org.springframework.extensions.surf.util.URLDecoder; * @author Neil McErlean, janv */ @BehaviourBean -public class RecordsManagementAdminServiceImpl implements RecordsManagementAdminService, - RecordsManagementCustomModel, - NodeServicePolicies.OnAddAspectPolicy, - NodeServicePolicies.OnRemoveAspectPolicy, - NodeServicePolicies.OnCreateNodePolicy +public class RecordsManagementAdminServiceImpl extends RecordsManagementAdminBase implements RecordsManagementAdminService, + NodeServicePolicies.OnAddAspectPolicy, + NodeServicePolicies.OnRemoveAspectPolicy, + NodeServicePolicies.OnCreateNodePolicy { - /** Logger */ - private static Log logger = LogFactory.getLog(RecordsManagementAdminServiceImpl.class); - /** I18N messages*/ private static final String MSG_SERVICE_NOT_INIT = "rm.admin.service-not-init"; private static final String MSG_PROP_EXIST = "rm.admin.prop-exist"; private static final String MSG_CUSTOM_PROP_EXIST = "rm.admin.custom-prop-exist"; private static final String MSG_UNKNOWN_ASPECT = "rm.admin.unknown-aspect"; - private static final String MSG_REF_EXIST = "rm.admin.ref-exist"; - private static final String MSG_REF_LABEL_IN_USE = "rm.admin.ref-label-in-use"; - private static final String MSG_ASSOC_EXISTS = "rm.admin.assoc-exists"; - private static final String MSG_CHILD_ASSOC_EXISTS = "rm.admin.child-assoc-exists"; - private static final String MSG_CONNOT_FIND_ASSOC_DEF = "rm.admin.cannot-find-assoc-def"; private static final String MSG_CONSTRAINT_EXISTS = "rm.admin.constraint-exists"; private static final String MSG_CANNOT_FIND_CONSTRAINT = "rm.admin.contraint-cannot-find"; private static final String MSG_UNEXPECTED_TYPE_CONSTRAINT = "rm.admin.unexpected_type_constraint"; - private static final String MSG_CUSTOM_MODEL_NOT_FOUND = "rm.admin.custom-model-not-found"; - private static final String MSG_CUSTOM_MODEL_NO_CONTENT = "rm.admin.custom-model-no-content"; - private static final String MSG_ERROR_WRITE_CUSTOM_MODEL = "rm.admin.error-write-custom-model"; private static final String MSG_ERROR_CLIENT_ID = "rm.admin.error-client-id"; - private static final String MSG_ERROR_SPLIT_ID = "rm.admin.error-split-id"; /** Constants */ - public static final String RMC_CUSTOM_ASSOCS = RecordsManagementCustomModel.RM_CUSTOM_PREFIX + ":customAssocs"; private static final String CUSTOM_CONSTRAINT_TYPE = org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.class.getName(); private static final String CAPATIBILITY_CUSTOM_CONTRAINT_TYPE = org.alfresco.module.org_alfresco_module_dod5015.caveat.RMListOfValuesConstraint.class.getName(); - private static final NodeRef RM_CUSTOM_MODEL_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "records_management_custom_model"); private static final String PARAM_ALLOWED_VALUES = "allowedValues"; private static final String PARAM_CASE_SENSITIVE = "caseSensitive"; private static final String PARAM_MATCH_LOGIC = "matchLogic"; - public static final String RMA_RECORD = "rma:record"; - private static final String SOURCE_TARGET_ID_SEPARATOR = "__"; - /** Dictionary service */ - private DictionaryService dictionaryService; - - /** Namespace service */ - private NamespaceService namespaceService; - - /** Node service */ - private NodeService nodeService; - - /** Content service */ - private ContentService contentService; - - /** Dictionary repository bootstrap */ - private DictionaryRepositoryBootstrap dictonaryRepositoryBootstrap; - - /** Policy component */ - private PolicyComponent policyComponent; - - /** Policy delegates */ - private ClassPolicyDelegate beforeCreateReferenceDelegate; - private ClassPolicyDelegate onCreateReferenceDelegate; - private ClassPolicyDelegate beforeRemoveReferenceDelegate; - private ClassPolicyDelegate onRemoveReferenceDelegate; + /** Relationship service */ + private RelationshipService relationshipService; /** List of types that can be customisable */ private List pendingCustomisableTypes; private Map customisableTypes; /** - * @param dictionaryService the dictionary service + * Sets the relationship instance + * + * @param relationshipService The relationship service instance */ - public void setDictionaryService(DictionaryService dictionaryService) + public void setRelationshipService(RelationshipService relationshipService) { - this.dictionaryService = dictionaryService; - } - - /** - * @param namespaceService the namespace service - */ - public void setNamespaceService(NamespaceService namespaceService) - { - this.namespaceService = namespaceService; - } - - /** - * @param nodeService the node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @param contentService the content service - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - /** - * @param policyComponent the policy component - */ - public void setPolicyComponent(PolicyComponent policyComponent) - { - this.policyComponent = policyComponent; + this.relationshipService = relationshipService; } /** - * Bootstrap for standard (non-RMC) dynamic models + * Gets the relationship service instance * - * @param dictonaryRepositoryBootstrap dictionary repository bootstrap + * @return The relationship service instance */ - public void setDictionaryRepositoryBootstrap(DictionaryRepositoryBootstrap dictonaryRepositoryBootstrap) + protected RelationshipService getRelationshipService() { - this.dictonaryRepositoryBootstrap = dictonaryRepositoryBootstrap; - } - - /** - * Initialisation method - */ - public void init() - { - // Register the various policies - beforeCreateReferenceDelegate = policyComponent.registerClassPolicy(BeforeCreateReference.class); - onCreateReferenceDelegate = policyComponent.registerClassPolicy(OnCreateReference.class); - beforeRemoveReferenceDelegate = policyComponent.registerClassPolicy(BeforeRemoveReference.class); - onRemoveReferenceDelegate = policyComponent.registerClassPolicy(OnRemoveReference.class); - } - - /** - * Invoke before create reference policy - * - * @param fromNodeRef - * @param toNodeRef - * @param reference - */ - protected void invokeBeforeCreateReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) - { - // get qnames to invoke against - Set qnames = PoliciesUtil.getTypeAndAspectQNames(nodeService, fromNodeRef); - // execute policy for node type and aspects - BeforeCreateReference policy = beforeCreateReferenceDelegate.get(qnames); - policy.beforeCreateReference(fromNodeRef, toNodeRef, reference); - } - - /** - * Invoke on create reference policy - * - * @param fromNodeRef - * @param toNodeRef - * @param reference - */ - protected void invokeOnCreateReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) - { - // get qnames to invoke against - Set qnames = PoliciesUtil.getTypeAndAspectQNames(nodeService, fromNodeRef); - // execute policy for node type and aspects - OnCreateReference policy = onCreateReferenceDelegate.get(qnames); - policy.onCreateReference(fromNodeRef, toNodeRef, reference); - } - - /** - * Invoke before remove reference policy - * - * @param fromNodeRef - * @param toNodeRef - * @param reference - */ - protected void invokeBeforeRemoveReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) - { - // get qnames to invoke against - Set qnames = PoliciesUtil.getTypeAndAspectQNames(nodeService, fromNodeRef); - // execute policy for node type and aspects - BeforeRemoveReference policy = beforeRemoveReferenceDelegate.get(qnames); - policy.beforeRemoveReference(fromNodeRef, toNodeRef, reference); - } - - /** - * Invoke on remove reference policy - * - * @param fromNodeRef - * @param toNodeRef - * @param reference - */ - protected void invokeOnRemoveReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) - { - // get qnames to invoke against - Set qnames = PoliciesUtil.getTypeAndAspectQNames(nodeService, fromNodeRef); - // execute policy for node type and aspects - OnRemoveReference policy = onRemoveReferenceDelegate.get(qnames); - policy.onRemoveReference(fromNodeRef, toNodeRef, reference); + return this.relationshipService; } /** @@ -301,17 +135,20 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onAddAspect(final NodeRef nodeRef, final QName aspectTypeQName) { + mandatory("nodeRef", nodeRef); + mandatory("aspectTypeQName", aspectTypeQName); + AuthenticationUtil.runAs(new RunAsWork() { @Override public Void doWork() { - if (nodeService.exists(nodeRef) && - dictionaryService.getAllModels().contains(RM_CUSTOM_MODEL) && + if (getNodeService().exists(nodeRef) && + getDictionaryService().getAllModels().contains(RM_CUSTOM_MODEL) && isCustomisable(aspectTypeQName)) { QName customPropertyAspect = getCustomAspect(aspectTypeQName); - nodeService.addAspect(nodeRef, customPropertyAspect, null); + getNodeService().addAspect(nodeRef, customPropertyAspect, null); } return null; @@ -331,16 +168,19 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onRemoveAspect(final NodeRef nodeRef, final QName aspectTypeQName) { + mandatory("nodeRef", nodeRef); + mandatory("aspectTypeQName", aspectTypeQName); + AuthenticationUtil.runAs(new RunAsWork() { @Override public Void doWork() { - if (nodeService.exists(nodeRef) && + if (getNodeService().exists(nodeRef) && isCustomisable(aspectTypeQName)) { QName customPropertyAspect = getCustomAspect(aspectTypeQName); - nodeService.removeAspect(nodeRef, customPropertyAspect); + getNodeService().removeAspect(nodeRef, customPropertyAspect); } return null; @@ -362,24 +202,26 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onCreateNode(final ChildAssociationRef childAssocRef) { + mandatory("nodeRef", childAssocRef); + AuthenticationUtil.runAs(new RunAsWork() { @Override public Void doWork() { - if (dictionaryService.getAllModels().contains(RecordsManagementCustomModel.RM_CUSTOM_MODEL)) + if (getDictionaryService().getAllModels().contains(RecordsManagementCustomModel.RM_CUSTOM_MODEL)) { NodeRef nodeRef = childAssocRef.getChildRef(); - QName type = nodeService.getType(nodeRef); + QName type = getNodeService().getType(nodeRef); while (type != null && !ContentModel.TYPE_CMOBJECT.equals(type)) { if (isCustomisable(type)) { QName customPropertyAspect = getCustomAspect(type); - nodeService.addAspect(nodeRef, customPropertyAspect, null); + getNodeService().addAspect(nodeRef, customPropertyAspect, null); } - TypeDefinition def = dictionaryService.getType(type); + TypeDefinition def = getDictionaryService().getType(type); if (def != null) { type = def.getParentName(); @@ -410,11 +252,13 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public void setCustomisableTypes(List customisableTypes) { - pendingCustomisableTypes = new ArrayList(); - for (String customisableType : customisableTypes) - { - pendingCustomisableTypes.add(QName.createQName(customisableType, namespaceService)); - } + mandatory("customisableTypes", customisableTypes); + + pendingCustomisableTypes = new ArrayList(); + for (String customisableType : customisableTypes) + { + pendingCustomisableTypes.add(QName.createQName(customisableType, getNamespaceService())); + } } /** @@ -422,7 +266,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public Set getCustomisable() { - return getCustomisableMap().keySet(); + return getCustomisableMap().keySet(); } /** @@ -431,10 +275,12 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin @Override public Set getCustomisable(NodeRef nodeRef) { + mandatory("nodeRef", nodeRef); + Set result = new HashSet(5); // Check the nodes hierarchy for customisable types - QName type = nodeService.getType(nodeRef); + QName type = getNodeService().getType(nodeRef); while (type != null && !ContentModel.TYPE_CMOBJECT.equals(type)) { // Add to the list if the type is customisable @@ -444,7 +290,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } // Type and get the types parent - TypeDefinition def = dictionaryService.getType(type); + TypeDefinition def = getDictionaryService().getType(type); if (def != null) { type = def.getParentName(); @@ -456,7 +302,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } // Get all the nodes aspects - Set aspects = nodeService.getAspects(nodeRef); + Set aspects = getNodeService().getAspects(nodeRef); for (QName aspect : aspects) { QName tempAspect = QName.createQName(aspect.toString()); @@ -469,7 +315,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } // Try and get the parent aspect - AspectDefinition aspectDef = dictionaryService.getAspect(tempAspect); + AspectDefinition aspectDef = getDictionaryService().getAspect(tempAspect); if (aspectDef != null) { tempAspect = aspectDef.getParentName(); @@ -491,86 +337,86 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ private Map getCustomisableMap() { - if (customisableTypes == null) - { - customisableTypes = new HashMap(7); - Collection aspects = dictionaryService.getAspects(RM_CUSTOM_MODEL); - for (QName aspect : aspects) - { - AspectDefinition aspectDef = dictionaryService.getAspect(aspect); - String name = aspectDef.getName().getLocalName(); - if (name.endsWith("Properties")) - { - QName type = null; - String prefixString = aspectDef.getDescription(dictionaryService); - if (prefixString == null) - { - // Backward compatibility from previous RM V1.0 custom models - if (CompatibilityModel.NAME_CUSTOM_RECORD_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.ASPECT_RECORD; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_FOLDER_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.TYPE_RECORD_FOLDER; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_CATEGORY_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.TYPE_RECORD_CATEGORY; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_SERIES_PROPERTIES.equals(name) && + if (customisableTypes == null) + { + customisableTypes = new HashMap(7); + Collection aspects = getDictionaryService().getAspects(RM_CUSTOM_MODEL); + for (QName aspect : aspects) + { + AspectDefinition aspectDef = getDictionaryService().getAspect(aspect); + String name = aspectDef.getName().getLocalName(); + if (name.endsWith("Properties")) + { + QName type = null; + String prefixString = aspectDef.getDescription(getDictionaryService()); + if (prefixString == null) + { + // Backward compatibility from previous RM V1.0 custom models + if (CompatibilityModel.NAME_CUSTOM_RECORD_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.ASPECT_RECORD; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_FOLDER_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.TYPE_RECORD_FOLDER; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_CATEGORY_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.TYPE_RECORD_CATEGORY; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_SERIES_PROPERTIES.equals(name) && // Only add the deprecated record series type as customisable if // a v1.0 installation has added custom properties - aspectDef.getProperties().size() != 0) - { - type = CompatibilityModel.TYPE_RECORD_SERIES; - } - } - else - { - type = QName.createQName(prefixString, namespaceService); - } + aspectDef.getProperties().size() != 0) + { + type = CompatibilityModel.TYPE_RECORD_SERIES; + } + } + else + { + type = QName.createQName(prefixString, getNamespaceService()); + } - // Add the customisable type to the map - if (type != null) - { - customisableTypes.put(type, aspect); + // Add the customisable type to the map + if (type != null) + { + customisableTypes.put(type, aspect); - // Remove customisable type from the pending list - if (pendingCustomisableTypes != null && pendingCustomisableTypes.contains(type)) - { - pendingCustomisableTypes.remove(type); - } - } - } - } + // Remove customisable type from the pending list + if (pendingCustomisableTypes != null && pendingCustomisableTypes.contains(type)) + { + pendingCustomisableTypes.remove(type); + } + } + } + } - // Deal with any pending types left over - if (pendingCustomisableTypes != null && pendingCustomisableTypes.size() != 0) - { - NodeRef modelRef = getCustomModelRef(RecordsManagementModel.RM_CUSTOM_URI); + // Deal with any pending types left over + if (pendingCustomisableTypes != null && pendingCustomisableTypes.size() != 0) + { + NodeRef modelRef = getCustomModelRef(RecordsManagementModel.RM_CUSTOM_URI); M2Model model = readCustomContentModel(modelRef); - try - { - for (QName customisableType : pendingCustomisableTypes) - { - QName customAspect = getCustomAspectImpl(customisableType); + try + { + for (QName customisableType : pendingCustomisableTypes) + { + QName customAspect = getCustomAspectImpl(customisableType); - // Create the new aspect to hold the custom properties - M2Aspect aspect = model.createAspect(customAspect.toPrefixString(namespaceService)); - aspect.setDescription(customisableType.toPrefixString(namespaceService)); + // Create the new aspect to hold the custom properties + M2Aspect aspect = model.createAspect(customAspect.toPrefixString(getNamespaceService())); + aspect.setDescription(customisableType.toPrefixString(getNamespaceService())); - // Make a record of the customisable type + // Make a record of the customisable type customisableTypes.put(customisableType, customAspect); - } - } - finally - { - writeCustomContentModel(modelRef, model); - } - } - } - return customisableTypes; + } + } + finally + { + writeCustomContentModel(modelRef, model); + } + } + } + return customisableTypes; } /** @@ -581,13 +427,13 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ private QName getCustomAspect(QName customisableType) { - Map map = getCustomisableMap(); - QName result = map.get(customisableType); - if (result == null) - { - result = getCustomAspectImpl(customisableType); - } - return result; + Map map = getCustomisableMap(); + QName result = map.get(customisableType); + if (result == null) + { + result = getCustomAspectImpl(customisableType); + } + return result; } /** @@ -598,7 +444,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ private QName getCustomAspectImpl(QName customisableType) { - String localName = customisableType.toPrefixString(namespaceService).replace(":", ""); + String localName = customisableType.toPrefixString(getNamespaceService()).replace(":", ""); localName = MessageFormat.format("{0}CustomProperties", localName); return QName.createQName(RM_CUSTOM_URI, localName); } @@ -609,8 +455,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin @Override public boolean isCustomisable(QName type) { - ParameterCheck.mandatory("type", type); - return getCustomisable().contains(type); + mandatory("type", type); + + return getCustomisable().contains(type); } /** @@ -619,33 +466,33 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin @Override public void makeCustomisable(QName type) { - ParameterCheck.mandatory("type", type); + mandatory("type", type); - if (customisableTypes == null) - { - // Add the type to the pending list - pendingCustomisableTypes.add(type); - } - else - { - QName customAspect = getCustomAspect(type); - if (dictionaryService.getAspect(customAspect) == null) - { - NodeRef modelRef = getCustomModelRef(customAspect.getNamespaceURI()); - M2Model model = readCustomContentModel(modelRef); - try - { - // Create the new aspect to hold the custom properties - M2Aspect aspect = model.createAspect(customAspect.toPrefixString(namespaceService)); - aspect.setDescription(type.toPrefixString(namespaceService)); - } - finally - { - writeCustomContentModel(modelRef, model); - } - customisableTypes.put(type, customAspect); - } - } + if (customisableTypes == null) + { + // Add the type to the pending list + pendingCustomisableTypes.add(type); + } + else + { + QName customAspect = getCustomAspect(type); + if (getDictionaryService().getAspect(customAspect) == null) + { + NodeRef modelRef = getCustomModelRef(customAspect.getNamespaceURI()); + M2Model model = readCustomContentModel(modelRef); + try + { + // Create the new aspect to hold the custom properties + M2Aspect aspect = model.createAspect(customAspect.toPrefixString(getNamespaceService())); + aspect.setDescription(type.toPrefixString(getNamespaceService())); + } + finally + { + writeCustomContentModel(modelRef, model); + } + customisableTypes.put(type, customAspect); + } + } } /** @@ -654,31 +501,31 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin @Override public void unmakeCustomisable(QName type) { - ParameterCheck.mandatory("type", type); + mandatory("type", type); - if (customisableTypes == null) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_SERVICE_NOT_INIT)); - } + if (customisableTypes == null) + { + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_SERVICE_NOT_INIT)); + } - QName customAspect = getCustomAspect(type); - if (dictionaryService.getAspect(customAspect) != null) - { - // TODO need to confirm that the custom properties are not being used! + QName customAspect = getCustomAspect(type); + if (getDictionaryService().getAspect(customAspect) != null) + { + // TODO need to confirm that the custom properties are not being used! - NodeRef modelRef = getCustomModelRef(customAspect.getNamespaceURI()); - M2Model model = readCustomContentModel(modelRef); - try - { - // Create the new aspect to hold the custom properties - model.removeAspect(customAspect.toPrefixString(namespaceService)); - } - finally - { - writeCustomContentModel(modelRef, model); - } - customisableTypes.remove(type); - } + NodeRef modelRef = getCustomModelRef(customAspect.getNamespaceURI()); + M2Model model = readCustomContentModel(modelRef); + try + { + // Create the new aspect to hold the custom properties + model.removeAspect(customAspect.toPrefixString(getNamespaceService())); + } + finally + { + writeCustomContentModel(modelRef, model); + } + customisableTypes.remove(type); + } } /** @@ -687,15 +534,15 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin @Override public boolean existsCustomProperty(QName propertyName) { - ParameterCheck.mandatory("propertyName", propertyName); + mandatory("propertyName", propertyName); - boolean result = false; - if (RM_CUSTOM_URI.equals(propertyName.getNamespaceURI()) && - dictionaryService.getProperty(propertyName) != null) - { - result = true; - } - return result; + boolean result = false; + if (RM_CUSTOM_URI.equals(propertyName.getNamespaceURI()) && + getDictionaryService().getProperty(propertyName) != null) + { + result = true; + } + return result; } /** @@ -703,15 +550,15 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public Map getCustomPropertyDefinitions() { - Map result = new HashMap(); - for (QName customisableType : getCustomisable()) - { - Map props = getCustomPropertyDefinitions(customisableType); - if (props != null) - { - result.putAll(props); - } - } + Map result = new HashMap(); + for (QName customisableType : getCustomisable()) + { + Map props = getCustomPropertyDefinitions(customisableType); + if (props != null) + { + result.putAll(props); + } + } return result; } @@ -720,12 +567,14 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public Map getCustomPropertyDefinitions(QName customisableType) { - Map propDefns = null; - QName relevantAspectQName = getCustomAspect(customisableType); - AspectDefinition aspectDefn = dictionaryService.getAspect(relevantAspectQName); + mandatory("customisableType", customisableType); + + Map propDefns = null; + QName relevantAspectQName = getCustomAspect(customisableType); + AspectDefinition aspectDefn = getDictionaryService().getAspect(relevantAspectQName); if (aspectDefn != null) { - propDefns = aspectDefn.getProperties(); + propDefns = aspectDefn.getProperties(); } return propDefns; @@ -757,7 +606,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin { if (!isCustomisable(aspectName)) { - throw new NotCustomisableMetadataException(aspectName.toPrefixString(namespaceService)); + throw new NotCustomisableMetadataException(aspectName.toPrefixString(getNamespaceService())); } // title parameter is currently ignored. Intentionally. @@ -767,22 +616,22 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin propId = this.generateQNameFor(label); } - ParameterCheck.mandatory("aspectName", aspectName); - ParameterCheck.mandatory("label", label); - ParameterCheck.mandatory("dataType", dataType); + mandatory("aspectName", aspectName); + mandatory("label", label); + mandatory("dataType", dataType); NodeRef modelRef = getCustomModelRef(propId.getNamespaceURI()); M2Model deserializedModel = readCustomContentModel(modelRef); QName customAspect = getCustomAspect(aspectName); - M2Aspect customPropsAspect = deserializedModel.getAspect(customAspect.toPrefixString(namespaceService)); + M2Aspect customPropsAspect = deserializedModel.getAspect(customAspect.toPrefixString(getNamespaceService())); if (customPropsAspect == null) { - throw new InvalidCustomAspectMetadataException(customAspect, aspectName.toPrefixString(namespaceService)); + throw new InvalidCustomAspectMetadataException(customAspect, aspectName.toPrefixString(getNamespaceService())); } - String propIdAsString = propId.toPrefixString(namespaceService); + String propIdAsString = propId.toPrefixString(getNamespaceService()); M2Property customProp = customPropsAspect.getProperty(propIdAsString); if (customProp != null) { @@ -791,7 +640,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin M2Property newProp = customPropsAspect.createProperty(propIdAsString); newProp.setName(propIdAsString); - newProp.setType(dataType.toPrefixString(namespaceService)); + newProp.setType(dataType.toPrefixString(getNamespaceService())); // Note that the title is used to store the RM 'label'. newProp.setTitle(label); @@ -814,7 +663,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin throw new CannotApplyConstraintMetadataException(lovConstraint, propIdAsString, dataType); } - String lovConstraintQNameAsString = lovConstraint.toPrefixString(namespaceService); + String lovConstraintQNameAsString = lovConstraint.toPrefixString(getNamespaceService()); newProp.addConstraintRef(lovConstraintQNameAsString); } @@ -834,9 +683,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public QName updateCustomPropertyDefinitionName(QName propQName, String newName) throws CustomMetadataException { - ParameterCheck.mandatory("propQName", propQName); + mandatory("propQName", propQName); - PropertyDefinition propDefn = dictionaryService.getProperty(propQName); + PropertyDefinition propDefn = getDictionaryService().getProperty(propQName); if (propDefn == null) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_PROP_EXIST, propQName)); @@ -850,11 +699,11 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin QName newPropQName = getQNameForClientId(newName); if (newPropQName != null) { - PropertyDefinition newPropDefn = dictionaryService.getProperty(newPropQName); + PropertyDefinition newPropDefn = getDictionaryService().getProperty(newPropQName); if (newPropDefn != null && !propDefn.equals(newPropDefn)) { // The requested QName is already in use - String propIdAsString = newPropQName.toPrefixString(namespaceService); + String propIdAsString = newPropQName.toPrefixString(getNamespaceService()); throw new PropertyAlreadyExistsMetadataException(propIdAsString); } } @@ -881,9 +730,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public QName setCustomPropertyDefinitionLabel(QName propQName, String newLabel) { - ParameterCheck.mandatory("propQName", propQName); + mandatory("propQName", propQName); - PropertyDefinition propDefn = dictionaryService.getProperty(propQName); + PropertyDefinition propDefn = getDictionaryService().getProperty(propQName); if (propDefn == null) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_PROP_EXIST, propQName)); @@ -916,9 +765,10 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public QName setCustomPropertyDefinitionConstraint(QName propQName, QName newLovConstraint) { - ParameterCheck.mandatory("propQName", propQName); + mandatory("propQName", propQName); + mandatory("newLovConstraint", newLovConstraint); - PropertyDefinition propDefn = dictionaryService.getProperty(propQName); + PropertyDefinition propDefn = getDictionaryService().getProperty(propQName); if (propDefn == null) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_PROP_EXIST, propQName)); @@ -930,12 +780,12 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin M2Property targetProp = findProperty(propQName, deserializedModel); String dataType = targetProp.getType(); - if (! dataType.equals(DataTypeDefinition.TEXT.toPrefixString(namespaceService))) + if (! dataType.equals(DataTypeDefinition.TEXT.toPrefixString(getNamespaceService()))) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(CannotApplyConstraintMetadataException.MSG_CANNOT_APPLY_CONSTRAINT, newLovConstraint, targetProp.getName(), dataType)); } - String lovConstraintQNameAsString = newLovConstraint.toPrefixString(namespaceService); + String lovConstraintQNameAsString = newLovConstraint.toPrefixString(getNamespaceService()); // Add the constraint - if it isn't already there. String refOfExistingConstraint = null; @@ -967,9 +817,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public QName removeCustomPropertyDefinitionConstraints(QName propQName) { - ParameterCheck.mandatory("propQName", propQName); + mandatory("propQName", propQName); - PropertyDefinition propDefn = dictionaryService.getProperty(propQName); + PropertyDefinition propDefn = getDictionaryService().getProperty(propQName); if (propDefn == null) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_PROP_EXIST, propQName)); @@ -1010,7 +860,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin { for (M2Property prop : aspect.getProperties()) { - if (propQName.toPrefixString(namespaceService).equals(prop.getName())) + if (propQName.toPrefixString(getNamespaceService()).equals(prop.getName())) { return prop; } @@ -1024,12 +874,12 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public void removeCustomPropertyDefinition(QName propQName) { - ParameterCheck.mandatory("propQName", propQName); + mandatory("propQName", propQName); NodeRef modelRef = getCustomModelRef(propQName.getNamespaceURI()); M2Model deserializedModel = readCustomContentModel(modelRef); - String propQNameAsString = propQName.toPrefixString(namespaceService); + String propQNameAsString = propQName.toPrefixString(getNamespaceService()); String aspectName = null; @@ -1039,7 +889,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin // attempt to delete the property definition. for (QName customisableType : getCustomisable()) { - aspectName = getCustomAspect(customisableType).toPrefixString(namespaceService); + aspectName = getCustomAspect(customisableType).toPrefixString(getNamespaceService()); M2Aspect customPropsAspect = deserializedModel.getAspect(aspectName); if (customPropsAspect == null) @@ -1082,123 +932,41 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public Map getCustomReferenceDefinitions() { - AspectDefinition aspectDefn = dictionaryService.getAspect(ASPECT_CUSTOM_ASSOCIATIONS); - Map assocDefns = aspectDefn.getAssociations(); - - return assocDefns; + return getCustomAssociations(); } /** * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementAdminService#addCustomReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) */ - public void addCustomReference(NodeRef fromNode, NodeRef toNode, QName refId) - { - // Check that a definition for the reference type exists. - Map availableAssocs = this.getCustomReferenceDefinitions(); + public void addCustomReference(NodeRef fromNode, NodeRef toNode, QName refId) + { + mandatory("fromNode", fromNode); + mandatory("toNode", toNode); + mandatory("refId", refId); - AssociationDefinition assocDef = availableAssocs.get(refId); - if (assocDef == null) - { - throw new IllegalArgumentException(I18NUtil.getMessage(MSG_REF_EXIST, refId)); - } + getRelationshipService().addRelationship(refId.getLocalName(), fromNode, toNode); + } - // Check if an instance of this reference type already exists in the same direction. - boolean associationAlreadyExists = false; - if (assocDef.isChild()) - { - List childAssocs = nodeService.getChildAssocs(fromNode, assocDef.getName(), assocDef.getName()); - for (ChildAssociationRef chAssRef : childAssocs) - { - if (chAssRef.getChildRef().equals(toNode)) - { - associationAlreadyExists = true; - } - } - } - else - { - List assocs = nodeService.getTargetAssocs(fromNode, assocDef.getName()); - for (AssociationRef assRef : assocs) - { - if (assRef.getTargetRef().equals(toNode)) - { - associationAlreadyExists = true; - } - } - } - if (associationAlreadyExists) - { - StringBuilder msg = new StringBuilder(); - msg.append("Association '").append(refId).append("' already exists from ") - .append(fromNode).append(" to ").append(toNode); - throw new AlfrescoRuntimeException(msg.toString()); - } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#removeCustomReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) + */ + public void removeCustomReference(final NodeRef fromNode, final NodeRef toNode, final QName assocId) + { + mandatory("fromNode", fromNode); + mandatory("toNode", toNode); + mandatory("assocId",assocId); - // Invoke before create reference policy - invokeBeforeCreateReference(fromNode, toNode, refId); - - if (assocDef.isChild()) - { - this.nodeService.addChild(fromNode, toNode, refId, refId); - } - else - { - this.nodeService.createAssociation(fromNode, toNode, refId); - } - - // Invoke on create reference policy - invokeOnCreateReference(fromNode, toNode, refId); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#removeCustomReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) - */ - public void removeCustomReference(final NodeRef fromNode, final NodeRef toNode, final QName assocId) - { - Map availableAssocs = this.getCustomReferenceDefinitions(); - - AssociationDefinition assocDef = availableAssocs.get(assocId); - if (assocDef == null) - { - throw new IllegalArgumentException(I18NUtil.getMessage(MSG_REF_EXIST, assocId)); - } - - invokeBeforeRemoveReference(fromNode, toNode, assocId); - - if (assocDef.isChild()) - { - AuthenticationUtil.runAsSystem(new RunAsWork() - { - @Override - public Void doWork() - { - List children = nodeService.getChildAssocs(fromNode); - for (ChildAssociationRef chRef : children) - { - if (assocId.equals(chRef.getTypeQName()) && chRef.getChildRef().equals(toNode)) - { - nodeService.removeChildAssociation(chRef); - } - } - - return null; - } - }); - } - else - { - nodeService.removeAssociation(fromNode, toNode, assocId); - } - - invokeOnRemoveReference(fromNode, toNode, assocId); - } + getRelationshipService().removeRelationship(assocId.getLocalName(), fromNode, toNode); + } /** * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#getCustomReferencesFrom(org.alfresco.service.cmr.repository.NodeRef) */ public List getCustomReferencesFrom(NodeRef node) { - return nodeService.getTargetAssocs(node, RegexQNamePattern.MATCH_ALL); + mandatory("node", node); + + return getNodeService().getTargetAssocs(node, RegexQNamePattern.MATCH_ALL); } /** @@ -1206,7 +974,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public List getCustomChildReferences(NodeRef node) { - return nodeService.getChildAssocs(node); + mandatory("node", node); + + return getNodeService().getChildAssocs(node); } /** @@ -1214,7 +984,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public List getCustomReferencesTo(NodeRef node) { - return nodeService.getSourceAssocs(node, RegexQNamePattern.MATCH_ALL); + mandatory("node", node); + + return getNodeService().getSourceAssocs(node, RegexQNamePattern.MATCH_ALL); } /** @@ -1222,206 +994,83 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin */ public List getCustomParentReferences(NodeRef node) { - return nodeService.getParentAssocs(node); - } + mandatory("node", node); - // note: currently RMC custom assocs only - public QName addCustomAssocDefinition(String label) - { - ParameterCheck.mandatoryString("label", label); - - // If this label is already taken... - if (existsLabel(label)) - { - throw new IllegalArgumentException(I18NUtil.getMessage(MSG_REF_LABEL_IN_USE, label)); - } - - // defaults to RM_CUSTOM_URI - NodeRef modelRef = getCustomModelRef(""); - M2Model deserializedModel = readCustomContentModel(modelRef); - - String aspectName = RecordsManagementAdminServiceImpl.RMC_CUSTOM_ASSOCS; - - M2Aspect customAssocsAspect = deserializedModel.getAspect(aspectName); - - if (customAssocsAspect == null) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UNKNOWN_ASPECT, aspectName)); - } - - QName generatedQName = this.generateQNameFor(label); - String generatedShortQName = generatedQName.toPrefixString(namespaceService); - - M2ClassAssociation customAssoc = customAssocsAspect.getAssociation(generatedShortQName); - if (customAssoc != null) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_ASSOC_EXISTS, generatedShortQName)); - } - - M2Association newAssoc = customAssocsAspect.createAssociation(generatedShortQName); - newAssoc.setSourceMandatory(false); - newAssoc.setTargetMandatory(false); - - // MOB-1573 - newAssoc.setSourceMany(true); - newAssoc.setTargetMany(true); - - // The label is stored in the title. - newAssoc.setTitle(label); - - // TODO Could be the customAssocs aspect - newAssoc.setTargetClassName(RecordsManagementAdminServiceImpl.RMA_RECORD); - - writeCustomContentModel(modelRef, deserializedModel); - - if (logger.isInfoEnabled()) - { - logger.info("addCustomAssocDefinition: ("+label+")"); - } - - return generatedQName; - } - - private boolean existsLabel(String label) - { - for (AssociationDefinition associationDefinition : getCustomReferenceDefinitions().values()) - { - if (associationDefinition.getTitle(dictionaryService).equalsIgnoreCase(label)) - { - return true; - } - } - return false; - } - - // note: currently RMC custom assocs only - public QName addCustomChildAssocDefinition(String source, String target) - { - ParameterCheck.mandatoryString("source", source); - ParameterCheck.mandatoryString("target", target); - - String compoundID = this.getCompoundIdFor(source, target); - if (existsLabel(compoundID)) - { - return null; - } - - // defaults to RM_CUSTOM_URI - NodeRef modelRef = getCustomModelRef(""); - M2Model deserializedModel = readCustomContentModel(modelRef); - - String aspectName = RecordsManagementAdminServiceImpl.RMC_CUSTOM_ASSOCS; - - M2Aspect customAssocsAspect = deserializedModel.getAspect(aspectName); - - if (customAssocsAspect == null) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UNKNOWN_ASPECT, aspectName)); - } - - M2ClassAssociation customAssoc = customAssocsAspect.getAssociation(compoundID); - if (customAssoc != null) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CHILD_ASSOC_EXISTS, compoundID)); - } - QName generatedQName = this.generateQNameFor(compoundID); - - M2ChildAssociation newAssoc = customAssocsAspect.createChildAssociation(generatedQName.toPrefixString(namespaceService)); - newAssoc.setSourceMandatory(false); - newAssoc.setTargetMandatory(false); - - // MOB-1573 - newAssoc.setSourceMany(true); - newAssoc.setTargetMany(true); - - // source and target are stored in title. - newAssoc.setTitle(compoundID); - - // TODO Could be the custom assocs aspect - newAssoc.setTargetClassName(RecordsManagementAdminServiceImpl.RMA_RECORD); - - writeCustomContentModel(modelRef, deserializedModel); - - if (logger.isInfoEnabled()) - { - logger.info("addCustomChildAssocDefinition: ("+source+","+target+")"); - } - - return generatedQName; - } - - // note: currently RMC custom assocs only - public QName updateCustomChildAssocDefinition(QName refQName, String newSource, String newTarget) - { - String compoundId = getCompoundIdFor(newSource, newTarget); - // If this compoundId is already taken... - if (existsLabel(compoundId)) - { - throw new IllegalArgumentException(I18NUtil.getMessage(MSG_REF_LABEL_IN_USE, compoundId)); - } - return persistUpdatedAssocTitle(refQName, compoundId); - } - - // note: currently RMC custom assocs only - public QName updateCustomAssocDefinition(QName refQName, String newLabel) - { - // If this label is already taken... - if (existsLabel(newLabel)) - { - throw new IllegalArgumentException(I18NUtil.getMessage(MSG_REF_LABEL_IN_USE, newLabel)); - } - return persistUpdatedAssocTitle(refQName, newLabel); + return getNodeService().getParentAssocs(node); } /** - * This method writes the specified String into the association's title property. - * For RM custom properties and references, Title is used to store the identifier. + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#addCustomAssocDefinition(java.lang.String) + * + * note: currently RMC custom assocs only */ - // note: currently RMC custom assocs only - private QName persistUpdatedAssocTitle(QName refQName, String newTitle) + public QName addCustomAssocDefinition(String label) { - ParameterCheck.mandatory("refQName", refQName); + mandatoryString("label", label); - AssociationDefinition assocDefn = dictionaryService.getAssociation(refQName); - if (assocDefn == null) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CONNOT_FIND_ASSOC_DEF, refQName)); - } - - // defaults to RM_CUSTOM_URI - NodeRef modelRef = getCustomModelRef(""); - M2Model deserializedModel = readCustomContentModel(modelRef); - - M2Aspect customAssocsAspect = deserializedModel.getAspect(RMC_CUSTOM_ASSOCS); - - for (M2ClassAssociation assoc : customAssocsAspect.getAssociations()) - { - if (refQName.toPrefixString(namespaceService).equals(assoc.getName()) && newTitle != null) - { - assoc.setTitle(newTitle); - } - } - writeCustomContentModel(modelRef, deserializedModel); - - if (logger.isInfoEnabled()) - { - logger.info("persistUpdatedAssocTitle: "+refQName+ - "=" + newTitle + " to aspect: " + RMC_CUSTOM_ASSOCS); - } - - return refQName; + return addCustomChildAssocDefinition(label, label); } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#addCustomChildAssocDefinition(java.lang.String, java.lang.String) + * + * note: currently RMC custom assocs only + */ + public QName addCustomChildAssocDefinition(String source, String target) + { + mandatoryString("source", source); + mandatoryString("target", target); + + RelationshipDisplayName displayName = new RelationshipDisplayName(source, target); + RelationshipDefinition relationshipDefinition = getRelationshipService().createRelationshipDefinition(displayName); + + return QName.createQName(RM_CUSTOM_PREFIX, relationshipDefinition.getUniqueName(), getNamespaceService()); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#updateCustomChildAssocDefinition(org.alfresco.service.namespace.QName, java.lang.String, java.lang.String) + * + * note: currently RMC custom assocs only + */ + public QName updateCustomChildAssocDefinition(QName refQName, String newSource, String newTarget) + { + mandatory("refQName", refQName); + mandatoryString("newSource", newSource); + mandatoryString("newTarget", newTarget); + + RelationshipDisplayName displayName = new RelationshipDisplayName(newSource, newTarget); + String localName = refQName.getLocalName(); + RelationshipDefinition relationshipDefinition = getRelationshipService().updateRelationshipDefinition(localName, displayName); + return QName.createQName(RM_CUSTOM_PREFIX, relationshipDefinition.getUniqueName(), getNamespaceService()); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#updateCustomAssocDefinition(org.alfresco.service.namespace.QName, java.lang.String) + * + * note: currently RMC custom assocs only + */ + public QName updateCustomAssocDefinition(QName refQName, String newLabel) + { + mandatory("refQName", refQName); + mandatoryString("newLabel", newLabel); + + return updateCustomChildAssocDefinition(refQName, newLabel, newLabel); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#addCustomConstraintDefinition(org.alfresco.service.namespace.QName, java.lang.String, boolean, java.util.List, org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.MatchLogic) + */ public void addCustomConstraintDefinition(QName constraintName, String title, boolean caseSensitive, List allowedValues, MatchLogic matchLogic) { - ParameterCheck.mandatory("constraintName", constraintName); - ParameterCheck.mandatoryString("title", title); - ParameterCheck.mandatory("allowedValues", allowedValues); + mandatory("constraintName", constraintName); + mandatoryString("title", title); + mandatory("allowedValues", allowedValues); + mandatory("matchLogic", matchLogic); NodeRef modelRef = getCustomModelRef(constraintName.getNamespaceURI()); M2Model deserializedModel = readCustomContentModel(modelRef); - String constraintNameAsPrefixString = constraintName.toPrefixString(namespaceService); + String constraintNameAsPrefixString = constraintName.toPrefixString(getNamespaceService()); M2Constraint customConstraint = deserializedModel.getConstraint(constraintNameAsPrefixString); if (customConstraint != null) @@ -1444,15 +1093,18 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#changeCustomConstraintValues(org.alfresco.service.namespace.QName, java.util.List) + */ public void changeCustomConstraintValues(QName constraintName, List newAllowedValues) { - ParameterCheck.mandatory("constraintName", constraintName); - ParameterCheck.mandatory("newAllowedValues", newAllowedValues); + mandatory("constraintName", constraintName); + mandatory("newAllowedValues", newAllowedValues); NodeRef modelRef = getCustomModelRef(constraintName.getNamespaceURI()); M2Model deserializedModel = readCustomContentModel(modelRef); - String constraintNameAsPrefixString = constraintName.toPrefixString(namespaceService); + String constraintNameAsPrefixString = constraintName.toPrefixString(getNamespaceService()); M2Constraint customConstraint = deserializedModel.getConstraint(constraintNameAsPrefixString); if (customConstraint == null) @@ -1479,15 +1131,18 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#changeCustomConstraintTitle(org.alfresco.service.namespace.QName, java.lang.String) + */ public void changeCustomConstraintTitle(QName constraintName, String title) { - ParameterCheck.mandatory("constraintName", constraintName); - ParameterCheck.mandatoryString("title", title); + mandatory("constraintName", constraintName); + mandatoryString("title", title); NodeRef modelRef = getCustomModelRef(constraintName.getNamespaceURI()); M2Model deserializedModel = readCustomContentModel(modelRef); - String constraintNameAsPrefixString = constraintName.toPrefixString(namespaceService); + String constraintNameAsPrefixString = constraintName.toPrefixString(getNamespaceService()); M2Constraint customConstraint = deserializedModel.getConstraint(constraintNameAsPrefixString); if (customConstraint == null) @@ -1512,9 +1167,14 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#getCustomConstraintDefinitions(org.alfresco.service.namespace.QName) + */ public List getCustomConstraintDefinitions(QName modelQName) { - Collection conDefs = dictionaryService.getConstraints(modelQName, true); + mandatory("modelQName", modelQName); + + Collection conDefs = getDictionaryService().getConstraints(modelQName, true); for (ConstraintDefinition conDef : conDefs) { @@ -1528,14 +1188,17 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin return new ArrayList(conDefs); } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#removeCustomConstraintDefinition(org.alfresco.service.namespace.QName) + */ public void removeCustomConstraintDefinition(QName constraintName) { - ParameterCheck.mandatory("constraintName", constraintName); + mandatory("constraintName", constraintName); NodeRef modelRef = getCustomModelRef(constraintName.getNamespaceURI()); M2Model deserializedModel = readCustomContentModel(modelRef); - String constraintNameAsPrefixString = constraintName.toPrefixString(namespaceService); + String constraintNameAsPrefixString = constraintName.toPrefixString(getNamespaceService()); M2Constraint customConstraint = deserializedModel.getConstraint(constraintNameAsPrefixString); if (customConstraint == null) @@ -1554,96 +1217,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } } - private NodeRef getCustomModelRef(String uri) - { - if ((uri.equals("")) || (uri.equals(RecordsManagementModel.RM_CUSTOM_URI))) - { - // note: short-cut for "rmc" currently assumes that RM custom model does not define additional namespaces - return RM_CUSTOM_MODEL_NODE_REF; - } - else - { - // ALF-5875 - List modelRefs = dictonaryRepositoryBootstrap.getModelRefs(); - - for (NodeRef modelRef : modelRefs) - { - try - { - M2Model model = readCustomContentModel(modelRef); - - for (M2Namespace namespace : model.getNamespaces()) - { - if (namespace.getUri().equals(uri)) - { - return modelRef; - } - } - } - catch (DictionaryException de) - { - logger.warn("readCustomContentModel: skip model ("+modelRef+") whilst searching for uri ("+uri+"): "+de); - } - } - - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CUSTOM_MODEL_NOT_FOUND, uri)); - } - } - - private M2Model readCustomContentModel(NodeRef modelNodeRef) - { - ContentReader reader = this.contentService.getReader(modelNodeRef, - ContentModel.TYPE_CONTENT); - - if (!reader.exists()) {throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CUSTOM_MODEL_NO_CONTENT, modelNodeRef.toString()));} - - InputStream contentIn = null; - M2Model deserializedModel = null; - try - { - contentIn = reader.getContentInputStream(); - deserializedModel = M2Model.createModel(contentIn); - } - finally - { - try - { - if (contentIn != null) - { - contentIn.close(); - } - } - catch (IOException ignored) - { - // Intentionally empty.` - } - } - return deserializedModel; - } - - private void writeCustomContentModel(NodeRef modelRef, M2Model deserializedModel) - { - ContentWriter writer = this.contentService.getWriter(modelRef, ContentModel.TYPE_CONTENT, true); - writer.setMimetype(MimetypeMap.MIMETYPE_XML); - writer.setEncoding("UTF-8"); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - deserializedModel.toXML(baos); - - String updatedModelXml; - try - { - updatedModelXml = baos.toString("UTF-8"); - writer.putContent(updatedModelXml); - // putContent closes all resources. - // so we don't have to. - } catch (UnsupportedEncodingException uex) - { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_ERROR_WRITE_CUSTOM_MODEL, modelRef.toString()), uex); - } - } - - + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#getQNameForClientId(java.lang.String) + */ public QName getQNameForClientId(String localName) { //TODO 1. After certification. This implementation currently does not support reference, @@ -1679,6 +1255,10 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin return referenceResult; } + /** + * @param clientId + * @return + */ private QName generateQNameFor(String clientId) { if (getQNameForClientId(clientId) != null) @@ -1688,34 +1268,29 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } String newGUID = GUID.generate(); - QName newQName = QName.createQName(RM_CUSTOM_PREFIX, newGUID, namespaceService); + QName newQName = QName.createQName(RM_CUSTOM_PREFIX, newGUID, getNamespaceService()); return newQName; } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#splitSourceTargetId(java.lang.String) + */ public String[] splitSourceTargetId(String sourceTargetId) { - if (!sourceTargetId.contains(SOURCE_TARGET_ID_SEPARATOR)) - { - throw new IllegalArgumentException(I18NUtil.getMessage(MSG_ERROR_SPLIT_ID, sourceTargetId, SOURCE_TARGET_ID_SEPARATOR)); - } - return sourceTargetId.split(SOURCE_TARGET_ID_SEPARATOR); + mandatoryString("sourceTargetId", sourceTargetId); + + return splitAssociationDefinitionTitle(sourceTargetId); } + /** + * @see org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService#getCompoundIdFor(java.lang.String, java.lang.String) + */ public String getCompoundIdFor(String sourceId, String targetId) { - ParameterCheck.mandatoryString("sourceId", sourceId); - ParameterCheck.mandatoryString("targetId", targetId); + mandatoryString("sourceId", sourceId); + mandatoryString("targetId", targetId); - if (sourceId.contains(SOURCE_TARGET_ID_SEPARATOR)) - { - throw new IllegalArgumentException("sourceId cannot contain '" + SOURCE_TARGET_ID_SEPARATOR - + "': " + sourceId); - } - StringBuilder result = new StringBuilder(); - result.append(sourceId) - .append(SOURCE_TARGET_ID_SEPARATOR) - .append(targetId); - return result.toString(); + return composeAssociationDefinitionTitle(sourceId, targetId); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/OnReferencedRecordActionedUpon.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/OnReferencedRecordActionedUpon.java index 5d3e04ece1..9b6d581f4e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/OnReferencedRecordActionedUpon.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/event/OnReferencedRecordActionedUpon.java @@ -26,7 +26,6 @@ import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService; import org.alfresco.module.org_alfresco_module_rm.action.impl.CompleteEventAction; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; @@ -60,9 +59,6 @@ public class OnReferencedRecordActionedUpon extends SimpleRecordsManagementEvent /** Records management action service */ private RecordsManagementActionService recordsManagementActionService; - /** Records management admin service */ - private RecordsManagementAdminService recordsManagementAdminService; - /** Node service */ private NodeService nodeService; @@ -94,14 +90,6 @@ public class OnReferencedRecordActionedUpon extends SimpleRecordsManagementEvent this.recordsManagementActionService = recordsManagementActionService; } - /** - * @param recordsManagementAdminService record management admin service - */ - public void setRecordsManagementAdminService(RecordsManagementAdminService recordsManagementAdminService) - { - this.recordsManagementAdminService = recordsManagementAdminService; - } - /** * @param nodeService node service */ @@ -212,7 +200,7 @@ public class OnReferencedRecordActionedUpon extends SimpleRecordsManagementEvent private void processRecord(NodeRef record) { - List fromAssocs = recordsManagementAdminService.getCustomReferencesFrom(record); + List fromAssocs = nodeService.getTargetAssocs(record, RegexQNamePattern.MATCH_ALL); for (AssociationRef fromAssoc : fromAssocs) { if (reference.equals(fromAssoc.getTypeQName())) @@ -222,7 +210,7 @@ public class OnReferencedRecordActionedUpon extends SimpleRecordsManagementEvent } } - List toAssocs = recordsManagementAdminService.getCustomReferencesTo(record); + List toAssocs = nodeService.getSourceAssocs(record, RegexQNamePattern.MATCH_ALL); for (AssociationRef toAssoc : toAssocs) { if (reference.equals(toAssoc.getTypeQName())) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipDisplayName.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipDisplayName.java index 8d090469c0..2ed160e07a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipDisplayName.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipDisplayName.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.relationship; +import static org.alfresco.util.ParameterCheck.mandatoryString; + /** * POJO representing the relationship display name * @@ -26,55 +28,33 @@ package org.alfresco.module.org_alfresco_module_rm.relationship; */ public class RelationshipDisplayName { - /** The label text for {@link RelationshipType#BIDIRECTIONAL} */ - private String labelText; - - /** The source text for {@link RelationshipType#PARENTCHILD} */ + /** The source text of the relationship */ private String sourceText; - /** The target text for {@link RelationshipType#PARENTCHILD} */ + /** The target text of the relationship */ private String targetText; /** - * Constructor for creating the relationship display name + * Constructor for creating the relationship display name. + * In case of a bidirectional relationship the source + * text and target text will be the same. * - * @param sourceText The source text of the relationship definition - * @param targetText The target text of the relationship definition - * @param labelText The label text of the relationship definition + * @param sourceText The source text of the relationship + * @param targetText The target text of the relationship */ - public RelationshipDisplayName(String sourceText, String targetText, String labelText) + public RelationshipDisplayName(String sourceText, String targetText) { - // Parameters might be blank. No check required. + mandatoryString("sourceText", sourceText); + mandatoryString("targetText", targetText); setSourceText(sourceText); setTargetText(targetText); - setLabelText(labelText); } /** - * Gets the label text of {@link RelationshipType#BIDIRECTIONAL} + * Gets the source text of the relationship * - * @return The label text of {@link RelationshipType#BIDIRECTIONAL} - */ - public String getLabelText() - { - return this.labelText; - } - - /** - * Sets the label text of {@link RelationshipType#BIDIRECTIONAL} - * - * @param labelText The label text of {@link RelationshipType#BIDIRECTIONAL} - */ - private void setLabelText(String labelText) - { - this.labelText = labelText; - } - - /** - * Gets the source text of {@link RelationshipType#PARENTCHILD} - * - * @return The source text of {@link RelationshipType#PARENTCHILD} + * @return The source text of the relationship */ public String getSourceText() { @@ -82,9 +62,9 @@ public class RelationshipDisplayName } /** - * Sets the source text of {@link RelationshipType#PARENTCHILD} + * Sets the source text of the relationship * - * @param sourceText The source text of {@link RelationshipType#PARENTCHILD} + * @param sourceText The source text of the relationship */ private void setSourceText(String sourceText) { @@ -92,9 +72,9 @@ public class RelationshipDisplayName } /** - * Gets the target text of {@link RelationshipType#PARENTCHILD} + * Gets the target text of the relationship * - * @return The target text of {@link RelationshipType#PARENTCHILD} + * @return The target text of the relationship */ public String getTargetText() { @@ -102,12 +82,26 @@ public class RelationshipDisplayName } /** - * Sets the target text of {@link RelationshipType#PARENTCHILD} + * Sets the target text of the relationship * - * @param targetText The target text of {@link RelationshipType#PARENTCHILD} + * @param targetText The target text of the relationship */ private void setTargetText(String targetText) { this.targetText = targetText; } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("(") + .append("source=").append(sourceText) + .append(", target=").append(targetText) + .append(")"); + return sb.toString(); + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipService.java index ecf674156f..0a619f53d1 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipService.java @@ -60,7 +60,7 @@ public interface RelationshipService * @param displayName The display name of the relationship definition * @return The updated relationship definition */ - RelationshipDefinition updateReleationshipDefinition(String uniqueName, RelationshipDisplayName displayName); + RelationshipDefinition updateRelationshipDefinition(String uniqueName, RelationshipDisplayName displayName); /** * Removes a relationship definition diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java index fbdb0dc2e2..ba7b3964a2 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java @@ -21,23 +21,36 @@ package org.alfresco.module.org_alfresco_module_rm.relationship; import static org.alfresco.util.ParameterCheck.mandatory; import static org.alfresco.util.ParameterCheck.mandatoryString; import static org.apache.commons.lang.StringUtils.isBlank; -import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; +import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.BeforeCreateReference; +import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.BeforeRemoveReference; +import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnCreateReference; +import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnRemoveReference; +import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminBase; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.util.PoliciesUtil; +import org.alfresco.repo.dictionary.M2Aspect; +import org.alfresco.repo.dictionary.M2ClassAssociation; +import org.alfresco.repo.dictionary.M2Model; +import org.alfresco.repo.policy.ClassPolicyDelegate; +import org.alfresco.repo.policy.PolicyComponent; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.NamespacePrefixResolver; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.util.GUID; /** * The relationship service implementation @@ -45,75 +58,47 @@ import org.alfresco.service.namespace.QName; * @author Tuna Aksoy * @since 2.3 */ -public class RelationshipServiceImpl implements RelationshipService +public class RelationshipServiceImpl extends RecordsManagementAdminBase implements RelationshipService { - /** Records management admin service */ - private RecordsManagementAdminService recordsManagementAdminService; - - /** Dictionary service */ - private DictionaryService dictionaryService; - - /** Namespace prefix resolver */ - private NamespacePrefixResolver namespacePrefixResolver; + /** Policy component */ + private PolicyComponent policyComponent; /** - * Gets the records management admin service instance + * Gets the policy component instance * - * @return The records management admin service instance + * @return The policy component instance */ - protected RecordsManagementAdminService getRecordsManagementAdminService() + private PolicyComponent getPolicyComponent() { - return this.recordsManagementAdminService; + return this.policyComponent; } /** - * Sets the records management admin service instance + * Sets the policy component instance * - * @param recordsManagementAdminService The records management admin service instance + * @param policyComponent The policy component instance */ - public void setRecordsManagementAdminService(RecordsManagementAdminService recordsManagementAdminService) + public void setPolicyComponent(PolicyComponent policyComponent) { - this.recordsManagementAdminService = recordsManagementAdminService; + this.policyComponent = policyComponent; } - /** - * Gets the dictionary service instance - * - * @return The dictionary service instance - */ - protected DictionaryService getDictionaryService() - { - return this.dictionaryService; - } + /** Policy delegates */ + private ClassPolicyDelegate beforeCreateReferenceDelegate; + private ClassPolicyDelegate onCreateReferenceDelegate; + private ClassPolicyDelegate beforeRemoveReferenceDelegate; + private ClassPolicyDelegate onRemoveReferenceDelegate; /** - * Sets the dictionary service instance - * - * @param dictionaryService The dictionary service instance + * Initialisation method */ - public void setDictionaryService(DictionaryService dictionaryService) + public void init() { - this.dictionaryService = dictionaryService; - } - - /** - * Gets the namespace prefix resolver instance - * - * @return The namespace prefix resolver instance - */ - protected NamespacePrefixResolver getNamespacePrefixResolver() - { - return this.namespacePrefixResolver; - } - - /** - * Sets the namespace prefix resolver instance - * - * @param namespacePrefixResolver The namespace prefix resolver instance - */ - public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver) - { - this.namespacePrefixResolver = namespacePrefixResolver; + // Register the various policies + beforeCreateReferenceDelegate = getPolicyComponent().registerClassPolicy(BeforeCreateReference.class); + onCreateReferenceDelegate = getPolicyComponent().registerClassPolicy(OnCreateReference.class); + beforeRemoveReferenceDelegate = getPolicyComponent().registerClassPolicy(BeforeRemoveReference.class); + onRemoveReferenceDelegate = getPolicyComponent().registerClassPolicy(OnRemoveReference.class); } /** @@ -124,10 +109,10 @@ public class RelationshipServiceImpl implements RelationshipService { Set relationshipDefinitions = new HashSet(); - Map customReferenceDefinitions = getRecordsManagementAdminService().getCustomReferenceDefinitions(); - for (Map.Entry customReferenceDefinitionEntry : customReferenceDefinitions.entrySet()) + Set> associationsEntrySet = getCustomAssociations().entrySet(); + for (Map.Entry associationEntry : associationsEntrySet) { - AssociationDefinition associationDefinition = customReferenceDefinitionEntry.getValue(); + AssociationDefinition associationDefinition = associationEntry.getValue(); RelationshipDefinition relationshipDefinition = createRelationshipDefinition(associationDefinition); if (relationshipDefinition != null) { @@ -148,10 +133,9 @@ public class RelationshipServiceImpl implements RelationshipService RelationshipDefinition relationshipDefinition = null; - QName associationDefinitionQName = getRecordsManagementAdminService().getQNameForClientId(uniqueName); - if (associationDefinitionQName != null) + AssociationDefinition associationDefinition = getAssociationDefinition(uniqueName); + if (associationDefinition != null) { - AssociationDefinition associationDefinition = getRecordsManagementAdminService().getCustomReferenceDefinitions().get(associationDefinitionQName); relationshipDefinition = createRelationshipDefinition(associationDefinition); } @@ -166,23 +150,21 @@ public class RelationshipServiceImpl implements RelationshipService { mandatory("displayName", displayName); + String title; RelationshipType type = determineRelationshipTypeFromDisplayName(displayName); - QName relationshipDefinitionQName; - switch (type) { case BIDIRECTIONAL: - String labelText = displayName.getLabelText(); - relationshipDefinitionQName = getRecordsManagementAdminService().addCustomAssocDefinition(labelText); + title = displayName.getSourceText(); break; case PARENTCHILD: String sourceText = displayName.getSourceText(); String targetText = displayName.getTargetText(); - relationshipDefinitionQName = getRecordsManagementAdminService().addCustomChildAssocDefinition(sourceText, targetText); + title = composeAssociationDefinitionTitle(sourceText, targetText); break; default: @@ -194,50 +176,117 @@ public class RelationshipServiceImpl implements RelationshipService throw new AlfrescoRuntimeException(sb.toString()); } - String uniqueName = relationshipDefinitionQName.getLocalName(); + // If this title is already taken... + if (existsTitle(title)) + { + StringBuilder sb = new StringBuilder(); + sb.append("Cannot create a relationship definition for the display name: '") + .append(displayName.toString()) + .append("' as there is already a relationship definition with this display name."); + throw new AlfrescoRuntimeException(sb.toString()); + } - return new RelationshipDefinitionImpl(uniqueName, type, displayName); + // Defaults to RM_CUSTOM_URI + NodeRef modelRef = getCustomModelRef(""); + M2Model deserializedModel = readCustomContentModel(modelRef); + String customAspectName = ASPECT_CUSTOM_ASSOCIATIONS.toPrefixString(getNamespaceService()); + M2Aspect customAssocsAspect = deserializedModel.getAspect(customAspectName); + + if (customAssocsAspect == null) + { + StringBuilder sb = new StringBuilder(); + sb.append("The aspect: '") + .append(customAspectName) + .append("' is undefined."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + QName relationshipDefinitionQName = generateRelationshipDefinitionQNameFor(title); + String generatedShortQName = relationshipDefinitionQName.toPrefixString(getNamespaceService()); + + M2ClassAssociation customAssoc = customAssocsAspect.getAssociation(generatedShortQName); + if (customAssoc != null) + { + StringBuilder sb = new StringBuilder(); + sb.append("The association: '") + .append(customAssoc.getName()) + .append("' already exists."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + M2ClassAssociation newAssoc; + + switch (type) + { + case BIDIRECTIONAL: + + newAssoc = customAssocsAspect.createAssociation(generatedShortQName); + break; + + case PARENTCHILD: + + newAssoc = customAssocsAspect.createChildAssociation(generatedShortQName); + break; + + default: + + StringBuilder sb = new StringBuilder(); + sb.append("Unsupported relationship type: '") + .append(type.toString()) + .append("'."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + newAssoc.setSourceMandatory(false); + newAssoc.setTargetMandatory(false); + + // MOB-1573 + newAssoc.setSourceMany(true); + newAssoc.setTargetMany(true); + + newAssoc.setTitle(title); + newAssoc.setTargetClassName(RecordsManagementModel.ASPECT_RECORD.toPrefixString(getNamespaceService())); + writeCustomContentModel(modelRef, deserializedModel); + + return new RelationshipDefinitionImpl(relationshipDefinitionQName.getLocalName(), type, displayName); } /** * @see org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService#updateReleationshipDefinition(java.lang.String) */ @Override - public RelationshipDefinition updateReleationshipDefinition(String uniqueName, RelationshipDisplayName displayName) + public RelationshipDefinition updateRelationshipDefinition(String uniqueName, RelationshipDisplayName displayName) { mandatoryString("uniqueName", uniqueName); - QName associationDefinitionQName = getRecordsManagementAdminService().getQNameForClientId(uniqueName); - if (associationDefinitionQName == null) + RelationshipDefinition relationshipDefinition = getRelationshipDefinition(uniqueName); + if (relationshipDefinition == null) { StringBuilder sb = new StringBuilder(); - sb.append("The qualified name for '") + sb.append("The relationship definition for the unique name '") .append(uniqueName) .append("' was not found."); throw new AlfrescoRuntimeException(sb.toString()); } - Map customReferenceDefinitions = getRecordsManagementAdminService().getCustomReferenceDefinitions(); - AssociationDefinition associationDefinition = customReferenceDefinitions.get(associationDefinitionQName); - RelationshipType type = getRelationshipType(associationDefinition); - QName updatedAssociationDefinitionQName; + String title; + RelationshipType type = relationshipDefinition.getType(); switch (type) { case BIDIRECTIONAL: - String labelText = displayName.getLabelText(); + title = displayName.getSourceText(); - if (isBlank(labelText)) + if (isBlank(title)) { StringBuilder sb = new StringBuilder(); sb.append("Label text '") - .append(labelText) + .append(title) .append(" cannot be blank."); throw new AlfrescoRuntimeException(sb.toString()); } - updatedAssociationDefinitionQName = getRecordsManagementAdminService().updateCustomAssocDefinition(associationDefinitionQName, labelText); break; case PARENTCHILD: @@ -256,7 +305,8 @@ public class RelationshipServiceImpl implements RelationshipService throw new AlfrescoRuntimeException(sb.toString()); } - updatedAssociationDefinitionQName = getRecordsManagementAdminService().updateCustomChildAssocDefinition(associationDefinitionQName, sourceText, targetText); + title = composeAssociationDefinitionTitle(sourceText, targetText); + break; default: @@ -268,12 +318,22 @@ public class RelationshipServiceImpl implements RelationshipService throw new AlfrescoRuntimeException(sb.toString()); } - customReferenceDefinitions = getRecordsManagementAdminService().getCustomReferenceDefinitions(); - AssociationDefinition updatedAssociationDefinition = customReferenceDefinitions.get(updatedAssociationDefinitionQName); - RelationshipDefinition updatedRelationshipDefinition = createRelationshipDefinition(updatedAssociationDefinition); + if (existsTitle(title)) + { + StringBuilder sb = new StringBuilder(); + sb.append("Cannot update the relationship definition as '") + .append(title) + .append("' already exists."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + QName associationDefinitionQName = getAssociationDefinitionName(uniqueName); + QName updatedAssociationDefinitionQName = persistUpdatedAssocTitle(associationDefinitionQName, title); + RelationshipDefinition updatedRelationshipDefinition = getRelationshipDefinition(updatedAssociationDefinitionQName.getLocalName()); + if (updatedRelationshipDefinition == null) { - throw new AlfrescoRuntimeException("The relationship definition was not updated successfully."); + throw new AlfrescoRuntimeException("The relationship definition could not be updated successfully."); } return updatedRelationshipDefinition; @@ -287,8 +347,7 @@ public class RelationshipServiceImpl implements RelationshipService { mandatoryString("uniqueName", uniqueName); - // FIXME!!! There is no method on the backend for this. Must be implemented. - throw new UnsupportedOperationException("Not implemented yet."); + throw new UnsupportedOperationException("It is not possible to remove a relationship."); } /** @@ -301,11 +360,10 @@ public class RelationshipServiceImpl implements RelationshipService boolean exists = false; - QName associationDefinitionQName = getRecordsManagementAdminService().getQNameForClientId(uniqueName); - if (associationDefinitionQName != null) + RelationshipDefinition relationshipDefinition = getRelationshipDefinition(uniqueName); + if (relationshipDefinition != null) { - Map customReferenceDefinitions = getRecordsManagementAdminService().getCustomReferenceDefinitions(); - exists = customReferenceDefinitions.containsKey(associationDefinitionQName); + exists = true; } return exists; @@ -321,10 +379,10 @@ public class RelationshipServiceImpl implements RelationshipService Set relationships = new HashSet(); - List customReferencesFrom = getRecordsManagementAdminService().getCustomReferencesFrom(nodeRef); + List customReferencesFrom = getNodeService().getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL); relationships.addAll(generateRelationshipFromAssociationRef(customReferencesFrom)); - List customChildReferences = getRecordsManagementAdminService().getCustomChildReferences(nodeRef); + List customChildReferences = getNodeService().getChildAssocs(nodeRef); relationships.addAll(generateRelationshipFromParentChildAssociationRef(customChildReferences)); return relationships; @@ -340,10 +398,10 @@ public class RelationshipServiceImpl implements RelationshipService Set relationships = new HashSet(); - List customReferencesTo = getRecordsManagementAdminService().getCustomReferencesTo(nodeRef); + List customReferencesTo = getNodeService().getSourceAssocs(nodeRef, RegexQNamePattern.MATCH_ALL); relationships.addAll(generateRelationshipFromAssociationRef(customReferencesTo)); - List customParentReferences = getRecordsManagementAdminService().getCustomParentReferences(nodeRef); + List customParentReferences = getNodeService().getParentAssocs(nodeRef); relationships.addAll(generateRelationshipFromParentChildAssociationRef(customParentReferences)); return relationships; @@ -359,8 +417,50 @@ public class RelationshipServiceImpl implements RelationshipService mandatory("source", source); mandatory("target", target); - QName associationDefinitionQName = getRecordsManagementAdminService().getQNameForClientId(uniqueName); - getRecordsManagementAdminService().addCustomReference(source, target, associationDefinitionQName); + // Check that the association definition for the given unique name exists. + AssociationDefinition associationDefinition = getAssociationDefinition(uniqueName); + if (associationDefinition == null) + { + StringBuilder sb = new StringBuilder(); + sb.append("No association definition found for '"). + append(uniqueName). + append("'."); + throw new IllegalArgumentException(sb.toString()); + } + + // Get the association definition name + QName associationDefinitionName = associationDefinition.getName(); + + // Check if an instance of this association already exists in the same direction + boolean associationAlreadyExists = associationExists(associationDefinition, source, target); + + if (associationAlreadyExists) + { + StringBuilder sb = new StringBuilder(); + sb.append("Association '"). + append(associationDefinitionName.getLocalName()). + append("' already exists from '"). + append(source). + append("' to '"). + append(target). + append("'."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + // Invoke before create reference policy + invokeBeforeCreateReference(source, target, associationDefinitionName); + + if (associationDefinition.isChild()) + { + getNodeService().addChild(source, target, associationDefinitionName, associationDefinitionName); + } + else + { + getNodeService().createAssociation(source, target, associationDefinitionName); + } + + // Invoke on create reference policy + invokeOnCreateReference(source, target, associationDefinitionName); } /** @@ -373,8 +473,49 @@ public class RelationshipServiceImpl implements RelationshipService mandatory("source", source); mandatory("target", target); - QName associationDefinitionQName = getRecordsManagementAdminService().getQNameForClientId(uniqueName); - getRecordsManagementAdminService().removeCustomReference(source, target, associationDefinitionQName); + // Check that the association definition for the given unique name exists. + AssociationDefinition associationDefinition = getAssociationDefinition(uniqueName); + if (associationDefinition == null) + { + StringBuilder sb = new StringBuilder(); + sb.append("No association definition found for '"). + append(uniqueName). + append("'."); + throw new IllegalArgumentException(sb.toString()); + } + + // Get the association definition name + final QName associationDefinitionName = associationDefinition.getName(); + final NodeRef targetNode = target; + + invokeBeforeRemoveReference(source, targetNode, associationDefinitionName); + + if (associationDefinition.isChild()) + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() + { + List children = getNodeService().getChildAssocs(targetNode); + for (ChildAssociationRef chRef : children) + { + if (associationDefinitionName.equals(chRef.getTypeQName()) && chRef.getChildRef().equals(targetNode)) + { + getNodeService().removeChildAssociation(chRef); + } + } + + return null; + } + }); + } + else + { + getNodeService().removeAssociation(source, targetNode, associationDefinitionName); + } + + invokeOnRemoveReference(source, targetNode, associationDefinitionName); } /** @@ -443,18 +584,18 @@ public class RelationshipServiceImpl implements RelationshipService { String sourceText = null; String targetText = null; - String labelText = null; switch (type) { case BIDIRECTIONAL: - labelText = title; + sourceText = title; + targetText = title; break; case PARENTCHILD: - String[] sourceAndTarget = getRecordsManagementAdminService().splitSourceTargetId(title); + String[] sourceAndTarget = splitAssociationDefinitionTitle(title); sourceText = sourceAndTarget[0]; targetText = sourceAndTarget[1]; break; @@ -468,7 +609,7 @@ public class RelationshipServiceImpl implements RelationshipService throw new AlfrescoRuntimeException(sb.toString()); } - return new RelationshipDisplayName(sourceText, targetText, labelText); + return new RelationshipDisplayName(sourceText, targetText); } /** @@ -523,29 +664,255 @@ public class RelationshipServiceImpl implements RelationshipService { RelationshipType relationshipType; - String labelText = displayName.getLabelText(); String sourceText = displayName.getSourceText(); String targetText = displayName.getTargetText(); String errorMsg = "Relationship type could not be determined from the display name. It is neither biderectional nor parent/child relationship"; - if (isBlank(labelText)) + if (isBlank(sourceText) || isBlank(targetText)) { - if (isBlank(sourceText) || isBlank(targetText)) - { - throw new AlfrescoRuntimeException(errorMsg); - } - relationshipType = RelationshipType.PARENTCHILD; + throw new AlfrescoRuntimeException(errorMsg); + } + + if (sourceText.equals(targetText)) + { + relationshipType = RelationshipType.BIDIRECTIONAL; } else { - if (isNotBlank(sourceText) || isNotBlank(targetText)) - { - throw new AlfrescoRuntimeException(errorMsg); - } - relationshipType = RelationshipType.BIDIRECTIONAL; + relationshipType = RelationshipType.PARENTCHILD; } return relationshipType; } + + /** + * Invoke before create reference policy + * + * @param source The source node reference + * @param target The target node reference + * @param associationDefinitionName The association definition name + */ + private void invokeBeforeCreateReference(NodeRef source, NodeRef target, QName associationDefinitionName) + { + // Get QNames to invoke against + Set qnames = PoliciesUtil.getTypeAndAspectQNames(getNodeService(), source); + // Execute policy for node type and aspects + BeforeCreateReference policy = beforeCreateReferenceDelegate.get(qnames); + policy.beforeCreateReference(source, target, associationDefinitionName); + } + + /** + * Invoke on create reference policy + * + * @param source The source node reference + * @param target The target node reference + * @param associationDefinitionName The association definition name + */ + private void invokeOnCreateReference(NodeRef source, NodeRef target, QName associationDefinitionName) + { + // Get QNames to invoke against + Set qnames = PoliciesUtil.getTypeAndAspectQNames(getNodeService(), source); + // Execute policy for node type and aspects + OnCreateReference policy = onCreateReferenceDelegate.get(qnames); + policy.onCreateReference(source, target, associationDefinitionName); + } + + /** + * Invoke before remove reference policy + * + * @param source The source node reference + * @param target The target node reference + * @param associationDefinitionName The association definition name + */ + private void invokeBeforeRemoveReference(NodeRef source, NodeRef target, QName associationDefinitionName) + { + // Get QNames to invoke against + Set qnames = PoliciesUtil.getTypeAndAspectQNames(getNodeService(), source); + // Execute policy for node type and aspects + BeforeRemoveReference policy = beforeRemoveReferenceDelegate.get(qnames); + policy.beforeRemoveReference(source, target, associationDefinitionName); + } + + /** + * Invoke on remove reference policy + * + * @param source The source node reference + * @param target The target node reference + * @param associationDefinitionName The association definition name + */ + private void invokeOnRemoveReference(NodeRef source, NodeRef target, QName associationDefinitionName) + { + // Get QNames to invoke against + Set qnames = PoliciesUtil.getTypeAndAspectQNames(getNodeService(), source); + // Execute policy for node type and aspects + OnRemoveReference policy = onRemoveReferenceDelegate.get(qnames); + policy.onRemoveReference(source, target, associationDefinitionName); + } + + /** + * Check if an instance of the association already exists from the given + * source node reference to the given target node reference + * + * @param associationDefinition The association definition + * @param source The source node reference + * @param target The target node reference + * @return true if an association already exists, false otherwise + */ + private boolean associationExists(AssociationDefinition associationDefinition, NodeRef source, NodeRef target) + { + boolean associationAlreadyExists = false; + + QName associationDefinitionName = associationDefinition.getName(); + if (associationDefinition.isChild()) + { + List childAssocs = getNodeService().getChildAssocs(source, associationDefinitionName, associationDefinitionName); + for (ChildAssociationRef chAssRef : childAssocs) + { + if (chAssRef.getChildRef().equals(target)) + { + associationAlreadyExists = true; + } + } + } + else + { + List assocs = getNodeService().getTargetAssocs(source, associationDefinitionName); + for (AssociationRef assRef : assocs) + { + if (assRef.getTargetRef().equals(target)) + { + associationAlreadyExists = true; + } + } + } + + return associationAlreadyExists; + } + + /** + * Gets the association definition for the given unique name + * + * @param uniqueName The unique name + * @return The association definition for the given unique name if exists, null otherwise + */ + private AssociationDefinition getAssociationDefinition(String uniqueName) + { + AssociationDefinition associationDefinition = null; + + Set> associationsEntrySet = getCustomAssociations().entrySet(); + for (Map.Entry associationEntry : associationsEntrySet) + { + String localName = associationEntry.getKey().getLocalName(); + if (uniqueName.equals(localName)) + { + associationDefinition = associationEntry.getValue(); + break; + } + } + + return associationDefinition; + } + + /** + * Gets the qualified name of the association definition for the given unique name + * + * @param uniqueName The unique name + * @return The qualified name of the association definition for the given unique name + */ + private QName getAssociationDefinitionName(String uniqueName) + { + AssociationDefinition associationDefinition = getAssociationDefinition(uniqueName); + + if (associationDefinition == null) + { + StringBuilder sb = new StringBuilder(); + sb.append("The qualified name for '") + .append(uniqueName) + .append("' was not found."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + return associationDefinition.getName(); + } + + /** + * This method writes the specified String into the association's title property. + * For RM custom properties and references, Title is used to store the identifier. + * + * NOTE: Currently RMC custom associations only + * @param associationDefinitionQName Qualified name for the association definition + * @param newTitle The new title + * @return Qualified name for the association definition + */ + private QName persistUpdatedAssocTitle(QName associationDefinitionQName, String newTitle) + { + mandatory("associationDefinitionQName", associationDefinitionQName); + + AssociationDefinition assocDefn = getDictionaryService().getAssociation(associationDefinitionQName); + if (assocDefn == null) + { + StringBuilder sb = new StringBuilder(); + sb.append("Cannot find the association definiton for '"). + append(associationDefinitionQName.getLocalName()). + append("'."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + // defaults to RM_CUSTOM_URI + NodeRef modelRef = getCustomModelRef(""); + M2Model deserializedModel = readCustomContentModel(modelRef); + + String customAspectName = ASPECT_CUSTOM_ASSOCIATIONS.toPrefixString(getNamespaceService()); + M2Aspect customAssocsAspect = deserializedModel.getAspect(customAspectName); + + for (M2ClassAssociation assoc : customAssocsAspect.getAssociations()) + { + if (associationDefinitionQName.toPrefixString(getNamespaceService()).equals(assoc.getName()) && newTitle != null) + { + assoc.setTitle(newTitle); + } + } + writeCustomContentModel(modelRef, deserializedModel); + + if (logger.isInfoEnabled()) + { + logger.info("persistUpdatedAssocTitle: " + associationDefinitionQName + "=" + newTitle + " to aspect: " + customAspectName); + } + + return associationDefinitionQName; + } + + /** + * Generates a qualified name for the given relationship definition unique name + * + * @param uniqueName The unique name of the relationship definition + * @return The qualified name of relationship definition + */ + private QName generateRelationshipDefinitionQNameFor(String uniqueName) + { + mandatoryString("uniqueName", uniqueName); + + QName existingQName = null; + + Set customAssociationsQNames = getCustomAssociations().keySet(); + for (QName customAssociationsQName : customAssociationsQNames) + { + if (uniqueName.equals(customAssociationsQName.getLocalName())) + { + existingQName = customAssociationsQName; + } + } + + if (existingQName != null) + { + StringBuilder sb = new StringBuilder(); + sb.append("Cannot create qualified name for given unique name '"). + append(uniqueName). + append("' as it already exists."); + throw new AlfrescoRuntimeException(sb.toString()); + } + + return QName.createQName(RM_CUSTOM_PREFIX, GUID.generate(), getNamespaceService()); + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyDodCertModelFixesGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyDodCertModelFixesGet.java index 1a518d72c3..754248276a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyDodCertModelFixesGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyDodCertModelFixesGet.java @@ -29,7 +29,6 @@ import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.content.MimetypeMap; @@ -42,6 +41,7 @@ import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.extensions.webscripts.Cache; @@ -75,12 +75,18 @@ public class ApplyDodCertModelFixesGet extends DeclarativeWebScript private static Log logger = LogFactory.getLog(ApplyDodCertModelFixesGet.class); private ContentService contentService; + private NamespaceService namespaceService; public void setContentService(ContentService contentService) { this.contentService = contentService; } + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + @Override public Map executeImpl(WebScriptRequest req, Status status, Cache cache) { @@ -91,11 +97,12 @@ public class ApplyDodCertModelFixesGet extends DeclarativeWebScript M2Model customModel = readCustomContentModel(); - M2Aspect customAssocsAspect = customModel.getAspect(RecordsManagementAdminServiceImpl.RMC_CUSTOM_ASSOCS); + String customAspectName = ASPECT_CUSTOM_ASSOCIATIONS.toPrefixString(namespaceService); + M2Aspect customAssocsAspect = customModel.getAspect(customAspectName); if (customAssocsAspect == null) { - final String msg = "Unknown aspect: " + RecordsManagementAdminServiceImpl.RMC_CUSTOM_ASSOCS; + final String msg = "Unknown aspect: " + customAspectName; if (logger.isErrorEnabled()) { logger.error(msg); @@ -117,8 +124,6 @@ public class ApplyDodCertModelFixesGet extends DeclarativeWebScript } - - //MOB-1621. Custom fields should be created as untokenized by default. if (logger.isInfoEnabled()) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyFixMob1573Get.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyFixMob1573Get.java index a0378ed758..df46460489 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyFixMob1573Get.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/ApplyFixMob1573Get.java @@ -27,7 +27,6 @@ import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.dictionary.M2Aspect; @@ -37,6 +36,7 @@ import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.DeclarativeWebScript; import org.springframework.extensions.webscripts.Status; @@ -58,12 +58,18 @@ public class ApplyFixMob1573Get extends DeclarativeWebScript private static final NodeRef RM_CUSTOM_MODEL_NODE_REF = new NodeRef("workspace://SpacesStore/records_management_custom_model"); private ContentService contentService; + private NamespaceService namespaceService; public void setContentService(ContentService contentService) { this.contentService = contentService; } + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + @Override public Map executeImpl(WebScriptRequest req, Status status, Cache cache) { @@ -71,7 +77,7 @@ public class ApplyFixMob1573Get extends DeclarativeWebScript // Go through every custom reference defined in the custom model and make sure that it // has many-to-many multiplicity - String aspectName = RecordsManagementAdminServiceImpl.RMC_CUSTOM_ASSOCS; + String aspectName = ASPECT_CUSTOM_ASSOCIATIONS.toPrefixString(namespaceService); M2Aspect customAssocsAspect = customModel.getAspect(aspectName); if (customAssocsAspect == null) @@ -95,7 +101,7 @@ public class ApplyFixMob1573Get extends DeclarativeWebScript private M2Model readCustomContentModel() { - ContentReader reader = this.contentService.getReader(RM_CUSTOM_MODEL_NODE_REF, + ContentReader reader = contentService.getReader(RM_CUSTOM_MODEL_NODE_REF, ContentModel.TYPE_CONTENT); if (!reader.exists()) {throw new AlfrescoRuntimeException("RM CustomModel has no content.");} @@ -118,7 +124,7 @@ public class ApplyFixMob1573Get extends DeclarativeWebScript } catch (IOException ignored) { - // Intentionally empty.` + // Intentionally empty. } } return deserializedModel; @@ -126,7 +132,7 @@ public class ApplyFixMob1573Get extends DeclarativeWebScript private void writeCustomContentModel(M2Model deserializedModel) { - ContentWriter writer = this.contentService.getWriter(RM_CUSTOM_MODEL_NODE_REF, + ContentWriter writer = contentService.getWriter(RM_CUSTOM_MODEL_NODE_REF, ContentModel.TYPE_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_XML); writer.setEncoding("UTF-8"); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionBase.java index 5db73136ee..e7e6d8c004 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionBase.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionBase.java @@ -19,6 +19,7 @@ package org.alfresco.module.org_alfresco_module_rm.script; import static org.alfresco.util.WebScriptUtils.getStringValueFromJSONObject; +import static org.apache.commons.lang.StringUtils.isBlank; import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName; import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; @@ -72,9 +73,22 @@ public class CustomReferenceDefinitionBase extends AbstractRmWebScript */ protected RelationshipDisplayName createDisplayName(JSONObject requestContent) { - String sourceText = getStringValueFromJSONObject(requestContent, SOURCE, false, false); - String targetText = getStringValueFromJSONObject(requestContent, TARGET, false, false); + String sourceText; + String targetText; + String labelText = getStringValueFromJSONObject(requestContent, LABEL, false, false); - return new RelationshipDisplayName(sourceText, targetText, labelText); + + if (isBlank(labelText)) + { + sourceText = getStringValueFromJSONObject(requestContent, SOURCE); + targetText = getStringValueFromJSONObject(requestContent, TARGET); + } + else + { + sourceText = labelText; + targetText = labelText; + } + + return new RelationshipDisplayName(sourceText, targetText); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java index 9c0f49b974..8483ef3b4f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java @@ -51,7 +51,7 @@ public class CustomReferenceDefinitionPut extends CustomReferenceDefinitionBase String uniqueName = getRequestParameterValue(req, REF_ID); JSONObject requestContent = getRequestContentAsJsonObject(req); RelationshipDisplayName displayName = createDisplayName(requestContent); - getRelationshipService().updateReleationshipDefinition(uniqueName, displayName); + getRelationshipService().updateRelationshipDefinition(uniqueName, displayName); Map model = new HashMap(); String servicePath = req.getServicePath(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java index 3c922c7532..e389dadb25 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java @@ -108,7 +108,7 @@ public class CustomReferenceDefinitionsGet extends CustomReferenceDefinitionBase if (RelationshipType.BIDIRECTIONAL.equals(type)) { - data.put(LABEL, displayName.getLabelText()); + data.put(LABEL, displayName.getSourceText()); } else if (RelationshipType.PARENTCHILD.equals(type)) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceType.java index a77676fb06..7618457f0f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceType.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceType.java @@ -18,10 +18,13 @@ */ package org.alfresco.module.org_alfresco_module_rm.script; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipType; + /** * This enum represents the allowed types of custom references. - * + * * @author Neil McErlean + * @deprecated as of RM 2.3, please use {@link RelationshipType} instead. */ public enum CustomReferenceType { @@ -29,18 +32,18 @@ public enum CustomReferenceType BIDIRECTIONAL("bidirectional"); private final String printableString; - + private CustomReferenceType(String printableString) { this.printableString = printableString; } - + @Override public String toString() { return this.printableString; } - + public static CustomReferenceType getEnumFromString(String stg) { for (CustomReferenceType type : CustomReferenceType.values()) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomRefsGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomRefsGet.java index 8edeb9bac3..cd240f689a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomRefsGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomRefsGet.java @@ -181,7 +181,7 @@ public class CustomRefsGet extends AbstractRmWebScript if (RelationshipType.BIDIRECTIONAL.equals(type)) { - data.put(LABEL, displayName.getLabelText()); + data.put(LABEL, displayName.getSourceText()); data.put(SOURCE_REF, source.toString()); data.put(TARGET_REF, target.toString()); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAdminServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAdminServiceImplTest.java index fe6c63716a..a2790fac5b 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAdminServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAdminServiceImplTest.java @@ -25,24 +25,25 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.alfresco.module.org_alfresco_module_rm.admin.CustomMetadataException; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.BeforeCreateReference; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnCreateReference; +import org.alfresco.module.org_alfresco_module_rm.admin.CustomMetadataException; +import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint; import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.MatchLogic; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.module.org_alfresco_module_rm.script.CustomReferenceType; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDefinition; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipType; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; -import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.dictionary.AspectDefinition; -import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.Constraint; import org.alfresco.service.cmr.dictionary.ConstraintDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; @@ -531,16 +532,16 @@ public class RecordsManagementAdminServiceImplTest extends BaseRMTestCase public void testCreateAndUseCustomChildReference() throws Exception { long now = System.currentTimeMillis(); - createAndUseCustomReference(CustomReferenceType.PARENT_CHILD, null, "superseded" + now, "superseding" + now); + createAndUseCustomReference(RelationshipType.PARENTCHILD, null, "superseded" + now, "superseding" + now); } public void testCreateAndUseCustomNonChildReference() throws Exception { long now = System.currentTimeMillis(); - createAndUseCustomReference(CustomReferenceType.BIDIRECTIONAL, "supporting" + now, null, null); + createAndUseCustomReference(RelationshipType.BIDIRECTIONAL, "supporting" + now, null, null); } - private void createAndUseCustomReference(final CustomReferenceType refType, final String label, final String source, final String target) throws Exception + private void createAndUseCustomReference(final RelationshipType refType, final String label, final String source, final String target) throws Exception { final NodeRef testRecord1 = retryingTransactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() { @@ -572,18 +573,25 @@ public class RecordsManagementAdminServiceImplTest extends BaseRMTestCase if (source != null) params.put("source", source); if (target != null) params.put("target", target); - // Create the reference definition. - QName qNameResult; + // Create the relationship display name + RelationshipDisplayName displayName; if (label != null) { // A bidirectional reference - qNameResult = rmAdminService.addCustomAssocDefinition(label); + displayName = new RelationshipDisplayName(label, label); } else { // A parent/child reference - qNameResult = rmAdminService.addCustomChildAssocDefinition(source, target); + displayName = new RelationshipDisplayName(source, target); } + + // Create the relationship definition + RelationshipDefinition relationshipDefinition = relationshipService.createRelationshipDefinition(displayName); + + // Get the qualified name + QName qNameResult = QName.createQName(RM_CUSTOM_PREFIX, relationshipDefinition.getUniqueName(), namespaceService);; + System.out.println("Creating new " + refType + " reference definition: " + qNameResult); System.out.println(" params- label: '" + label + "' source: '" + source + "' target: '" + target + "'"); @@ -595,21 +603,16 @@ public class RecordsManagementAdminServiceImplTest extends BaseRMTestCase { public Void execute() throws Throwable { - // Confirm the custom reference is included in the list from adminService. - Map customRefDefinitions = rmAdminService.getCustomReferenceDefinitions(); - AssociationDefinition retrievedRefDefn = customRefDefinitions.get(generatedQName); - assertNotNull("Custom reference definition from adminService was null.", retrievedRefDefn); - assertEquals(generatedQName, retrievedRefDefn.getName()); - assertEquals(refType.equals(CustomReferenceType.PARENT_CHILD), retrievedRefDefn.isChild()); + RelationshipDefinition relationshipDefinition = relationshipService.getRelationshipDefinition(generatedQName.getLocalName()); + assertNotNull("Relationship definition from relationshipService was null.", relationshipDefinition); + assertEquals(generatedQName.getLocalName(), relationshipDefinition.getUniqueName()); + assertTrue(refType.equals(relationshipDefinition.getType())); // Now we need to use the custom reference. // So we apply the aspect containing it to our test records. nodeService.addAspect(testRecord1, ASPECT_CUSTOM_ASSOCIATIONS, null); - QName assocsAspectQName = QName.createQName("rmc:customAssocs", namespaceService); - nodeService.addAspect(testRecord1, assocsAspectQName, null); - - if (CustomReferenceType.PARENT_CHILD.equals(refType)) + if (RelationshipType.PARENTCHILD.equals(refType)) { nodeService.addChild(testRecord1, testRecord2, generatedQName, generatedQName); } @@ -630,7 +633,7 @@ public class RecordsManagementAdminServiceImplTest extends BaseRMTestCase List retrievedAssocs = nodeService.getTargetAssocs(testRecord1, RegexQNamePattern.MATCH_ALL); Object newlyAddedRef = null; - if (CustomReferenceType.PARENT_CHILD.equals(refType)) + if (RelationshipType.PARENTCHILD.equals(refType)) { for (ChildAssociationRef caRef : childAssocs) { @@ -651,7 +654,7 @@ public class RecordsManagementAdminServiceImplTest extends BaseRMTestCase // Check that the reference has appeared in the data dictionary AspectDefinition customAssocsAspect = dictionaryService.getAspect(ASPECT_CUSTOM_ASSOCIATIONS); assertNotNull(customAssocsAspect); - if (CustomReferenceType.PARENT_CHILD.equals(refType)) + if (RelationshipType.PARENTCHILD.equals(refType)) { assertNotNull("The customReference is not returned from the dictionaryService.", customAssocsAspect.getChildAssociations().get(generatedQName)); @@ -696,13 +699,17 @@ public class RecordsManagementAdminServiceImplTest extends BaseRMTestCase public Void execute() throws Throwable { // Just dump them out for visual inspection - System.out.println("Available custom references:"); - Map references = rmAdminService.getCustomReferenceDefinitions(); - for (QName reference : references.keySet()) + System.out.println("Available relationship definitions:"); + Set relationshipDefinitions = relationshipService.getRelationshipDefinitions(); + for (RelationshipDefinition relationshipDefinition : relationshipDefinitions) { - System.out.println(" - " + reference.toString()); - System.out.println(" " + references.get(reference).getTitle(dictionaryService)); + String uniqueName = relationshipDefinition.getUniqueName(); + RelationshipDisplayName displayName = relationshipDefinition.getDisplayName(); + + System.out.println(" - " + uniqueName); + System.out.println(" " + displayName.toString()); } + return null; } }); @@ -770,7 +777,7 @@ public class RecordsManagementAdminServiceImplTest extends BaseRMTestCase assertFalse(beforeMarker); assertFalse(onMarker); - rmAdminService.addCustomReference(testRecord1, testRecord2, CUSTOM_REF_VERSIONS); + relationshipService.addRelationship(CUSTOM_REF_VERSIONS.getLocalName(), testRecord1, testRecord2); assertTrue(beforeMarker); assertTrue(onMarker); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java index cb64ba01bf..3c9ec4744a 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java @@ -25,10 +25,9 @@ import java.text.MessageFormat; import java.util.Date; import java.util.Map; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.module.org_alfresco_module_rm.script.CustomReferenceType; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipType; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMWebScriptTestCase; import org.alfresco.module.org_alfresco_module_rm.test.util.TestActionParams; import org.alfresco.service.cmr.dictionary.AspectDefinition; @@ -65,59 +64,11 @@ public class RmRestApiTest extends BaseRMWebScriptTestCase implements RecordsMan protected static final String APPLICATION_JSON = "application/json"; protected static final String RMA_CUSTOM_PROPS_DEFINITIONS_URL = "/api/rma/admin/custompropertydefinitions"; protected static final String RMA_CUSTOM_REFS_DEFINITIONS_URL = "/api/rma/admin/customreferencedefinitions"; -// protected NamespaceService namespaceService; -// protected NodeService nodeService; -// protected ContentService contentService; -// protected DictionaryService dictionaryService; -// protected SearchService searchService; -// protected ImporterService importService; -// protected TransactionService transactionService; -// protected ServiceRegistry services; -// protected RecordsManagementActionService rmActionService; -// protected RecordsManagementAuditService rmAuditService; -// protected RecordsManagementAdminService rmAdminService; -// protected RetryingTransactionHelper transactionHelper; -// protected DispositionService dispositionService; private static final String BI_DI = "BiDi"; private static final String CHILD_SRC = "childSrc"; private static final String CHILD_TGT = "childTgt"; -// @Override -// protected void setUp() throws Exception -// { -// setCustomContext("classpath:test-context.xml"); -// -// super.setUp(); -// this.namespaceService = (NamespaceService) getServer().getApplicationContext().getBean("NamespaceService"); -// this.nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService"); -// this.contentService = (ContentService)getServer().getApplicationContext().getBean("ContentService"); -// this.dictionaryService = (DictionaryService)getServer().getApplicationContext().getBean("DictionaryService"); -// this.searchService = (SearchService)getServer().getApplicationContext().getBean("SearchService"); -// this.importService = (ImporterService)getServer().getApplicationContext().getBean("ImporterService"); -// this.transactionService = (TransactionService)getServer().getApplicationContext().getBean("TransactionService"); -// this.services = (ServiceRegistry)getServer().getApplicationContext().getBean("ServiceRegistry"); -// this.rmActionService = (RecordsManagementActionService)getServer().getApplicationContext().getBean("RecordsManagementActionService"); -// this.rmAuditService = (RecordsManagementAuditService)getServer().getApplicationContext().getBean("RecordsManagementAuditService"); -// this.rmAdminService = (RecordsManagementAdminService)getServer().getApplicationContext().getBean("RecordsManagementAdminService"); -// transactionHelper = (RetryingTransactionHelper)getServer().getApplicationContext().getBean("retryingTransactionHelper"); -// dispositionService = (DispositionService)getServer().getApplicationContext().getBean("DispositionService"); -// -// AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); -// -// // Bring the filePlan into the test database. -// // -// // This is quite a slow call, so if this class grew to have many test methods, -// // there would be a real benefit in using something like @BeforeClass for the line below. -// transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() -// { -// public NodeRef execute() throws Throwable -// { -// return TestUtilities.loadFilePlanData(getServer().getApplicationContext()); -// } -// }); -// } - /** * This test method ensures that a POST of an RM action to a non-existent node * will result in a 404 status. @@ -263,7 +214,7 @@ public class RmRestApiTest extends BaseRMWebScriptTestCase implements RecordsMan // 1. Child association. String jsonString = new JSONStringer().object() - .key("referenceType").value(CustomReferenceType.PARENT_CHILD) + .key("referenceType").value(RelationshipType.PARENTCHILD) .key("source").value(CHILD_SRC) .key("target").value(CHILD_TGT) .endObject() @@ -287,7 +238,7 @@ public class RmRestApiTest extends BaseRMWebScriptTestCase implements RecordsMan // 2. Non-child or standard association. jsonString = new JSONStringer().object() - .key("referenceType").value(CustomReferenceType.BIDIRECTIONAL) + .key("referenceType").value(RelationshipType.BIDIRECTIONAL) .key("label").value(BI_DI) .endObject() .toString(); @@ -308,8 +259,7 @@ public class RmRestApiTest extends BaseRMWebScriptTestCase implements RecordsMan result[1] = generatedBidiRefId; // Now assert that both have appeared in the data dictionary. - AspectDefinition customAssocsAspect = - dictionaryService.getAspect(QName.createQName(RecordsManagementAdminServiceImpl.RMC_CUSTOM_ASSOCS, namespaceService)); + AspectDefinition customAssocsAspect = dictionaryService.getAspect(ASPECT_CUSTOM_ASSOCIATIONS); assertNotNull("Missing customAssocs aspect", customAssocsAspect); QName newRefQname = adminService.getQNameForClientId(generatedChildRefId); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index 077d86c61d..54d4ade864 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -42,6 +42,7 @@ import org.alfresco.module.org_alfresco_module_rm.model.rma.type.RmSiteType; import org.alfresco.module.org_alfresco_module_rm.record.InplaceRecordService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; import org.alfresco.module.org_alfresco_module_rm.report.ReportService; import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService; @@ -158,6 +159,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase protected IdentifierService identifierService; protected HoldService holdService; protected InplaceRecordService inplaceRecordService; + protected RelationshipService relationshipService; /** test data */ protected String siteId; @@ -394,6 +396,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase identifierService = (IdentifierService) applicationContext.getBean("recordsManagementIdentifierService"); holdService = (HoldService) applicationContext.getBean("HoldService"); inplaceRecordService = (InplaceRecordService) applicationContext.getBean("InplaceRecordService"); + relationshipService = (RelationshipService) applicationContext.getBean("RelationshipService"); } /**