From 61c2f1a614ee84e1523c921581bd196422e2e8bb Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Tue, 2 Jan 2007 14:25:16 +0000 Subject: [PATCH] Added removeChildAssociation method to NodeService git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4706 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/repo/avm/AVMNodeService.java | 35 +++++++++++ .../repo/domain/hibernate/Node.hbm.xml | 15 +++++ .../repo/node/BaseNodeServiceTest.java | 25 ++++++++ .../repo/node/db/DbNodeServiceImpl.java | 17 +++++ .../alfresco/repo/node/db/NodeDaoService.java | 11 ++++ .../HibernateNodeDaoServiceImpl.java | 63 +++++++++++++------ .../repo/version/NodeServiceImpl.java | 34 ++++++---- .../service/cmr/repository/NodeService.java | 13 +++- 8 files changed, 179 insertions(+), 34 deletions(-) diff --git a/source/java/org/alfresco/repo/avm/AVMNodeService.java b/source/java/org/alfresco/repo/avm/AVMNodeService.java index 8c091af26b..cc4469c87f 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeService.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeService.java @@ -885,6 +885,41 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi } } + /** + * TODO: Check implementation + */ + public boolean removeChildAssociation(ChildAssociationRef childAssocRef) + { + NodeRef parentRef = childAssocRef.getParentRef(); + NodeRef childRef = childAssocRef.getChildRef(); + Pair parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); + if (parentVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", parentRef); + } + Pair childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef); + if (childVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", childRef); + } + String parentPath = parentVersionPath.getSecond(); + String childPath = childVersionPath.getSecond(); + String [] childPathBase = AVMNodeConverter.SplitBase(childPath); + if (childPathBase[0] == null || !childPathBase[0].equals(parentPath)) + { + return false; + } + try + { + fAVMService.removeNode(childPathBase[0], childPathBase[1]); + return true; + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException("Not found.", childRef); + } + } + /** * @param nodeRef * @return Returns all properties keyed by their qualified name diff --git a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml index cf0a22b2fa..148838c39c 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml +++ b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml @@ -244,6 +244,21 @@ ) + + select + assoc + from + org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc + where + assoc.parent.id = :parentId and + assoc.child.id = :childId and + assoc.typeQName = :typeQName and + assoc.qname = :qname + order by + assoc.index, + assoc.id + + select assoc diff --git a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java index 7c616bba95..0059e3eaa2 100644 --- a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java +++ b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java @@ -816,6 +816,31 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest // expected } } + + public void testRemoveSpecificChild() throws Exception + { + NodeRef parentRef = nodeService.createNode( + rootNodeRef, + ASSOC_TYPE_QNAME_TEST_CHILDREN, + QName.createQName("parent_child"), + ContentModel.TYPE_CONTAINER).getChildRef(); + ChildAssociationRef pathARef = nodeService.createNode( + parentRef, + ASSOC_TYPE_QNAME_TEST_CHILDREN, + QName.createQName("pathA"), + ContentModel.TYPE_CONTAINER); + ChildAssociationRef pathBRef = nodeService.addChild( + parentRef, + pathARef.getChildRef(), + ASSOC_TYPE_QNAME_TEST_CHILDREN, + QName.createQName("pathB")); + + // now remove the second association + boolean removed = nodeService.removeChildAssociation(pathBRef); + assertTrue("Association was not removed", removed); + removed = nodeService.removeChildAssociation(pathBRef); + assertFalse("Non-existent association was apparently removed", removed); + } public void testRemoveChildByRef() throws Exception { diff --git a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java index 184a895833..5603adacaa 100644 --- a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java @@ -771,6 +771,23 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl // done } + public boolean removeChildAssociation(ChildAssociationRef childAssocRef) + { + Node parentNode = getNodeNotNull(childAssocRef.getParentRef()); + Node childNode = getNodeNotNull(childAssocRef.getChildRef()); + QName typeQName = childAssocRef.getTypeQName(); + QName qname = childAssocRef.getQName(); + // Delete the association + invokeBeforeDeleteChildAssociation(childAssocRef); + boolean deleted = nodeDaoService.deleteChildAssoc(parentNode, childNode, typeQName, qname); + if (deleted) + { + invokeOnDeleteChildAssociation(childAssocRef); + } + // Done + return deleted; + } + /** * Remove properties that should not be persisted as general properties. Where necessary, the * properties are set on the node. diff --git a/source/java/org/alfresco/repo/node/db/NodeDaoService.java b/source/java/org/alfresco/repo/node/db/NodeDaoService.java index 1984eb1a15..98c306efaf 100644 --- a/source/java/org/alfresco/repo/node/db/NodeDaoService.java +++ b/source/java/org/alfresco/repo/node/db/NodeDaoService.java @@ -189,6 +189,17 @@ public interface NodeDaoService */ public ChildAssoc getChildAssoc(Node parentNode, QName assocTypeQName, String childName); + /** + * Deletes an explicit child association. + * + * @return Returns true if the association was deleted, otherwise false + */ + public boolean deleteChildAssoc( + final Node parentNode, + final Node childNode, + final QName assocTypeQName, + final QName qname); + /** * @param assoc the child association to remove * @param cascade true if the assoc deletions must cascade to primary child nodes diff --git a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java index 3f9a39d858..ea51bab0e2 100644 --- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java @@ -85,6 +85,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements private static final String UPDATE_SET_CHILD_ASSOC_NAME = "node.updateChildAssocName"; private static final String QUERY_GET_PRIMARY_CHILD_NODE_STATUSES = "node.GetPrimaryChildNodeStatuses"; private static final String QUERY_GET_CHILD_ASSOCS = "node.GetChildAssocs"; + private static final String QUERY_GET_CHILD_ASSOCS_BY_ALL = "node.GetChildAssocsByAll"; private static final String QUERY_GET_CHILD_ASSOC_BY_TYPE_AND_NAME = "node.GetChildAssocByTypeAndName"; private static final String QUERY_GET_CHILD_ASSOC_REFS = "node.GetChildAssocRefs"; private static final String QUERY_GET_CHILD_ASSOC_REFS_BY_QNAME = "node.GetChildAssocRefsByQName"; @@ -758,33 +759,55 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements } public ChildAssoc getChildAssoc( - Node parentNode, - Node childNode, - QName assocTypeQName, - QName qname) + final Node parentNode, + final Node childNode, + final QName assocTypeQName, + final QName qname) { - ChildAssociationRef childAssocRef = new ChildAssociationRef( - assocTypeQName, - parentNode.getNodeRef(), - qname, - childNode.getNodeRef()); - // get all the parent's child associations - Collection assocs = getChildAssocs(parentNode); - // hunt down the desired assoc - for (ChildAssoc assoc : assocs) + HibernateCallback callback = new HibernateCallback() { - // is it a match? - if (!assoc.getChildAssocRef().equals(childAssocRef)) // not a match + public Object doInHibernate(Session session) { - continue; + Query query = session + .getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_CHILD_ASSOCS_BY_ALL) + .setLong("parentId", parentNode.getId()) + .setLong("childId", childNode.getId()) + .setParameter("typeQName", assocTypeQName) + .setParameter("qname", qname); + return query.uniqueResult(); } - else + }; + ChildAssoc childAssoc = (ChildAssoc) getHibernateTemplate().execute(callback); + return childAssoc; + } + + @SuppressWarnings("unchecked") + public boolean deleteChildAssoc( + final Node parentNode, + final Node childNode, + final QName assocTypeQName, + final QName qname) + { + HibernateCallback callback = new HibernateCallback() + { + public Object doInHibernate(Session session) { - return assoc; + Query query = session + .getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_CHILD_ASSOCS_BY_ALL) + .setLong("parentId", parentNode.getId()) + .setLong("childId", childNode.getId()) + .setParameter("typeQName", assocTypeQName) + .setParameter("qname", qname); + return query.list(); } + }; + List childAssocs = (List) getHibernateTemplate().execute(callback); + // Remove each child association with full cascade + for (ChildAssoc assoc : childAssocs) + { + deleteChildAssoc(assoc, true); } - // not found - return null; + return (childAssocs.size() > 0); } public ChildAssoc getChildAssoc(final Node parentNode, final QName assocTypeQName, final String childName) diff --git a/source/java/org/alfresco/repo/version/NodeServiceImpl.java b/source/java/org/alfresco/repo/version/NodeServiceImpl.java index c7d73b6468..30e3c95b0e 100644 --- a/source/java/org/alfresco/repo/version/NodeServiceImpl.java +++ b/source/java/org/alfresco/repo/version/NodeServiceImpl.java @@ -181,7 +181,7 @@ public class NodeServiceImpl implements NodeService, VersionModel QName assocQName, QName nodeTypeQName) throws InvalidNodeRefException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -195,7 +195,7 @@ public class NodeServiceImpl implements NodeService, VersionModel QName nodeTypeQName, Map properties) throws InvalidNodeRefException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -204,7 +204,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public void deleteNode(NodeRef nodeRef) throws InvalidNodeRefException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -216,7 +216,7 @@ public class NodeServiceImpl implements NodeService, VersionModel QName assocTypeQName, QName qname) throws InvalidNodeRefException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -225,7 +225,15 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public void removeChild(NodeRef parentRef, NodeRef childRef) throws InvalidNodeRefException { - // This operation is not supported for a verion store + // This operation is not supported for a version store + throw new UnsupportedOperationException(MSG_UNSUPPORTED); + } + + /** + * @throws UnsupportedOperationException always + */ + public boolean removeChildAssociation(ChildAssociationRef childAssocRef) + { throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -267,7 +275,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public void addAspect(NodeRef nodeRef, QName aspectRef, Map aspectProperties) throws InvalidNodeRefException, InvalidAspectException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -284,7 +292,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public void removeAspect(NodeRef nodeRef, QName aspectRef) throws InvalidNodeRefException, InvalidAspectException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -347,7 +355,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public void setProperties(NodeRef nodeRef, Map properties) throws InvalidNodeRefException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -356,7 +364,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public void setProperty(NodeRef nodeRef, QName qame, Serializable value) throws InvalidNodeRefException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -447,7 +455,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public NodeRef getChildByName(NodeRef nodeRef, QName assocTypeQName, String childName) { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -469,7 +477,7 @@ public class NodeServiceImpl implements NodeService, VersionModel public AssociationRef createAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) throws InvalidNodeRefException, AssociationExistsException { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -478,7 +486,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } @@ -516,7 +524,7 @@ public class NodeServiceImpl implements NodeService, VersionModel */ public List getSourceAssocs(NodeRef sourceRef, QNamePattern qnamePattern) { - // This operation is not supported for a verion store + // This operation is not supported for a version store throw new UnsupportedOperationException(MSG_UNSUPPORTED); } diff --git a/source/java/org/alfresco/service/cmr/repository/NodeService.java b/source/java/org/alfresco/service/cmr/repository/NodeService.java index 4398cfd981..e8d4ae53dc 100644 --- a/source/java/org/alfresco/service/cmr/repository/NodeService.java +++ b/source/java/org/alfresco/service/cmr/repository/NodeService.java @@ -314,12 +314,23 @@ public interface NodeService * * @param parentRef the parent end of the association * @param childRef the child end of the association - * @return Returns a collection of deleted entities - both associations and node references. * @throws InvalidNodeRefException if the parent or child nodes could not be found */ @Auditable(key = Auditable.Key.ARG_0 ,parameters = {"parentRef", "childRef"}) public void removeChild(NodeRef parentRef, NodeRef childRef) throws InvalidNodeRefException; + /** + * Remove a specific child association. + *

+ * The child node will be cascade deleted if the association was the + * primary association, i.e. the one with which the child node was created. + * + * @param childAssocRef the association to remove + * @return Returns true if the association existed, otherwise false. + */ + @Auditable(key = Auditable.Key.ARG_0 ,parameters = {"childAssocRef"}) + public boolean removeChildAssociation(ChildAssociationRef childAssocRef); + /** * @param nodeRef * @return Returns all properties keyed by their qualified name