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
This commit is contained in:
Tuna Aksoy
2014-10-01 15:42:47 +00:00
parent 9929bca562
commit 829a135988
23 changed files with 1434 additions and 1102 deletions

View File

@@ -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}.

View File

@@ -143,7 +143,6 @@
<property name="actionName" value="transferComplete"/>
<property name="nodeService" ref="nodeService"/>
<property name="dispositionService" ref="dispositionService"/>
<property name="recordsManagementAdminService" ref="recordsManagementAdminService"/>
<property name="recordsManagementActionService" ref="recordsManagementActionService"/>
<property name="recordService" ref="recordService" />
<property name="recordFolderService" ref="RecordFolderService"/>

View File

@@ -678,6 +678,7 @@
</bean>
<bean id="splitEmail" class="org.alfresco.module.org_alfresco_module_rm.action.impl.SplitEmailAction" parent="rmAction">
<property name="RelationshipService" ref="RelationshipService"/>
</bean>
<!-- Create disposition schedule -->

View File

@@ -753,24 +753,27 @@
</property>
</bean>
<!-- Records Management Admin Service -->
<bean id="recordsManagementAdminBase" class="org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminBase" abstract="true">
<property name="dictionaryService" ref="DictionaryService"/>
<property name="nodeService" ref="NodeService"/>
<property name="contentService" ref="contentService"/>
<property name="namespaceService" ref="NamespaceService"/>
<property name="dictionaryRepositoryBootstrap" ref="dictionaryRepositoryBootstrap"/>
</bean>
<bean id="recordsManagementAdminService" class="org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl" init-method="init">
<property name="dictionaryService" ref="DictionaryService"/>
<property name="namespaceService" ref="NamespaceService"/>
<property name="nodeService" ref="NodeService"/>
<property name="policyComponent" ref="policyComponent"/>
<property name="contentService" ref="contentService"/>
<property name="dictionaryRepositoryBootstrap" ref="dictionaryRepositoryBootstrap"/>
<property name="customisableTypes">
<list>
<value>rma:recordCategory</value>
<value>rma:recordFolder</value>
<value>rma:record</value>
<value>rma:nonElectronicDocument</value>
</list>
</property>
</bean>
<!-- Records Management Admin Service -->
<bean id="recordsManagementAdminService" class="org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl" parent="recordsManagementAdminBase">
<property name="relationshipService" ref="RelationshipService" />
<property name="customisableTypes">
<list>
<value>rma:recordCategory</value>
<value>rma:recordFolder</value>
<value>rma:record</value>
<value>rma:nonElectronicDocument</value>
</list>
</property>
</bean>
<bean id="RecordsManagementAdminService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
@@ -1526,10 +1529,8 @@
<!-- Relationship Service -->
<bean id="relationshipService" class="org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipServiceImpl">
<property name="recordsManagementAdminService" ref="RecordsManagementAdminService"/>
<property name="dictionaryService" ref="DictionaryService" />
<property name="namespacePrefixResolver" ref="namespaceService"/>
<bean id="relationshipService" class="org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipServiceImpl" init-method="init" parent="recordsManagementAdminBase">
<property name="policyComponent" ref="policyComponent"/>
</bean>
<bean id="RelationshipService" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -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

View File

@@ -420,6 +420,7 @@
class="org.alfresco.module.org_alfresco_module_rm.script.ApplyDodCertModelFixesGet"
parent="webscript">
<property name="contentService" ref="ContentService" />
<property name="namespaceService" ref="NamespaceService"/>
</bean>
<!-- REST impl for GET applyfixmob1573 -->
@@ -428,6 +429,7 @@
class="org.alfresco.module.org_alfresco_module_rm.script.ApplyFixMob1573Get"
parent="webscript">
<property name="contentService" ref="ContentService" />
<property name="namespaceService" ref="NamespaceService"/>
</bean>
<!-- RM search web script -->

View File

@@ -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<QName, AssociationDefinition> map = recordsManagementAdminService.getCustomReferenceDefinitions();
for (Map.Entry<QName, AssociationDefinition> entry : map.entrySet())
Set<RelationshipDefinition> 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(

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<QName, AssociationDefinition> getCustomAssociations()
{
Map<QName, AssociationDefinition> customAssociations = new HashMap<QName,AssociationDefinition>();
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<NodeRef> 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 <code>true</code> if the association definition title exists, <code>false</code> otherwise
*/
protected boolean existsTitle(String associationDefinitionTitle)
{
boolean existsLabel = false;
Collection<AssociationDefinition> 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();
}
}

View File

@@ -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<QName, AssociationDefinition> 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<AssociationRef> 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<ChildAssociationRef> 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<AssociationRef> 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<ChildAssociationRef> 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);

View File

@@ -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<AssociationRef> fromAssocs = recordsManagementAdminService.getCustomReferencesFrom(record);
List<AssociationRef> 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<AssociationRef> toAssocs = recordsManagementAdminService.getCustomReferencesTo(record);
List<AssociationRef> toAssocs = nodeService.getSourceAssocs(record, RegexQNamePattern.MATCH_ALL);
for (AssociationRef toAssoc : toAssocs)
{
if (reference.equals(toAssoc.getTypeQName()))

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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<BeforeCreateReference> beforeCreateReferenceDelegate;
private ClassPolicyDelegate<OnCreateReference> onCreateReferenceDelegate;
private ClassPolicyDelegate<BeforeRemoveReference> beforeRemoveReferenceDelegate;
private ClassPolicyDelegate<OnRemoveReference> 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<RelationshipDefinition> relationshipDefinitions = new HashSet<RelationshipDefinition>();
Map<QName, AssociationDefinition> customReferenceDefinitions = getRecordsManagementAdminService().getCustomReferenceDefinitions();
for (Map.Entry<QName, AssociationDefinition> customReferenceDefinitionEntry : customReferenceDefinitions.entrySet())
Set<Entry<QName, AssociationDefinition>> associationsEntrySet = getCustomAssociations().entrySet();
for (Map.Entry<QName, AssociationDefinition> 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<QName, AssociationDefinition> 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<QName, AssociationDefinition> customReferenceDefinitions = getRecordsManagementAdminService().getCustomReferenceDefinitions();
exists = customReferenceDefinitions.containsKey(associationDefinitionQName);
exists = true;
}
return exists;
@@ -321,10 +379,10 @@ public class RelationshipServiceImpl implements RelationshipService
Set<Relationship> relationships = new HashSet<Relationship>();
List<AssociationRef> customReferencesFrom = getRecordsManagementAdminService().getCustomReferencesFrom(nodeRef);
List<AssociationRef> customReferencesFrom = getNodeService().getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
relationships.addAll(generateRelationshipFromAssociationRef(customReferencesFrom));
List<ChildAssociationRef> customChildReferences = getRecordsManagementAdminService().getCustomChildReferences(nodeRef);
List<ChildAssociationRef> customChildReferences = getNodeService().getChildAssocs(nodeRef);
relationships.addAll(generateRelationshipFromParentChildAssociationRef(customChildReferences));
return relationships;
@@ -340,10 +398,10 @@ public class RelationshipServiceImpl implements RelationshipService
Set<Relationship> relationships = new HashSet<Relationship>();
List<AssociationRef> customReferencesTo = getRecordsManagementAdminService().getCustomReferencesTo(nodeRef);
List<AssociationRef> customReferencesTo = getNodeService().getSourceAssocs(nodeRef, RegexQNamePattern.MATCH_ALL);
relationships.addAll(generateRelationshipFromAssociationRef(customReferencesTo));
List<ChildAssociationRef> customParentReferences = getRecordsManagementAdminService().getCustomParentReferences(nodeRef);
List<ChildAssociationRef> 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<Void>()
{
@Override
public Void doWork()
{
List<ChildAssociationRef> 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<QName> 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<QName> 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<QName> 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<QName> 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 <code>true</code> if an association already exists, <code>false</code> otherwise
*/
private boolean associationExists(AssociationDefinition associationDefinition, NodeRef source, NodeRef target)
{
boolean associationAlreadyExists = false;
QName associationDefinitionName = associationDefinition.getName();
if (associationDefinition.isChild())
{
List<ChildAssociationRef> childAssocs = getNodeService().getChildAssocs(source, associationDefinitionName, associationDefinitionName);
for (ChildAssociationRef chAssRef : childAssocs)
{
if (chAssRef.getChildRef().equals(target))
{
associationAlreadyExists = true;
}
}
}
else
{
List<AssociationRef> 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, <code>null</code> otherwise
*/
private AssociationDefinition getAssociationDefinition(String uniqueName)
{
AssociationDefinition associationDefinition = null;
Set<Entry<QName, AssociationDefinition>> associationsEntrySet = getCustomAssociations().entrySet();
for (Map.Entry<QName, AssociationDefinition> 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<QName> 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());
}
}

View File

@@ -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<String, Object> 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())
{

View File

@@ -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<String, Object> 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");

View File

@@ -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);
}
}

View File

@@ -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<String, Object> model = new HashMap<String, Object>();
String servicePath = req.getServicePath();

View File

@@ -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))
{

View File

@@ -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
{

View File

@@ -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());
}

View File

@@ -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<NodeRef>()
{
@@ -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<QName, AssociationDefinition> 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<AssociationRef> 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<QName, AssociationDefinition> references = rmAdminService.getCustomReferenceDefinitions();
for (QName reference : references.keySet())
System.out.println("Available relationship definitions:");
Set<RelationshipDefinition> 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);

View File

@@ -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<NodeRef>()
// {
// 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);

View File

@@ -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");
}
/**