From f91cedfd694b7b127cd0f1768e8107bc286670b0 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Mon, 30 Apr 2007 18:48:19 +0000 Subject: [PATCH] Fixed createBranch() so that layered node lookups behave properly. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5579 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/avm-services-context.xml | 18 +++ .../alfresco/repo/avm/AVMNodeConverter.java | 12 ++ .../org/alfresco/repo/avm/AVMRepository.java | 141 ++++++++++++------ .../org/alfresco/repo/avm/AVMServiceTest.java | 28 ++++ .../org/alfresco/repo/avm/AVMStoreImpl.java | 2 +- 5 files changed, 158 insertions(+), 43 deletions(-) diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml index efb668c172..073810ddfa 100644 --- a/config/alfresco/avm-services-context.xml +++ b/config/alfresco/avm-services-context.xml @@ -214,6 +214,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/avm/AVMNodeConverter.java b/source/java/org/alfresco/repo/avm/AVMNodeConverter.java index d0bd225d63..bc9c97e292 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeConverter.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeConverter.java @@ -141,4 +141,16 @@ public class AVMNodeConverter decomposed[1] = path.substring(off + 1); return decomposed; } + + /** + * Normalize an AVM path. + * @param path The incoming path. + * @return The normalized path. + */ + public static String NormalizePath(String path) + { + path = path.replaceAll("/+", "/"); + path = path.replaceAll("/$", ""); + return path; + } } diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index 27242c3e21..7c39cae7a1 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -94,6 +94,18 @@ public class AVMRepository */ private LookupCache fLookupCache; + private AVMStoreDAO fAVMStoreDAO; + + private AVMNodeDAO fAVMNodeDAO; + + private VersionRootDAO fVersionRootDAO; + + private VersionLayeredNodeEntryDAO fVersionLayeredNodeEntryDAO; + + private AVMStorePropertyDAO fAVMStorePropertyDAO; + + private ChildEntryDAO fChildEntryDAO; + // A bunch of TransactionListeners that do work for this. /** @@ -180,6 +192,36 @@ public class AVMRepository fPurgeVersionTxnListener = listener; } + public void setAvmStoreDAO(AVMStoreDAO dao) + { + fAVMStoreDAO = dao; + } + + public void setAvmNodeDAO(AVMNodeDAO dao) + { + fAVMNodeDAO = dao; + } + + public void setVersionRootDAO(VersionRootDAO dao) + { + fVersionRootDAO = dao; + } + + public void setVersionLayeredNodeEntryDAO(VersionLayeredNodeEntryDAO dao) + { + fVersionLayeredNodeEntryDAO = dao; + } + + public void setAvmStorePropertyDAO(AVMStorePropertyDAO dao) + { + fAVMStorePropertyDAO = dao; + } + + public void setChildEntryDAO(ChildEntryDAO dao) + { + fChildEntryDAO = dao; + } + /** * Create a file. * @param path The path to the containing directory. @@ -265,7 +307,7 @@ public class AVMRepository */ public AVMNodeDescriptor createDirectory(AVMNodeDescriptor parent, String name) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(parent.getId()); + AVMNode node = fAVMNodeDAO.getByID(parent.getId()); if (node == null) { throw new AVMNotFoundException(parent.getId() + " not found."); @@ -391,6 +433,7 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts; Lookup sPath; + List layeredEntries = null; try { pathParts = SplitPath(srcPath); @@ -409,6 +452,8 @@ public class AVMRepository { throw new AVMNotFoundException("Path not found."); } + VersionRoot lastVersion = fVersionRootDAO.getByVersionID(srcRepo, version); + layeredEntries = fVersionLayeredNodeEntryDAO.get(lastVersion); } finally { @@ -458,6 +503,22 @@ public class AVMRepository dstNode.setAncestor(srcNode); dirNode.putChild(name, dstNode); dirNode.updateModTime(); + String beginingPath = AVMNodeConverter.NormalizePath(srcPath); + String finalPath = AVMNodeConverter.ExtendAVMPath(dstPath, name); + finalPath = AVMNodeConverter.NormalizePath(finalPath); + VersionRoot latestVersion = fVersionRootDAO.getMaxVersion(dstRepo); + for (VersionLayeredNodeEntry entry : layeredEntries) + { + String path = entry.getPath(); + if (!path.startsWith(srcPath)) + { + continue; + } + String newPath = finalPath + path.substring(beginingPath.length()); + VersionLayeredNodeEntry newEntry = + new VersionLayeredNodeEntryImpl(latestVersion, newPath); + fVersionLayeredNodeEntryDAO.save(newEntry); + } } finally { @@ -639,8 +700,6 @@ public class AVMRepository } else if (srcNode.getType() == AVMNodeType.LAYERED_DIRECTORY) { - // TODO I think I need to subdivide this logic again. - // based on whether the destination is a layer or not. if (!sPath.isLayered() || (sPath.isInThisLayer() && srcDir.getType() == AVMNodeType.LAYERED_DIRECTORY && ((LayeredDirectoryNode)srcDir).directlyContains(srcNode))) @@ -795,23 +854,22 @@ public class AVMRepository fLookupCache.onDelete(name); AVMNode root = store.getRoot(); root.setIsRoot(false); - VersionRootDAO vrDAO = AVMDAOs.Instance().fVersionRootDAO; - List vRoots = vrDAO.getAllInAVMStore(store); + List vRoots = fVersionRootDAO.getAllInAVMStore(store); for (VersionRoot vr : vRoots) { AVMNode node = vr.getRoot(); node.setIsRoot(false); - AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(vr); - vrDAO.delete(vr); + fVersionLayeredNodeEntryDAO.delete(vr); + fVersionRootDAO.delete(vr); } - List newGuys = AVMDAOs.Instance().fAVMNodeDAO.getNewInStore(store); + List newGuys = fAVMNodeDAO.getNewInStore(store); for (AVMNode newGuy : newGuys) { newGuy.setStoreNew(null); } - AVMDAOs.Instance().fAVMStorePropertyDAO.delete(store); - AVMDAOs.Instance().fAVMStoreDAO.delete(store); - AVMDAOs.Instance().fAVMStoreDAO.invalidateCache(); + fAVMStorePropertyDAO.delete(store); + fAVMStoreDAO.delete(store); + fAVMStoreDAO.invalidateCache(); fPurgeStoreTxnListener.storePurged(name); } @@ -860,7 +918,7 @@ public class AVMRepository public InputStream getInputStream(AVMNodeDescriptor desc) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); if (!(node instanceof FileNode)) { throw new AVMWrongTypeException(desc + " is not a File."); @@ -937,7 +995,7 @@ public class AVMRepository public SortedMap getListingDirect(AVMNodeDescriptor dir, boolean includeDeleted) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(dir.getId()); + AVMNode node = fAVMNodeDAO.getByID(dir.getId()); if (node == null) { throw new AVMBadArgumentException("Invalid Node."); @@ -964,7 +1022,7 @@ public class AVMRepository fLookupCount.set(1); try { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(dir.getId()); + AVMNode node = fAVMNodeDAO.getByID(dir.getId()); if (node == null) { throw new AVMBadArgumentException("Invalid Node."); @@ -1015,7 +1073,7 @@ public class AVMRepository @SuppressWarnings("unchecked") public List getAVMStores() { - List l = AVMDAOs.Instance().fAVMStoreDAO.getAll(); + List l = fAVMStoreDAO.getAll(); List result = new ArrayList(); for (AVMStore store : l) { @@ -1151,7 +1209,7 @@ public class AVMRepository */ private AVMStore getAVMStoreByName(String name) { - AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByName(name); + AVMStore store = fAVMStoreDAO.getByName(name); return store; } @@ -1213,7 +1271,6 @@ public class AVMRepository } } - // TODO This should really return null for not found. /** * Lookup a descriptor from a directory descriptor. * @param dir The directory descriptor. @@ -1225,7 +1282,7 @@ public class AVMRepository fLookupCount.set(1); try { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(dir.getId()); + AVMNode node = fAVMNodeDAO.getByID(dir.getId()); if (node == null) { throw new AVMNotFoundException("Not found: " + dir.getId()); @@ -1251,7 +1308,7 @@ public class AVMRepository */ public List> getPaths(AVMNodeDescriptor desc) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); if (node == null) { throw new AVMNotFoundException("Not found: " + desc.getPath()); @@ -1269,7 +1326,7 @@ public class AVMRepository */ public Pair getAPath(AVMNodeDescriptor desc) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); if (node == null) { throw new AVMNotFoundException("Could not find node: " + desc); @@ -1285,7 +1342,7 @@ public class AVMRepository */ public List> getHeadPaths(AVMNodeDescriptor desc) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); if (node == null) { throw new AVMNotFoundException("Not found: " + desc.getPath()); @@ -1325,7 +1382,7 @@ public class AVMRepository paths.add(this.makePath(components, storeName)); return; } - List entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node); + List entries = fChildEntryDAO.getByChild(node); for (ChildEntry entry : entries) { String name = entry.getKey().getName(); @@ -1350,7 +1407,7 @@ public class AVMRepository { throw new AVMNotFoundException("Store not found: " + store); } - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); if (node == null) { throw new AVMNotFoundException("Not found: " + desc.getPath()); @@ -1372,20 +1429,20 @@ public class AVMRepository { if (node.getIsRoot()) { - AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByRoot(node); + AVMStore store = fAVMStoreDAO.getByRoot(node); if (store != null) { addPath(components, -1, store.getName(), paths); return; } - VersionRoot vr = AVMDAOs.Instance().fVersionRootDAO.getByRoot(node); + VersionRoot vr = fVersionRootDAO.getByRoot(node); if (vr != null) { addPath(components, vr.getVersionID(), vr.getAvmStore().getName(), paths); } return; } - List entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node); + List entries = fChildEntryDAO.getByChild(node); for (ChildEntry entry : entries) { String name = entry.getKey().getName(); @@ -1406,19 +1463,19 @@ public class AVMRepository { if (node.getIsRoot()) { - AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByRoot(node); + AVMStore store = fAVMStoreDAO.getByRoot(node); if (store != null) { return new Pair(-1, makePath(components, store.getName())); } - VersionRoot vr = AVMDAOs.Instance().fVersionRootDAO.getByRoot(node); + VersionRoot vr = fVersionRootDAO.getByRoot(node); if (vr != null) { return new Pair(vr.getVersionID(), makePath(components, vr.getAvmStore().getName())); } return null; } - List entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node); + List entries = fChildEntryDAO.getByChild(node); for (ChildEntry entry : entries) { String name = entry.getKey().getName(); @@ -1444,7 +1501,7 @@ public class AVMRepository { if (node.getIsRoot()) { - AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByRoot(node); + AVMStore store = fAVMStoreDAO.getByRoot(node); if (store != null) { addPath(components, -1, store.getName(), paths); @@ -1452,7 +1509,7 @@ public class AVMRepository } return; } - List entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node); + List entries = fChildEntryDAO.getByChild(node); for (ChildEntry entry : entries) { String name = entry.getKey().getName(); @@ -1478,7 +1535,7 @@ public class AVMRepository addPath(components, -1, storeName, paths); return; } - List entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node); + List entries = fChildEntryDAO.getByChild(node); for (ChildEntry entry : entries) { String name = entry.getKey().getName(); @@ -1652,7 +1709,7 @@ public class AVMRepository */ public List getHistory(AVMNodeDescriptor desc, int count) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); + AVMNode node = fAVMNodeDAO.getByID(desc.getId()); if (node == null) { throw new AVMNotFoundException("Not found."); @@ -1916,8 +1973,8 @@ public class AVMRepository throw new AVMNotFoundException("Store not found."); } List matches = - AVMDAOs.Instance().fAVMStorePropertyDAO.queryByKeyPattern(st, - keyPattern); + fAVMStorePropertyDAO.queryByKeyPattern(st, + keyPattern); Map results = new HashMap(); for (AVMStoreProperty prop : matches) { @@ -1935,7 +1992,7 @@ public class AVMRepository queryStoresPropertyKeys(QName keyPattern) { List matches = - AVMDAOs.Instance().fAVMStorePropertyDAO.queryByKeyPattern(keyPattern); + fAVMStorePropertyDAO.queryByKeyPattern(keyPattern); Map> results = new HashMap>(); for (AVMStoreProperty prop : matches) @@ -2001,8 +2058,8 @@ public class AVMRepository public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, AVMNodeDescriptor right) { - AVMNode lNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(left.getId()); - AVMNode rNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(right.getId()); + AVMNode lNode = fAVMNodeDAO.getByID(left.getId()); + AVMNode rNode = fAVMNodeDAO.getByID(right.getId()); if (lNode == null || rNode == null) { throw new AVMNotFoundException("Node not found."); @@ -2143,7 +2200,7 @@ public class AVMRepository { throw new AVMNotFoundException("Store not found: " + pathParts[0]); } - AVMNode fromNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(from.getId()); + AVMNode fromNode = fAVMNodeDAO.getByID(from.getId()); if (fromNode == null) { throw new AVMNotFoundException("Node not found: " + from.getPath()); @@ -2344,7 +2401,7 @@ public class AVMRepository */ public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child) { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(parent.getId()); + AVMNode node = fAVMNodeDAO.getByID(parent.getId()); if (!(node instanceof DirectoryNode)) { throw new AVMWrongTypeException("Not a Directory."); @@ -2387,7 +2444,7 @@ public class AVMRepository } LayeredDirectoryNode dir = (LayeredDirectoryNode)node; dir.flatten(name); - AVMDAOs.Instance().fAVMNodeDAO.flush(); + fAVMNodeDAO.flush(); } finally { @@ -2452,7 +2509,7 @@ public class AVMRepository } store.setName(destName); fLookupCache.onDelete(sourceName); - AVMDAOs.Instance().fAVMStoreDAO.invalidateCache(); + fAVMStoreDAO.invalidateCache(); fPurgeStoreTxnListener.storePurged(sourceName); fCreateStoreTxnListener.storeCreated(destName); } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index 9edeaac48b..fd0be3a3ef 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -83,6 +83,34 @@ import org.alfresco.util.Pair; */ public class AVMServiceTest extends AVMServiceTestBase { + public void testBranchLayerSnapshot() + { + try + { + setupBasicTree(); + fService.createStore("layer"); + fService.createDirectory("layer:/", "root"); + fService.createLayeredDirectory("main:/a", "layer:/root", "layer"); + fService.createSnapshot("layer", null, null); + fService.createFile("main:/a", "dummy").close(); + fService.createFile("layer:/root/layer", "pygmy"); + fService.createSnapshot("layer", null, null); + fService.createStore("branch"); + fService.createBranch(1, "layer:/root", "branch:/", "branch"); + fService.createSnapshot("branch", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + assertEquals(fService.lookup(1, "main:/a/b/c/foo").getId(), + fService.lookup(1, "branch:/branch/layer/b/c/foo").getId()); + assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), + fService.lookup(-1, "branch:/branch/layer/b/c/foo").getId()); + } + catch (Exception e) + { + e.printStackTrace(); + fail(); + } + } + /** * Test Deployment. */ diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java index 702da122e1..195785bf3b 100644 --- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java @@ -235,7 +235,7 @@ public class AVMStoreImpl implements AVMStore, Serializable } parent.putChild(parentName[1], newChild); } - AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(lastVersion); + // AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(lastVersion); // Clear out the new nodes. List newInRep = AVMDAOs.Instance().fAVMNodeDAO.getNewInStore(this); List layeredNodes = new ArrayList();