From 8e56ad390cd06672e92f420ad60fe03661c9ac96 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Thu, 28 Sep 2006 20:19:48 +0000 Subject: [PATCH] Added missing callbacks to AVMNodeService. This makes things slow. Have to do something about that. Added getPaths call to AVMService. Retrieves all possible paths to a node. Need to do timing tests. I believe, the 6th version of a Pair template class. This one's public and perhaps when we have time we could use it in place of all the inner class implementations. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3964 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/repo/avm/AVMNodeService.java | 72 ++++++++++++++----- .../org/alfresco/repo/avm/AVMRepository.java | 71 ++++++++++++++++++ .../org/alfresco/repo/avm/AVMServiceImpl.java | 16 +++++ .../org/alfresco/repo/avm/AVMServiceTest.java | 27 +++++++ .../org/alfresco/repo/avm/AVMStoreDAO.java | 7 ++ .../org/alfresco/repo/avm/ChildEntryDAO.java | 7 ++ .../org/alfresco/repo/avm/VersionRootDAO.java | 7 ++ .../avm/actions/SimpleAVMSubmitAction.java | 1 - .../avm/hibernate/AVMStoreDAOHibernate.java | 16 ++++- .../avm/hibernate/ChildEntryDAOHibernate.java | 14 ++++ .../hibernate/VersionRootDAOHibernate.java | 16 ++++- .../alfresco/service/cmr/avm/AVMService.java | 8 +++ 12 files changed, 243 insertions(+), 19 deletions(-) diff --git a/source/java/org/alfresco/repo/avm/AVMNodeService.java b/source/java/org/alfresco/repo/avm/AVMNodeService.java index a049f75a36..e33bacb985 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeService.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeService.java @@ -285,7 +285,7 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi throw new InvalidTypeException("Invalid node type for AVM.", nodeTypeQName); } addDefaultPropertyValues(nodeTypeDef, properties); - // TODO Add default aspects to the child.. + addDefaultAspects(nodeTypeDef, avmPath, properties); } catch (AVMNotFoundException e) { @@ -318,8 +318,10 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi -1); invokeOnCreateNode(ref); invokeOnUpdateNode(parentRef); - // TODO invokeOnUpdateProperties - + if (properties.size() != 0) + { + invokeOnUpdateProperties(childRef, new HashMap(), properties); + } return ref; } @@ -388,19 +390,37 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi String dstParent = (String)dst[1]; String dstName = assocQName.getLocalName(); // TODO Invoke policy behavior. Not quite sure how to translate this. + NodeRef oldParentRef = AVMNodeConverter.ToNodeRef(-1, srcParent); + ChildAssociationRef oldAssocRef = + new ChildAssociationRef(assocTypeQName, + oldParentRef, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, srcName), + nodeToMoveRef, + true, + -1); + invokeBeforeDeleteChildAssociation(oldAssocRef); + String dstPath = AVMNodeConverter.ExtendAVMPath(dstParent, dstName); + NodeRef newChildRef = AVMNodeConverter.ToNodeRef(-1, dstPath); + invokeBeforeCreateChildAssociation(newParentRef, newChildRef, assocTypeQName, assocQName); + invokeBeforeUpdateNode(oldParentRef); + invokeBeforeUpdateNode(newParentRef); // Actually perform the rename and return a pseudo // ChildAssociationRef. try { fAVMService.rename(srcParent, srcName, dstParent, dstName); - String dstPath = AVMNodeConverter.ExtendAVMPath(dstParent, dstName); - // TODO Invoke policy behaviors. Not sure how to translate that. - return new ChildAssociationRef(assocTypeQName, - newParentRef, - assocQName, - AVMNodeConverter.ToNodeRef(-1, dstPath), - true, - -1); + ChildAssociationRef newAssocRef = + new ChildAssociationRef(assocTypeQName, + newParentRef, + assocQName, + newChildRef, + true, + -1); + invokeOnCreateChildAssociation(newAssocRef); + invokeOnDeleteChildAssociation(oldAssocRef); + invokeOnUpdateNode(oldParentRef); + invokeOnUpdateNode(newParentRef); + return newAssocRef; } catch (AVMNotFoundException e) { @@ -739,9 +759,16 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi } try { + QName nodeTypeQName = getType(nodeRef); + Set aspects = getAspects(nodeRef); fAVMService.removeNode(avmPathBase[0], avmPathBase[1]); - // Invoke policy behaviors. - // TODO invokeOnDeleteNode() Need to fake up ChildAssocRef. + ChildAssociationRef childAssocRef = + new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, + AVMNodeConverter.ToNodeRef(-1, avmPathBase[0]), + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + avmPathBase[1]), + nodeRef); + invokeOnDeleteNode(childAssocRef, nodeTypeQName, aspects, false); } catch (AVMNotFoundException e) { @@ -767,6 +794,8 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi QName assocTypeQName, QName qname) throws InvalidNodeRefException { + // TODO This can be supported theoretically. I'm not sure if + // the link operation is semantically equivalent. throw new UnsupportedOperationException("addChild: unsupported"); } @@ -803,9 +832,16 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi } try { + ChildAssociationRef assocRef = + new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, + AVMNodeConverter.ToNodeRef(-1, parentPath), + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + childPathBase[1]), + AVMNodeConverter.ToNodeRef(-1, childPath)); + invokeBeforeDeleteChildAssociation(assocRef); fAVMService.removeNode(childPathBase[0], childPathBase[1]); - // Invoke policy behaviors. - // TODO Need to fake up ChildAssocRef. + invokeOnDeleteChildAssociation(assocRef); + invokeOnUpdateNode(AVMNodeConverter.ToNodeRef(-1, parentPath)); } catch (AVMNotFoundException e) { @@ -1027,6 +1063,7 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi { // Invoke policy behaviors. invokeBeforeUpdateNode(nodeRef); + Map oldProps = getProperties(nodeRef); fAVMService.deleteNodeProperties((String)avmVersionPath[1]); Map values = new HashMap(); for (QName qName : properties.keySet()) @@ -1053,6 +1090,7 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi fAVMService.setNodeProperties((String)avmVersionPath[1], values); // Invoke policy behaviors. invokeOnUpdateNode(nodeRef); + invokeOnUpdateProperties(nodeRef, oldProps, properties); } catch (AVMNotFoundException e) { @@ -1115,7 +1153,6 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi { throw new InvalidNodeRefException("Read only store.", nodeRef); } - // TODO Just until we can set built in properties on AVM Nodes. if (isBuiltInProperty(qname)) { if (qname.equals(ContentModel.PROP_CONTENT)) @@ -1133,9 +1170,12 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi } try { + Map propsBefore = getProperties(nodeRef); fAVMService.setNodeProperty((String)avmVersionPath[1], qname, new PropertyValue(null, value)); + Map propsAfter = getProperties(nodeRef); // Invoke policy behaviors. invokeOnUpdateNode(nodeRef); + invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); } catch (AVMNotFoundException e) { diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index 5d22bc6370..13684fa579 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -41,6 +41,7 @@ import org.alfresco.service.cmr.avm.LayeringDescriptor; import org.alfresco.service.cmr.avm.VersionDescriptor; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.namespace.QName; +import org.alfresco.util.Pair; import org.apache.log4j.Logger; /** @@ -923,6 +924,76 @@ public class AVMRepository return dirNode.lookupChild(dir, name, includeDeleted); } + /** + * Get all the paths to a particular node. + * @param desc The node descriptor. + * @return The list of version, paths. + */ + public List> getPaths(AVMNodeDescriptor desc) + { + AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(desc.getId()); + List> paths = new ArrayList>(); + List components = new ArrayList(); + recursiveGetPaths(node, components, paths); + return paths; + } + + private void recursiveGetPaths(AVMNode node, List components, + List> paths) + { + if (node.getIsRoot()) + { + AVMStore store = AVMContext.fgInstance.fAVMStoreDAO.getByRoot(node); + if (store != null) + { + addPath(components, -1, store.getName(), paths); + return; + } + VersionRoot vr = AVMContext.fgInstance.fVersionRootDAO.getByRoot(node); + if (vr != null) + { + addPath(components, vr.getVersionID(), vr.getAvmStore().getName(), paths); + } + return; + } + List entries = AVMContext.fgInstance.fChildEntryDAO.getByChild(node); + for (ChildEntry entry : entries) + { + String name = entry.getName(); + components.add(name); + AVMNode parent = entry.getParent(); + recursiveGetPaths(parent, components, paths); + components.remove(components.size() - 1); + } + } + + /** + * Add a path to the list. + * @param components The path name components. + * @param version The version id. + * @param storeName The name of the + * @param paths The List to add to. + */ + private void addPath(List components, int version, String storeName, + List> paths) + { + StringBuilder pathBuilder = new StringBuilder(); + pathBuilder.append(storeName); + pathBuilder.append(":"); + if (components.size() == 0) + { + pathBuilder.append("/"); + paths.add(new Pair(version, pathBuilder.toString())); + return; + } + for (int i = components.size() - 1; i >= 0; i--) + { + pathBuilder.append("/"); + pathBuilder.append(components.get(i)); + } + paths.add(new Pair(version, pathBuilder.toString())); + } + /** * Get information about layering of a path. * @param version The version to look under. diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index b8f7b4e0e8..dafc8a2b32 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -41,6 +41,7 @@ import org.alfresco.service.cmr.avm.LayeringDescriptor; import org.alfresco.service.cmr.avm.VersionDescriptor; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.namespace.QName; +import org.alfresco.util.Pair; import org.alfresco.util.TempFileProvider; import org.apache.log4j.Logger; @@ -567,6 +568,21 @@ public class AVMServiceImpl implements AVMService } } + /** + * Get a list of all paths that a given node has. + * @param desc The node descriptor to get paths for. + * @return A List of version, path Pairs. + */ + public List> getPaths(AVMNodeDescriptor desc) + { + if (desc == null) + { + throw new AVMBadArgumentException("Descriptor is null."); + } + return fAVMRepository.getPaths(desc); + } + + /** * Purge an AVMStore. Permanently delete everything that * is only referenced in that AVMStore. diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index 1bedfb4431..fa82bf45e5 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -56,6 +56,7 @@ import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.GUID; +import org.alfresco.util.Pair; /** * Big test of AVM behavior. @@ -63,6 +64,31 @@ import org.alfresco.util.GUID; */ public class AVMServiceTest extends AVMServiceTestBase { + /** + * Test getting all paths for a node. + * + */ + public void testGetPaths() + { + try + { + setupBasicTree(); + fService.createBranch(-1, "main:/a", "main:/", "abranch"); + fService.createSnapshot("main"); + fService.createBranch(-1, "main:/a/b", "main:/", "bbranch"); + List> paths = fService.getPaths(fService.lookup(-1, "main:/a/b/c/foo")); + for (Pair path : paths) + { + System.out.println(path.getFirst() + " " + path.getSecond()); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + fail(); + } + } + /** * Test partial flatten. */ @@ -85,6 +111,7 @@ public class AVMServiceTest extends AVMServiceTestBase assertTrue(b.isLayeredDirectory()); AVMNodeDescriptor c = fService.lookup(-1, "layer:/a/b/c"); assertTrue(c.isPlainDirectory()); + assertEquals(1, fSyncService.compare(-1, "layer:/a", -1, "main:/a").size()); } catch (Exception e) { diff --git a/source/java/org/alfresco/repo/avm/AVMStoreDAO.java b/source/java/org/alfresco/repo/avm/AVMStoreDAO.java index 305968f226..ca291fb0d0 100644 --- a/source/java/org/alfresco/repo/avm/AVMStoreDAO.java +++ b/source/java/org/alfresco/repo/avm/AVMStoreDAO.java @@ -50,6 +50,13 @@ public interface AVMStoreDAO */ public AVMStore getByName(String name); + /** + * Get the AVM Store that has the given root as HEAD. + * @param root The root to query. + * @return The matching store or null. + */ + public AVMStore getByRoot(AVMNode root); + /** * Update the given AVMStore record. * @param rep The dirty AVMStore. diff --git a/source/java/org/alfresco/repo/avm/ChildEntryDAO.java b/source/java/org/alfresco/repo/avm/ChildEntryDAO.java index 6420cfd514..a1797e7f0d 100644 --- a/source/java/org/alfresco/repo/avm/ChildEntryDAO.java +++ b/source/java/org/alfresco/repo/avm/ChildEntryDAO.java @@ -54,6 +54,13 @@ public interface ChildEntryDAO */ public ChildEntry getByParentChild(DirectoryNode parent, AVMNode child); + /** + * Get all the ChildEntries corresponding to the given child. + * @param child The child for which to look up entries. + * @return The matching entries. + */ + public List getByChild(AVMNode child); + /** * Update a dirty ChildEntry. * @param child The dirty entry. diff --git a/source/java/org/alfresco/repo/avm/VersionRootDAO.java b/source/java/org/alfresco/repo/avm/VersionRootDAO.java index af8cf55c39..0c679b5b9d 100644 --- a/source/java/org/alfresco/repo/avm/VersionRootDAO.java +++ b/source/java/org/alfresco/repo/avm/VersionRootDAO.java @@ -53,6 +53,13 @@ public interface VersionRootDAO */ public VersionRoot getByVersionID(AVMStore store, int id); + /** + * Get one from its root. + * @param root The root to match. + * @return The version root or null. + */ + public VersionRoot getByRoot(AVMNode root); + /** * Get the version of a store by dates. * @param store The store. diff --git a/source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java b/source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java index e645fcbcee..1b954b1197 100644 --- a/source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java +++ b/source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java @@ -92,7 +92,6 @@ public class SimpleAVMSubmitAction extends ActionExecuterAbstractBase Object [] avmVersionPath = AVMNodeConverter.ToAVMVersionPath(actionedUponNodeRef); int version = (Integer)avmVersionPath[0]; String path = (String)avmVersionPath[1]; - fgLogger.error(path); // Get store name and path parts. String [] storePath = path.split(":"); if (storePath.length != 2) diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVMStoreDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/AVMStoreDAOHibernate.java index 45c632ccd9..41b3476300 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/AVMStoreDAOHibernate.java +++ b/source/java/org/alfresco/repo/avm/hibernate/AVMStoreDAOHibernate.java @@ -19,6 +19,7 @@ package org.alfresco.repo.avm.hibernate; import java.util.List; +import org.alfresco.repo.avm.AVMNode; import org.alfresco.repo.avm.AVMStore; import org.alfresco.repo.avm.AVMStoreDAO; import org.alfresco.repo.avm.AVMStoreImpl; @@ -78,7 +79,20 @@ class AVMStoreDAOHibernate extends HibernateDaoSupport implements { return (AVMStore)getSession().get(AVMStoreImpl.class, name); } - + + /** + * Get the AVM Store that has the given root as HEAD. + * @param root The root to query. + * @return The matching store or null. + */ + public AVMStore getByRoot(AVMNode root) + { + Query query = getSession().createQuery("from AVMStoreImpl st " + + "where st.root = :root"); + query.setEntity("root", root); + return (AVMStore)query.uniqueResult(); + } + /** * Update the given AVMStore record. * @param store The dirty AVMStore. diff --git a/source/java/org/alfresco/repo/avm/hibernate/ChildEntryDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/ChildEntryDAOHibernate.java index da53e3ef74..47695a9208 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/ChildEntryDAOHibernate.java +++ b/source/java/org/alfresco/repo/avm/hibernate/ChildEntryDAOHibernate.java @@ -92,6 +92,20 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements return (ChildEntry)query.uniqueResult(); } + /** + * Get all the ChildEntries corresponding to the given child. + * @param child The child for which to look up entries. + * @return The matching entries. + */ + @SuppressWarnings("unchecked") + public List getByChild(AVMNode child) + { + Query query = getSession().createQuery("from ChildEntryImpl ce " + + "where ce.child = :child"); + query.setEntity("child", child); + return (List)query.list(); + } + /** * Update a dirty ChildEntry. * @param child The dirty entry. diff --git a/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java index d7a22ff2e7..d2be18aa79 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java +++ b/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java @@ -20,6 +20,7 @@ package org.alfresco.repo.avm.hibernate; import java.util.Date; import java.util.List; +import org.alfresco.repo.avm.AVMNode; import org.alfresco.repo.avm.AVMStore; import org.alfresco.repo.avm.VersionRoot; import org.alfresco.repo.avm.VersionRootDAO; @@ -128,7 +129,20 @@ class VersionRootDAOHibernate extends HibernateDaoSupport implements query.setInteger("version", id); return (VersionRoot)query.uniqueResult(); } - + + /** + * Get one from its root. + * @param root The root to match. + * @return The version root or null. + */ + public VersionRoot getByRoot(AVMNode root) + { + Query query = getSession().createQuery("from VersionRootImpl vr " + + "where vr.root = :root"); + query.setEntity("root", root); + return (VersionRoot)query.uniqueResult(); + } + /** * Get the highest numbered version in a repository. * @param rep The repository. diff --git a/source/java/org/alfresco/service/cmr/avm/AVMService.java b/source/java/org/alfresco/service/cmr/avm/AVMService.java index dc55f0a879..2d0eac10fa 100644 --- a/source/java/org/alfresco/service/cmr/avm/AVMService.java +++ b/source/java/org/alfresco/service/cmr/avm/AVMService.java @@ -27,6 +27,7 @@ import java.util.SortedMap; import org.alfresco.repo.domain.PropertyValue; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.namespace.QName; +import org.alfresco.util.Pair; /** * This is the service interface for the [Alfresco|Addled|Advanced|Aleatoric|Apotheosed|Awful] @@ -407,6 +408,13 @@ public interface AVMService */ public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name, boolean includeDeleted); + /** + * Get a list of all paths that a given node has. + * @param desc The node descriptor to get paths for. + * @return A List of version, path Pairs. + */ + public List> getPaths(AVMNodeDescriptor desc); + /** * Get the indirection path for a node in a layered context. * @param version The version number to get.