From 437a01294c37f262d8299382f8c76810233977d0 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Fri, 3 Jun 2016 14:09:38 +0000 Subject: [PATCH] Merged HEAD (5.2) to 5.2.N (5.2.1) 127569 jkaabimofrad: Merged API-STRIKES-BACK (5.2.0) to HEAD (5.2) 126200 jvonka: Node Associations - follow-on to r126104 to provide initial impl for both peer & child assocs - experimental -> pending detailed review & discussion (and tests) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@127663 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/public-rest-context.xml | 10 ++ source/java/org/alfresco/rest/api/Nodes.java | 2 + .../org/alfresco/rest/api/impl/NodesImpl.java | 26 ++++ .../alfresco/rest/api/model/AssocChild.java | 79 +++++++++++ .../rest/api/nodes/AbstractNodeRelation.java | 124 ++++++++++++++++++ .../rest/api/nodes/NodeParentsRelation.java | 111 ++++++++++++++++ .../rest/api/nodes/NodeSourcesRelation.java | 37 ++---- .../rest/api/nodes/NodeTargetsRelation.java | 74 ++--------- 8 files changed, 370 insertions(+), 93 deletions(-) create mode 100644 source/java/org/alfresco/rest/api/model/AssocChild.java create mode 100644 source/java/org/alfresco/rest/api/nodes/AbstractNodeRelation.java create mode 100644 source/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml index f3d2ebd48f..bc4fa2a283 100644 --- a/config/alfresco/public-rest-context.xml +++ b/config/alfresco/public-rest-context.xml @@ -774,7 +774,17 @@ + + + + + + + + + + diff --git a/source/java/org/alfresco/rest/api/Nodes.java b/source/java/org/alfresco/rest/api/Nodes.java index 8e8ae3a97e..046fc1eeaf 100644 --- a/source/java/org/alfresco/rest/api/Nodes.java +++ b/source/java/org/alfresco/rest/api/Nodes.java @@ -245,6 +245,8 @@ public interface Nodes String PARAM_INCLUDE_ISLINK = "isLink"; String PARAM_INCLUDE_ALLOWABLEOPERATIONS = "allowableOperations"; + String PARAM_INCLUDE_ASSOCIATION = "association"; + String PARAM_ISFOLDER = "isFolder"; String PARAM_ISFILE = "isFile"; diff --git a/source/java/org/alfresco/rest/api/impl/NodesImpl.java b/source/java/org/alfresco/rest/api/impl/NodesImpl.java index b843f0cb80..0914628838 100644 --- a/source/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -53,6 +53,7 @@ import org.alfresco.rest.antlr.WhereClauseParser; import org.alfresco.rest.api.Activities; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.QuickShareLinks; +import org.alfresco.rest.api.model.AssocChild; import org.alfresco.rest.api.model.ContentInfo; import org.alfresco.rest.api.model.Document; import org.alfresco.rest.api.model.Folder; @@ -901,6 +902,31 @@ public class NodesImpl implements Nodes node.setAllowableOperations((allowableOperations.size() > 0 )? allowableOperations : null); } + if (includeParam.contains(PARAM_INCLUDE_ASSOCIATION)) + { + // Ugh ... can we optimise this and return the actual assoc directly (via FileFolderService/GetChildrenCQ) ? + ChildAssociationRef parentAssocRef = nodeService.getPrimaryParent(nodeRef); + if (! parentAssocRef.getParentRef().equals(parentNodeRef)) + { + List parentAssocRefs = nodeService.getParentAssocs(nodeRef); + for (ChildAssociationRef pAssocRef : parentAssocRefs) + { + if (pAssocRef.getParentRef().equals(parentNodeRef)) + { + // for now, assume same parent/child cannot appear more than once (due to unique name) + parentAssocRef = pAssocRef; + break; + } + } + } + + AssocChild childAssoc = new AssocChild( + parentAssocRef.getTypeQName().toPrefixString(namespaceService), + parentAssocRef.isPrimary(), + parentAssocRef.getQName().toPrefixString(namespaceService)); + node.setAssociation(childAssoc); + } + node.setNodeType(nodeTypeQName.toPrefixString(namespaceService)); node.setPath(pathInfo); diff --git a/source/java/org/alfresco/rest/api/model/AssocChild.java b/source/java/org/alfresco/rest/api/model/AssocChild.java new file mode 100644 index 0000000000..9d980e0cdc --- /dev/null +++ b/source/java/org/alfresco/rest/api/model/AssocChild.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2005-2016 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.rest.api.model; + +/** + * @author janv + */ +public class AssocChild extends Assoc +{ + private String childId; + private String prefixAssocChildQName; + private Boolean isPrimaryParent; + + public AssocChild() + { + } + + public AssocChild(String prefixAssocTypeQName, boolean isPrimaryParent, String prefixAssocChildQName) + { + super(prefixAssocTypeQName); + + this.prefixAssocChildQName = prefixAssocChildQName; + this.isPrimaryParent = isPrimaryParent; + } + + public AssocChild(String childId, String prefixAssocTypeQName, String prefixAssocNameQName) + { + super(prefixAssocTypeQName); + + this.childId = childId; + this.prefixAssocChildQName = prefixAssocNameQName; + } + + public String getChildQName() + { + return prefixAssocChildQName; + } + + public void setChildQName(String prefixAssocChildQName) + { + this.prefixAssocChildQName = prefixAssocChildQName; + } + + public Boolean getIsPrimaryParent() + { + return isPrimaryParent; + } + + public void setIsPrimaryParent(Boolean isPrimaryParent) + { + this.isPrimaryParent = isPrimaryParent; + } + + public String getChildId() + { + return childId; + } + + public void setChildId(String childId) + { + this.childId = childId; + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/rest/api/nodes/AbstractNodeRelation.java b/source/java/org/alfresco/rest/api/nodes/AbstractNodeRelation.java new file mode 100644 index 0000000000..21d1f479b0 --- /dev/null +++ b/source/java/org/alfresco/rest/api/nodes/AbstractNodeRelation.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2005-2016 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.rest.api.nodes; + +import org.alfresco.rest.antlr.WhereClauseParser; +import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.model.Assoc; +import org.alfresco.rest.api.model.AssocTarget; +import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.api.model.UserInfo; +import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.framework.resource.RelationshipResource; +import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Paging; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rest.framework.resource.parameters.where.Query; +import org.alfresco.rest.framework.resource.parameters.where.QueryHelper; +import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.AssociationExistsException; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.QNamePattern; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.util.ParameterCheck; +import org.alfresco.util.PropertyCheck; +import org.springframework.beans.factory.InitializingBean; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author janv + */ +public class AbstractNodeRelation implements InitializingBean +{ + public final static String PARAM_ASSOC_TYPE = "assocType"; + + private final static Set WHERE_PARAMS = + new HashSet<>(Arrays.asList(new String[] {PARAM_ASSOC_TYPE})); + + protected ServiceRegistry sr; + protected NodeService nodeService; + protected NamespaceService namespaceService; + protected Nodes nodes; + + public void setNodes(Nodes nodes) + { + this.nodes = nodes; + } + + public void setServiceRegistry(ServiceRegistry sr) + { + this.sr = sr; + } + + @Override + public void afterPropertiesSet() + { + PropertyCheck.mandatory(this, "serviceRegistry", sr); + ParameterCheck.mandatory("nodes", this.nodes); + + this.nodeService = sr.getNodeService(); + this.namespaceService = sr.getNamespaceService(); + } + + protected QName getAssocType(String prefixAssocTypeStr, boolean mandatory) + { + if (mandatory && ((prefixAssocTypeStr == null) || prefixAssocTypeStr.isEmpty())) + { + throw new InvalidArgumentException("Missing "+PARAM_ASSOC_TYPE); + } + + return QName.createQName(prefixAssocTypeStr, namespaceService); + } + + protected QNamePattern getAssocTypeFromWhereElseAll(Parameters parameters) + { + QNamePattern assocTypeQNameParam = RegexQNamePattern.MATCH_ALL; + + Query q = parameters.getQuery(); + if (q != null) + { + MapBasedQueryWalker propertyWalker = new MapBasedQueryWalker(WHERE_PARAMS, null); + QueryHelper.walk(q, propertyWalker); + + String assocTypeQNameStr = propertyWalker.getProperty(PARAM_ASSOC_TYPE, WhereClauseParser.EQUALS, String.class); + if (assocTypeQNameStr != null) + { + assocTypeQNameParam = getAssocType(assocTypeQNameStr, true); + } + } + + return assocTypeQNameParam; + } +} diff --git a/source/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java b/source/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java new file mode 100644 index 0000000000..819d9eada9 --- /dev/null +++ b/source/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005-2016 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.rest.api.nodes; + +import org.alfresco.rest.api.model.AssocChild; +import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.api.model.UserInfo; +import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.resource.RelationshipResource; +import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Paging; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.QNamePattern; +import org.alfresco.service.namespace.RegexQNamePattern; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Node Parents + * + * List node's parent(s) - primary & also secondary, if any - based on (parent ->) child associations + * + * @author janv + */ +@RelationshipResource(name = "parents", entityResource = NodesEntityResource.class, title = "Node Parents") +public class NodeParentsRelation extends AbstractNodeRelation implements RelationshipResourceAction.Read +{ + /** + * List parents + * + * @param childNodeId String id of child node + */ + @Override + @WebApiDescription(title = "Return a paged list of parent nodes based on child assocs") + public CollectionWithPagingInfo readAll(String childNodeId, Parameters parameters) + { + NodeRef childNodeRef = nodes.validateOrLookupNode(childNodeId, null); + + QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters); + + List assocRefs = null; + if (assocTypeQNameParam.equals(RegexQNamePattern.MATCH_ALL)) + { + assocRefs = nodeService.getParentAssocs(childNodeRef); + } + else + { + assocRefs = nodeService.getParentAssocs(childNodeRef, assocTypeQNameParam, RegexQNamePattern.MATCH_ALL); + } + + Map qnameMap = new HashMap<>(3); + + Map mapUserInfo = new HashMap<>(10); + + List includeParam = parameters.getInclude(); + + List collection = new ArrayList<>(assocRefs.size()); + for (ChildAssociationRef assocRef : assocRefs) + { + // minimal info by default (unless "include"d otherwise) + Node node = nodes.getFolderOrDocument(assocRef.getParentRef(), null, null, includeParam, mapUserInfo); + + QName assocTypeQName = assocRef.getTypeQName(); + QName assocChildQName = assocRef.getQName(); + + String assocType = qnameMap.get(assocTypeQName); + if (assocType == null) + { + assocType = assocTypeQName.toPrefixString(namespaceService); + qnameMap.put(assocTypeQName, assocType); + } + + String childQNameStr = qnameMap.get(assocChildQName); + if (childQNameStr == null) + { + childQNameStr = assocChildQName.toPrefixString(namespaceService); + qnameMap.put(assocChildQName, childQNameStr); + } + + node.setAssociation(new AssocChild(assocType, assocRef.isPrimary(), childQNameStr)); + + collection.add(node); + } + + Paging paging = parameters.getPaging(); + return CollectionWithPagingInfo.asPaged(paging, collection, false, collection.size()); + } +} diff --git a/source/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java b/source/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java index 78cad2c19a..3694b123ec 100644 --- a/source/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java +++ b/source/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java @@ -20,6 +20,7 @@ package org.alfresco.rest.api.nodes; import org.activiti.engine.history.HistoricActivityInstance; import org.alfresco.repo.web.scripts.admin.NodeBrowserPost; +import org.alfresco.rest.antlr.WhereClauseParser; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.Assoc; import org.alfresco.rest.api.model.Comment; @@ -35,7 +36,10 @@ import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResou import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rest.framework.resource.parameters.where.Query; +import org.alfresco.rest.framework.resource.parameters.where.QueryHelper; import org.alfresco.rest.framework.webscripts.WithResponse; +import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker; import org.alfresco.rest.workflow.api.model.Activity; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.AssociationRef; @@ -45,6 +49,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.QNamePattern; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.ParameterCheck; import org.alfresco.util.PropertyCheck; @@ -63,33 +68,8 @@ import java.util.Map; * @author janv */ @RelationshipResource(name = "sources", entityResource = NodesEntityResource.class, title = "Node Sources") -public class NodeSourcesRelation implements RelationshipResourceAction.Read, InitializingBean +public class NodeSourcesRelation extends AbstractNodeRelation implements RelationshipResourceAction.Read { - private ServiceRegistry sr; - private NodeService nodeService; - private NamespaceService namespaceService; - private Nodes nodes; - - public void setNodes(Nodes nodes) - { - this.nodes = nodes; - } - - public void setServiceRegistry(ServiceRegistry sr) - { - this.sr = sr; - } - - @Override - public void afterPropertiesSet() - { - PropertyCheck.mandatory(this, "serviceRegistry", sr); - ParameterCheck.mandatory("nodes", this.nodes); - - this.nodeService = sr.getNodeService(); - this.namespaceService = sr.getNamespaceService(); - } - /** * List sources * @@ -101,8 +81,9 @@ public class NodeSourcesRelation implements RelationshipResourceAction.Read assocRefs = nodeService.getSourceAssocs(targetNodeRef, RegexQNamePattern.MATCH_ALL); + QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters); + + List assocRefs = nodeService.getSourceAssocs(targetNodeRef, assocTypeQNameParam); Map qnameMap = new HashMap<>(3); diff --git a/source/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java b/source/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java index 38f1704984..dd711d8741 100644 --- a/source/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java +++ b/source/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java @@ -18,54 +18,30 @@ */ package org.alfresco.rest.api.nodes; -import org.activiti.engine.history.HistoricActivityInstance; -import org.alfresco.repo.web.scripts.admin.NodeBrowserPost; -import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.Assoc; import org.alfresco.rest.api.model.AssocTarget; -import org.alfresco.rest.api.model.Comment; import org.alfresco.rest.api.model.Node; import org.alfresco.rest.api.model.UserInfo; import org.alfresco.rest.framework.WebApiDescription; -import org.alfresco.rest.framework.WebApiParam; -import org.alfresco.rest.framework.WebApiParameters; import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException; -import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; -import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.resource.RelationshipResource; -import org.alfresco.rest.framework.resource.actions.interfaces.MultiPartRelationshipResourceAction; import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.rest.framework.resource.parameters.Parameters; -import org.alfresco.rest.framework.webscripts.WithResponse; -import org.alfresco.rest.workflow.api.model.Activity; -import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.AssociationExistsException; import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; 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.cmr.search.ResultSetRow; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.QNamePattern; import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.util.ParameterCheck; -import org.alfresco.util.PropertyCheck; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.ConcurrencyFailureException; -import org.springframework.extensions.webscripts.servlet.FormData; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import static org.alfresco.repo.publishing.PublishingModel.ASSOC_LAST_PUBLISHING_EVENT; -import static org.alfresco.util.collections.CollectionUtils.isEmpty; - /** * Node Targets * @@ -74,36 +50,11 @@ import static org.alfresco.util.collections.CollectionUtils.isEmpty; * @author janv */ @RelationshipResource(name = "targets", entityResource = NodesEntityResource.class, title = "Node Targets") -public class NodeTargetsRelation implements +public class NodeTargetsRelation extends AbstractNodeRelation implements RelationshipResourceAction.Read, RelationshipResourceAction.Create, - RelationshipResourceAction.Delete, InitializingBean + RelationshipResourceAction.Delete { - private ServiceRegistry sr; - private NodeService nodeService; - private NamespaceService namespaceService; - private Nodes nodes; - - public void setNodes(Nodes nodes) - { - this.nodes = nodes; - } - - public void setServiceRegistry(ServiceRegistry sr) - { - this.sr = sr; - } - - @Override - public void afterPropertiesSet() - { - PropertyCheck.mandatory(this, "serviceRegistry", sr); - ParameterCheck.mandatory("nodes", this.nodes); - - this.nodeService = sr.getNodeService(); - this.namespaceService = sr.getNamespaceService(); - } - /** * List targets * @@ -115,8 +66,9 @@ public class NodeTargetsRelation implements { NodeRef sourceNodeRef = nodes.validateOrLookupNode(sourceNodeId, null); - // TODO option to filter by assocType ... ? - List assocRefs = nodeService.getTargetAssocs(sourceNodeRef, RegexQNamePattern.MATCH_ALL); + QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters); + + List assocRefs = nodeService.getTargetAssocs(sourceNodeRef, assocTypeQNameParam); Map qnameMap = new HashMap<>(3); @@ -124,7 +76,7 @@ public class NodeTargetsRelation implements List includeParam = parameters.getInclude(); - List collection = new ArrayList(assocRefs.size()); + List collection = new ArrayList<>(assocRefs.size()); for (AssociationRef assocRef : assocRefs) { // minimal info by default (unless "include"d otherwise) @@ -156,17 +108,10 @@ public class NodeTargetsRelation implements for (AssocTarget assoc : entity) { - String assocTypeStr = assoc.getAssocType(); - if ((assocTypeStr == null) || assocTypeStr.isEmpty()) - { - throw new InvalidArgumentException("Missing assocType"); - } - - QName assocTypeQName = QName.createQName(assocTypeStr, namespaceService); + QName assocTypeQName = getAssocType(assoc.getAssocType(), true); try { - // TODO consider x-store refs ? NodeRef tgtNodeRef = nodes.validateNode(assoc.getTargetId()); nodeService.createAssociation(srcNodeRef, tgtNodeRef, assocTypeQName); } @@ -184,11 +129,10 @@ public class NodeTargetsRelation implements @WebApiDescription(title = "Remove node assoc(s)") public void delete(String sourceNodeId, String targetNodeId, Parameters parameters) { - // TODO consider x-store refs ? NodeRef srcNodeRef = nodes.validateNode(sourceNodeId); NodeRef tgtNodeRef = nodes.validateNode(targetNodeId); - String assocTypeStr = parameters.getParameter("assocType"); + String assocTypeStr = parameters.getParameter(PARAM_ASSOC_TYPE); if ((assocTypeStr != null) && (! assocTypeStr.isEmpty())) { QName assocTypeQName = QName.createQName(assocTypeStr, namespaceService);