mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged HEAD (5.2) to 5.2.N (5.2.1)
127579 jkaabimofrad: Merged API-STRIKES-BACK (5.2.0) to HEAD (5.2) 126567 jvonka: Node Associations - further updates - for child assocs, do not expose assoc child qname (nominally like file/folder for primary child assoc) - additional api tests (+ve & -ve) for peer assocs & secondary child assocs - RA-745, RA-920, RA-921, RA-930, RA-742, RA-918, RA-919 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@127672 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -137,6 +137,7 @@
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.InvalidArgumentException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_BAD_REQUEST}" />
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.NotFoundException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_NOT_FOUND}" />
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.EntityNotFoundException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_NOT_FOUND}" />
|
||||
<entry key="org.alfresco.service.cmr.repository.InvalidNodeRefException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_NOT_FOUND}" />
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_NOT_FOUND}" />
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.PermissionDeniedException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_FORBIDDEN}" />
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_METHOD_NOT_ALLOWED}" />
|
||||
|
@@ -922,8 +922,8 @@ public class NodesImpl implements Nodes
|
||||
|
||||
AssocChild childAssoc = new AssocChild(
|
||||
parentAssocRef.getTypeQName().toPrefixString(namespaceService),
|
||||
parentAssocRef.isPrimary(),
|
||||
parentAssocRef.getQName().toPrefixString(namespaceService));
|
||||
parentAssocRef.isPrimary());
|
||||
|
||||
node.setAssociation(childAssoc);
|
||||
}
|
||||
|
||||
|
@@ -24,37 +24,24 @@ package org.alfresco.rest.api.model;
|
||||
public class AssocChild extends Assoc
|
||||
{
|
||||
private String childId;
|
||||
private String prefixAssocChildQName;
|
||||
private Boolean isPrimaryParent;
|
||||
|
||||
public AssocChild()
|
||||
{
|
||||
}
|
||||
|
||||
public AssocChild(String prefixAssocTypeQName, boolean isPrimaryParent, String prefixAssocChildQName)
|
||||
public AssocChild(String prefixAssocTypeQName, boolean isPrimaryParent)
|
||||
{
|
||||
super(prefixAssocTypeQName);
|
||||
|
||||
this.prefixAssocChildQName = prefixAssocChildQName;
|
||||
this.isPrimaryParent = isPrimaryParent;
|
||||
}
|
||||
|
||||
public AssocChild(String childId, String prefixAssocTypeQName, String prefixAssocNameQName)
|
||||
public AssocChild(String childId, String prefixAssocTypeQName)
|
||||
{
|
||||
super(prefixAssocTypeQName);
|
||||
|
||||
this.childId = childId;
|
||||
this.prefixAssocChildQName = prefixAssocNameQName;
|
||||
}
|
||||
|
||||
public String getChildQName()
|
||||
{
|
||||
return prefixAssocChildQName;
|
||||
}
|
||||
|
||||
public void setChildQName(String prefixAssocChildQName)
|
||||
{
|
||||
this.prefixAssocChildQName = prefixAssocChildQName;
|
||||
}
|
||||
|
||||
public Boolean getIsPrimaryParent()
|
||||
|
@@ -36,6 +36,7 @@ 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.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.AssociationExistsException;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -70,6 +71,7 @@ public class AbstractNodeRelation implements InitializingBean
|
||||
protected ServiceRegistry sr;
|
||||
protected NodeService nodeService;
|
||||
protected NamespaceService namespaceService;
|
||||
protected DictionaryService dictionaryService;
|
||||
protected Nodes nodes;
|
||||
|
||||
public void setNodes(Nodes nodes)
|
||||
@@ -90,21 +92,42 @@ public class AbstractNodeRelation implements InitializingBean
|
||||
|
||||
this.nodeService = sr.getNodeService();
|
||||
this.namespaceService = sr.getNamespaceService();
|
||||
this.dictionaryService = sr.getDictionaryService();
|
||||
}
|
||||
|
||||
protected QName getAssocType(String prefixAssocTypeStr, boolean mandatory)
|
||||
protected QName getAssocType(String prefixAssocTypeStr)
|
||||
{
|
||||
if (mandatory && ((prefixAssocTypeStr == null) || prefixAssocTypeStr.isEmpty()))
|
||||
return getAssocType(prefixAssocTypeStr, true, true);
|
||||
}
|
||||
|
||||
protected QName getAssocType(String prefixAssocTypeStr, boolean mandatory, boolean validate)
|
||||
{
|
||||
QName assocType = null;
|
||||
|
||||
if ((prefixAssocTypeStr != null) && (! prefixAssocTypeStr.isEmpty()))
|
||||
{
|
||||
assocType = QName.createQName(prefixAssocTypeStr, namespaceService);
|
||||
|
||||
if (validate)
|
||||
{
|
||||
if (dictionaryService.getAssociation(assocType) == null)
|
||||
{
|
||||
throw new InvalidArgumentException("Unknown filter assocType: "+prefixAssocTypeStr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (mandatory)
|
||||
{
|
||||
throw new InvalidArgumentException("Missing "+PARAM_ASSOC_TYPE);
|
||||
}
|
||||
|
||||
return QName.createQName(prefixAssocTypeStr, namespaceService);
|
||||
return assocType;
|
||||
}
|
||||
|
||||
protected QNamePattern getAssocTypeFromWhereElseAll(Parameters parameters)
|
||||
{
|
||||
QNamePattern assocTypeQNameParam = RegexQNamePattern.MATCH_ALL;
|
||||
QNamePattern assocTypeQNamePattern = RegexQNamePattern.MATCH_ALL;
|
||||
|
||||
Query q = parameters.getQuery();
|
||||
if (q != null)
|
||||
@@ -115,10 +138,10 @@ public class AbstractNodeRelation implements InitializingBean
|
||||
String assocTypeQNameStr = propertyWalker.getProperty(PARAM_ASSOC_TYPE, WhereClauseParser.EQUALS, String.class);
|
||||
if (assocTypeQNameStr != null)
|
||||
{
|
||||
assocTypeQNameParam = getAssocType(assocTypeQNameStr, true);
|
||||
assocTypeQNamePattern = getAssocType(assocTypeQNameStr);
|
||||
}
|
||||
}
|
||||
|
||||
return assocTypeQNameParam;
|
||||
return assocTypeQNamePattern;
|
||||
}
|
||||
}
|
||||
|
@@ -41,20 +41,19 @@ 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<Node>
|
||||
{
|
||||
/**
|
||||
* List parents
|
||||
* List child node's parent(s) based on (parent ->) child associations.
|
||||
* Returns primary parent & also secondary parents, if any.
|
||||
*
|
||||
* @param childNodeId String id of child node
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Return a paged list of parent nodes based on child assocs")
|
||||
@WebApiDescription(title = "Return a list of parent nodes based on child assocs")
|
||||
public CollectionWithPagingInfo<Node> readAll(String childNodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef childNodeRef = nodes.validateOrLookupNode(childNodeId, null);
|
||||
@@ -84,7 +83,6 @@ public class NodeParentsRelation extends AbstractNodeRelation implements Relatio
|
||||
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)
|
||||
@@ -93,14 +91,7 @@ public class NodeParentsRelation extends AbstractNodeRelation implements Relatio
|
||||
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));
|
||||
node.setAssociation(new AssocChild(assocType, assocRef.isPrimary()));
|
||||
|
||||
collection.add(node);
|
||||
}
|
||||
|
@@ -18,11 +18,13 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
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.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.RelationshipResourceAction;
|
||||
@@ -33,6 +35,7 @@ import org.alfresco.service.cmr.repository.AssociationExistsException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
@@ -106,15 +109,7 @@ public class NodeSecondaryChildrenRelation extends AbstractNodeRelation implemen
|
||||
qnameMap.put(assocTypeQName, assocType);
|
||||
}
|
||||
|
||||
QName assocChildQName = assocRef.getQName();
|
||||
String childQNameStr = qnameMap.get(assocChildQName);
|
||||
if (childQNameStr == null)
|
||||
{
|
||||
childQNameStr = assocChildQName.toPrefixString(namespaceService);
|
||||
qnameMap.put(assocChildQName, childQNameStr);
|
||||
}
|
||||
|
||||
node.setAssociation(new AssocChild(assocType, assocRef.isPrimary(), childQNameStr));
|
||||
node.setAssociation(new AssocChild(assocType, assocRef.isPrimary()));
|
||||
|
||||
collection.add(node);
|
||||
}
|
||||
@@ -134,20 +129,16 @@ public class NodeSecondaryChildrenRelation extends AbstractNodeRelation implemen
|
||||
|
||||
for (AssocChild assoc : entity)
|
||||
{
|
||||
QName assocTypeQName = getAssocType(assoc.getAssocType(), true);
|
||||
|
||||
String childQNameStr = assoc.getChildQName();
|
||||
if ((childQNameStr == null) || childQNameStr.isEmpty())
|
||||
{
|
||||
throw new InvalidArgumentException("Missing childQName");
|
||||
}
|
||||
|
||||
QName childQName = QName.createQName(childQNameStr, namespaceService);
|
||||
QName assocTypeQName = getAssocType(assoc.getAssocType());
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef childNodeRef = nodes.validateNode(assoc.getChildId());
|
||||
nodeService.addChild(parentNodeRef, childNodeRef, assocTypeQName, childQName);
|
||||
|
||||
String nodeName = (String)nodeService.getProperty(childNodeRef, ContentModel.PROP_NAME);
|
||||
QName assocChildQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName));
|
||||
|
||||
nodeService.addChild(parentNodeRef, childNodeRef, assocTypeQName, assocChildQName);
|
||||
}
|
||||
catch (AssociationExistsException aee)
|
||||
{
|
||||
@@ -170,41 +161,53 @@ public class NodeSecondaryChildrenRelation extends AbstractNodeRelation implemen
|
||||
NodeRef parentNodeRef = nodes.validateNode(parentNodeId);
|
||||
NodeRef childNodeRef = nodes.validateNode(childNodeId);
|
||||
|
||||
QName assocTypeQName = getAssocType(parameters.getParameter("assocType"), false);
|
||||
String assocTypeStr = parameters.getParameter(PARAM_ASSOC_TYPE);
|
||||
QName assocTypeQName = getAssocType(assocTypeStr, false, true);
|
||||
|
||||
String childQNameStr = parameters.getParameter("childQName");
|
||||
QName childQName = null;
|
||||
if ((childQNameStr != null) && (!childQNameStr.isEmpty()))
|
||||
List<ChildAssociationRef> assocRefs = nodeService.getChildAssocs(parentNodeRef);
|
||||
|
||||
boolean found = false;
|
||||
|
||||
for (ChildAssociationRef assocRef : assocRefs)
|
||||
{
|
||||
childQName = QName.createQName(childQNameStr, namespaceService);
|
||||
if (! assocRef.getChildRef().equals(childNodeRef))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assocTypeQName != null)
|
||||
{
|
||||
if (childQName != null)
|
||||
if (assocTypeQName.equals(assocRef.getTypeQName()))
|
||||
{
|
||||
ChildAssociationRef assocRef = new ChildAssociationRef(assocTypeQName, parentNodeRef, childQName, childNodeRef);
|
||||
nodeService.removeSecondaryChildAssociation(assocRef);
|
||||
if (assocRef.isPrimary())
|
||||
{
|
||||
throw new InvalidArgumentException("Cannot use secondary-children to delete primary assoc: "
|
||||
+parentNodeId+","+assocTypeStr+","+childNodeId);
|
||||
}
|
||||
|
||||
boolean existed = nodeService.removeSecondaryChildAssociation(assocRef);
|
||||
if (existed)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException("Missing childQName (in addition to assocType)");
|
||||
}
|
||||
}
|
||||
else if (childQName != null)
|
||||
if (! assocRef.isPrimary())
|
||||
{
|
||||
throw new InvalidArgumentException("Missing assocType (in addition to childQName)");
|
||||
}
|
||||
else
|
||||
boolean existed = nodeService.removeSecondaryChildAssociation(assocRef);
|
||||
if (existed)
|
||||
{
|
||||
List<ChildAssociationRef> assocRefs = nodeService.getChildAssocs(parentNodeRef);
|
||||
for (ChildAssociationRef assocRef : assocRefs)
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! found)
|
||||
{
|
||||
if (assocRef.getChildRef().equals(childNodeRef) && (! assocRef.isPrimary()))
|
||||
{
|
||||
nodeService.removeSecondaryChildAssociation(assocRef);
|
||||
}
|
||||
}
|
||||
throw new EntityNotFoundException(parentNodeId+","+assocTypeStr+","+childNodeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@ 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.EntityNotFoundException;
|
||||
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;
|
||||
@@ -108,17 +110,25 @@ public class NodeTargetsRelation extends AbstractNodeRelation implements
|
||||
|
||||
for (AssocTarget assoc : entity)
|
||||
{
|
||||
QName assocTypeQName = getAssocType(assoc.getAssocType(), true);
|
||||
String assocTypeStr = assoc.getAssocType();
|
||||
QName assocTypeQName = getAssocType(assocTypeStr);
|
||||
|
||||
String targetNodeId = assoc.getTargetId();
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef tgtNodeRef = nodes.validateNode(assoc.getTargetId());
|
||||
NodeRef tgtNodeRef = nodes.validateNode(targetNodeId);
|
||||
nodeService.createAssociation(srcNodeRef, tgtNodeRef, assocTypeQName);
|
||||
}
|
||||
catch (AssociationExistsException aee)
|
||||
{
|
||||
throw new ConstraintViolatedException(aee.getMessage());
|
||||
}
|
||||
catch (IllegalArgumentException iae)
|
||||
{
|
||||
// note: for now, we assume it is invalid assocType - alternatively, we could attempt to pre-validate via dictionary.getAssociation
|
||||
throw new InvalidArgumentException(sourceNodeId+","+assocTypeStr+","+targetNodeId);
|
||||
}
|
||||
|
||||
result.add(assoc);
|
||||
}
|
||||
@@ -133,21 +143,31 @@ public class NodeTargetsRelation extends AbstractNodeRelation implements
|
||||
NodeRef tgtNodeRef = nodes.validateNode(targetNodeId);
|
||||
|
||||
String assocTypeStr = parameters.getParameter(PARAM_ASSOC_TYPE);
|
||||
if ((assocTypeStr != null) && (! assocTypeStr.isEmpty()))
|
||||
QNamePattern assocTypeQName = getAssocType(assocTypeStr, false, true);
|
||||
|
||||
if (assocTypeQName == null)
|
||||
{
|
||||
QName assocTypeQName = QName.createQName(assocTypeStr, namespaceService);
|
||||
nodeService.removeAssociation(srcNodeRef, tgtNodeRef, assocTypeQName);
|
||||
assocTypeQName = RegexQNamePattern.MATCH_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<AssociationRef> assocRefs = nodeService.getTargetAssocs(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, sourceNodeId), RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
// note: even if assocType is provided, we currently don't use nodeService.removeAssociation(srcNodeRef, tgtNodeRef, assocTypeQName);
|
||||
// since silent it returns void even if nothing deleted, where as we return 404
|
||||
|
||||
boolean found = false;
|
||||
|
||||
List<AssociationRef> assocRefs = nodeService.getTargetAssocs(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, sourceNodeId), assocTypeQName);
|
||||
for (AssociationRef assocRef : assocRefs)
|
||||
{
|
||||
if (assocRef.getTargetRef().equals(tgtNodeRef))
|
||||
{
|
||||
nodeService.removeAssociation(srcNodeRef, tgtNodeRef, assocRef.getTypeQName());
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found)
|
||||
{
|
||||
throw new EntityNotFoundException(sourceNodeId+","+assocTypeStr+","+targetNodeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -21,19 +21,12 @@ package org.alfresco.rest.api.tests;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.Queries;
|
||||
import org.alfresco.rest.api.model.AssocChild;
|
||||
import org.alfresco.rest.api.model.AssocTarget;
|
||||
import org.alfresco.rest.api.tests.client.HttpResponse;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiClient;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiClient.Paging;
|
||||
import org.alfresco.rest.api.tests.client.RequestContext;
|
||||
import org.alfresco.rest.api.tests.client.data.Association;
|
||||
import org.alfresco.rest.api.tests.client.data.ContentInfo;
|
||||
import org.alfresco.rest.api.tests.client.data.Document;
|
||||
import org.alfresco.rest.api.tests.client.data.Folder;
|
||||
import org.alfresco.rest.api.tests.client.data.Node;
|
||||
import org.alfresco.rest.api.tests.client.data.Tag;
|
||||
import org.alfresco.rest.api.tests.util.RestApiUtil;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
@@ -44,12 +37,10 @@ import org.junit.Test;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
|
||||
import static org.junit.Assert.*;
|
||||
@@ -100,9 +91,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
private static final String ASPECT_CM_PREFERENCES = "cm:preferences";
|
||||
private static final String ASSOC_TYPE_CM_PREFERENCE_IMAGE = "cm:preferenceImage";
|
||||
|
||||
private static final String PARAM_CHILD_NAME = "childQName";
|
||||
|
||||
|
||||
|
||||
private String user1;
|
||||
private String user2;
|
||||
@@ -220,10 +208,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
|
||||
Paging paging = getPaging(0, 100);
|
||||
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
getAll(getNodeTargetsUrl(f1Id), null, paging, null, 401);
|
||||
getAll(getNodeSourcesUrl(f1Id), null, paging, null, 401);
|
||||
|
||||
// empty lists - before
|
||||
|
||||
response = getAll(getNodeTargetsUrl(o1Id), user1, paging, null, 200);
|
||||
@@ -242,13 +226,9 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||
assertEquals(0, nodes.size());
|
||||
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
AssocTarget tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_REFERENCES);
|
||||
post(getNodeTargetsUrl(o1Id), null, toJsonAsStringNonNull(tgt), 401);
|
||||
|
||||
// create two assocs in one direction (from src to tgt)
|
||||
|
||||
tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_REFERENCES);
|
||||
AssocTarget tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_REFERENCES);
|
||||
post(getNodeTargetsUrl(o1Id), user1, toJsonAsStringNonNull(tgt), 201);
|
||||
|
||||
tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_PARTS);
|
||||
@@ -311,7 +291,7 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
assertEquals(o2Id, nodes.get(0).getId());
|
||||
assertEquals(ASSOC_TYPE_CM_REFERENCES, nodes.get(0).getAssociation().getAssocType());
|
||||
|
||||
params = new HashMap<>();
|
||||
params = new HashMap<>(1);
|
||||
params.put("where", "(assocType='"+ASSOC_TYPE_CM_PARTS+"')");
|
||||
|
||||
response = getAll(getNodeTargetsUrl(o2Id), user1, paging, params, 200);
|
||||
@@ -326,10 +306,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
assertEquals(o1Id, nodes.get(0).getId());
|
||||
assertEquals(ASSOC_TYPE_CM_PARTS, nodes.get(0).getAssociation().getAssocType());
|
||||
|
||||
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
delete(getNodeTargetsUrl(o1Id), null, o2Id, 401);
|
||||
|
||||
// remove assocs - specific type - in one direction
|
||||
params = new HashMap<>(2);
|
||||
params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_REFERENCES);
|
||||
@@ -393,6 +369,15 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
assertEquals(0, nodes.size());
|
||||
|
||||
|
||||
//
|
||||
// -ve tests - add assoc
|
||||
//
|
||||
|
||||
{
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
tgt = new AssocTarget(o2Id, ASSOC_TYPE_CM_REFERENCES);
|
||||
post(getNodeTargetsUrl(o1Id), null, toJsonAsStringNonNull(tgt), 401);
|
||||
|
||||
// -ve test - model integrity
|
||||
tgt = new AssocTarget(f2Id, ASSOC_TYPE_CM_REFERENCES);
|
||||
post(getNodeTargetsUrl(o1Id), user1, toJsonAsStringNonNull(tgt), 422);
|
||||
@@ -402,9 +387,56 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 201);
|
||||
post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 409);
|
||||
|
||||
// TODO some more negative tests
|
||||
// 400s - eg. invalid qname
|
||||
// 404s - eg. unknown src, tgt, assoc of given type
|
||||
tgt = new AssocTarget(o1Id, "cm:unknowntype");
|
||||
post(getNodeTargetsUrl(o2Id), user1, toJsonAsStringNonNull(tgt), 400);
|
||||
}
|
||||
|
||||
//
|
||||
// -ve test - list assocs
|
||||
//
|
||||
|
||||
{
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
getAll(getNodeTargetsUrl(f1Id), null, paging, null, 401);
|
||||
getAll(getNodeSourcesUrl(f1Id), null, paging, null, 401);
|
||||
|
||||
getAll(getNodeTargetsUrl(UUID.randomUUID().toString()), user1, paging, null, 404);
|
||||
getAll(getNodeSourcesUrl(UUID.randomUUID().toString()), user1, paging, null, 404);
|
||||
|
||||
params = new HashMap<>(1);
|
||||
params.put("where", "(assocType='cm:unknownassoctype')");
|
||||
|
||||
getAll(getNodeTargetsUrl(o1Id), user1, paging, params, 400);
|
||||
getAll(getNodeSourcesUrl(o1Id), user1, paging, params, 400);
|
||||
|
||||
// TODO paging - in-built sort order ?
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// -ve test - remove assoc(s)
|
||||
//
|
||||
|
||||
{
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
delete(getNodeTargetsUrl(o1Id), null, o2Id, 401);
|
||||
|
||||
delete(getNodeTargetsUrl(UUID.randomUUID().toString()), user1, o2Id, null, 404);
|
||||
delete(getNodeTargetsUrl(o1Id), user1, UUID.randomUUID().toString(), null, 404);
|
||||
|
||||
// -ve test -nothing to delete - for any assoc type
|
||||
delete(getNodeTargetsUrl(o1Id), user1, o2Id, null, 404);
|
||||
|
||||
// -ve test - nothing to delete - for given assoc type
|
||||
params = new HashMap<>(2);
|
||||
params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_REFERENCES);
|
||||
delete(getNodeTargetsUrl(o1Id), user1, o2Id, params, 404);
|
||||
|
||||
// -ve test - unknown assoc type
|
||||
params = new HashMap<>(2);
|
||||
params.put(PARAM_ASSOC_TYPE, "cm:unknowntype");
|
||||
delete(getNodeTargetsUrl(o1Id), user1, o2Id, params, 400);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -469,10 +501,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
|
||||
Paging paging = getPaging(0, 100);
|
||||
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
getAll(getNodeSecondaryChildrenUrl(f1Id), null, paging, null, 401);
|
||||
getAll(getNodeParentsUrl(o2Id), null, paging, null, 401);
|
||||
|
||||
// lists - before
|
||||
|
||||
response = getAll(getNodeSecondaryChildrenUrl(f1Id), user1, paging, null, 200);
|
||||
@@ -485,22 +513,14 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
assertEquals(1, nodes.size());
|
||||
assertEquals(f2Id, nodes.get(0).getId());
|
||||
assertEquals(ASSOC_TYPE_CM_CONTAINS, nodes.get(0).getAssociation().getAssocType());
|
||||
assertEquals("cm:"+o2Name, nodes.get(0).getAssociation().getChildQName());
|
||||
assertTrue(nodes.get(0).getAssociation().getIsPrimaryParent());
|
||||
|
||||
String o2SecChildName = "cm:o2SecChildName";
|
||||
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
AssocChild secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName);
|
||||
post(getNodeSecondaryChildrenUrl(f1Id), null, toJsonAsStringNonNull(secChild), 401);
|
||||
|
||||
|
||||
// create secondary child assoc
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName);
|
||||
AssocChild secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS);
|
||||
post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 201);
|
||||
|
||||
// create ano' secondary child assoc (different type) between the same two nodes
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_PREFERENCE_IMAGE, o2SecChildName);
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_PREFERENCE_IMAGE);
|
||||
post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 201);
|
||||
|
||||
|
||||
@@ -520,7 +540,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
i++;
|
||||
}
|
||||
assertEquals(o2Id, node.getId());
|
||||
assertEquals(o2SecChildName, nodeAssoc.getChildQName());
|
||||
assertFalse(nodeAssoc.getIsPrimaryParent());
|
||||
}
|
||||
assertEquals(2, i);
|
||||
@@ -536,7 +555,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
if (nodeId.equals(f2Id))
|
||||
{
|
||||
assertEquals(ASSOC_TYPE_CM_CONTAINS, nodeAssoc.getAssocType());
|
||||
assertEquals("cm:"+o2Name, nodeAssoc.getChildQName());
|
||||
assertTrue(nodeAssoc.getIsPrimaryParent());
|
||||
i++;
|
||||
}
|
||||
@@ -550,7 +568,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
{
|
||||
i++;
|
||||
}
|
||||
assertEquals(o2SecChildName, nodeAssoc.getChildQName());
|
||||
assertFalse(nodeAssoc.getIsPrimaryParent());
|
||||
}
|
||||
}
|
||||
@@ -577,14 +594,12 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
if (nodeId.equals(f2Id))
|
||||
{
|
||||
assertEquals(ASSOC_TYPE_CM_CONTAINS, nodeAssoc.getAssocType());
|
||||
assertEquals("cm:"+o2Name, nodeAssoc.getChildQName());
|
||||
assertTrue(nodeAssoc.getIsPrimaryParent());
|
||||
i++;
|
||||
}
|
||||
else if (nodeId.equals(f1Id))
|
||||
{
|
||||
assertEquals(ASSOC_TYPE_CM_CONTAINS, nodeAssoc.getAssocType());
|
||||
assertEquals(o2SecChildName, nodeAssoc.getChildQName());
|
||||
assertFalse(nodeAssoc.getIsPrimaryParent());
|
||||
i++;
|
||||
}
|
||||
@@ -611,10 +626,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
|
||||
params = new HashMap<>(2);
|
||||
params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_CONTAINS);
|
||||
params.put(PARAM_CHILD_NAME, o2SecChildName);
|
||||
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), null, o2Id, params, 401);
|
||||
|
||||
// remove one secondary child assoc
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, params, 204);
|
||||
@@ -629,7 +640,6 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
|
||||
params = new HashMap<>(2);
|
||||
params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_PREFERENCE_IMAGE);
|
||||
params.put(PARAM_CHILD_NAME, o2SecChildName);
|
||||
|
||||
// remove other secondary child assoc
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, params, 204);
|
||||
@@ -642,26 +652,83 @@ public class NodeAssociationsApiTest extends AbstractBaseApiTest
|
||||
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||
assertEquals(1, nodes.size());
|
||||
|
||||
// TODO test delete of multiple secondary child assocs (if assoc type is not specified)
|
||||
// TODO +ve test delete of multiple secondary child assocs (if assoc type is not specified)
|
||||
|
||||
//
|
||||
// -ve tests - add assoc
|
||||
//
|
||||
|
||||
{
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS);
|
||||
post(getNodeSecondaryChildrenUrl(f1Id), null, toJsonAsStringNonNull(secChild), 401);
|
||||
|
||||
// -ve test - model integrity
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName);
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS);
|
||||
post(getNodeSecondaryChildrenUrl(o1Id), user1, toJsonAsStringNonNull(secChild), 422);
|
||||
|
||||
// -ve test - duplicate assoc
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS, o2SecChildName);
|
||||
secChild = new AssocChild(o2Id, ASSOC_TYPE_CM_CONTAINS);
|
||||
post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 201);
|
||||
post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 409);
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, null, 204); // cleanup
|
||||
|
||||
// TODO some more negative tests
|
||||
// 400s - eg. invalid qname
|
||||
// 404s - eg. unknown src, tgt, assoc of given type
|
||||
secChild = new AssocChild(o2Id, "cm:unknowntype");
|
||||
post(getNodeSecondaryChildrenUrl(f1Id), user1, toJsonAsStringNonNull(secChild), 400);
|
||||
}
|
||||
|
||||
//
|
||||
// -ve test - list assocs
|
||||
//
|
||||
|
||||
{
|
||||
// -ve test - unauthenticated - belts-and-braces ;-)
|
||||
getAll(getNodeSecondaryChildrenUrl(f1Id), null, paging, null, 401);
|
||||
getAll(getNodeParentsUrl(o2Id), null, paging, null, 401);
|
||||
|
||||
getAll(getNodeSecondaryChildrenUrl(UUID.randomUUID().toString()), user1, paging, null, 404);
|
||||
getAll(getNodeParentsUrl(UUID.randomUUID().toString()), user1, paging, null, 404);
|
||||
|
||||
params = new HashMap<>(1);
|
||||
params.put("where", "(assocType='cm:unknownassoctype')");
|
||||
|
||||
getAll(getNodeSecondaryChildrenUrl(o1Id), user1, paging, params, 400);
|
||||
getAll(getNodeParentsUrl(o1Id), user1, paging, params, 400);
|
||||
|
||||
// TODO paging - in-built sort order ?
|
||||
}
|
||||
|
||||
//
|
||||
// -ve test - remove assoc(s)
|
||||
//
|
||||
|
||||
{
|
||||
// unauthenticated - belts-and-braces ;-)
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), null, o2Id, null, 401);
|
||||
|
||||
delete(getNodeSecondaryChildrenUrl(UUID.randomUUID().toString()), user1, o2Id, null, 404);
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), user1, UUID.randomUUID().toString(), null, 404);
|
||||
|
||||
// nothing to delete - for any assoc type
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, null, 404);
|
||||
|
||||
// nothing to delete - for given assoc type
|
||||
params = new HashMap<>(2);
|
||||
params.put(PARAM_ASSOC_TYPE, ASSOC_TYPE_CM_PREFERENCE_IMAGE);
|
||||
delete(getNodeSecondaryChildrenUrl(f1Id), user1, o2Id, params, 404);
|
||||
|
||||
// unknown assoc type
|
||||
params = new HashMap<>(2);
|
||||
params.put(PARAM_ASSOC_TYPE, "cm:unknowntype");
|
||||
delete(getNodeSecondaryChildrenUrl(o1Id), user1, o2Id, params, 400);
|
||||
|
||||
// TODO 400 - try to delete primary assoc using /secondary-children
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// some cleanup
|
||||
Map<String, String> params = Collections.singletonMap("permanent", "true");
|
||||
Map<String, String> params = Collections.singletonMap(Nodes.PARAM_PERMANENT, "true");
|
||||
delete(URL_NODES, user1, f1Id, params, 204);
|
||||
delete(URL_NODES, user1, f2Id, params, 204);
|
||||
}
|
||||
|
@@ -34,19 +34,8 @@ public class Association
|
||||
}
|
||||
|
||||
// child assoc
|
||||
private String prefixAssocChildQName;
|
||||
private Boolean isPrimaryParent;
|
||||
|
||||
public String getChildQName()
|
||||
{
|
||||
return prefixAssocChildQName;
|
||||
}
|
||||
|
||||
public void setChildQName(String prefixAssocChildQName)
|
||||
{
|
||||
this.prefixAssocChildQName = prefixAssocChildQName;
|
||||
}
|
||||
|
||||
public Boolean getIsPrimaryParent()
|
||||
{
|
||||
return isPrimaryParent;
|
||||
|
Reference in New Issue
Block a user