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 0ccd58ebf8
commit 74899161ce
23 changed files with 1434 additions and 1102 deletions

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

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