From 90d171b913d11ec018bfc4def7ae83464829cec7 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Sun, 17 Sep 2006 20:05:27 +0000 Subject: [PATCH] Moved dangerous helper methods out of AVMService. Reworked handling of path lookup failures to not throw exceptions internally, to improve performance of certain layered directory operations. Unfortunately there remains at least one scenario, handling of bulk loads, and promotions of deeply nested directories in layered contexts, in which performance is considerably less than ideal. Made AVMService.createBranch() and AVMSyncService.update() perform implicit snapshots of source tree's stores before proceeding. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3812 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/public-services-context.xml | 3 + .../org/alfresco/repo/avm/AVMRepository.java | 331 +++++++++++++++--- .../org/alfresco/repo/avm/AVMServiceImpl.java | 56 +-- .../org/alfresco/repo/avm/AVMServiceTest.java | 55 +++ .../org/alfresco/repo/avm/AVMStoreImpl.java | 146 +++++++- .../alfresco/repo/avm/AVMSyncServiceImpl.java | 34 +- .../repo/avm/LayeredDirectoryNodeImpl.java | 42 +-- .../repo/avm/LayeredFileNodeImpl.java | 8 + .../org/alfresco/repo/avm/VersionRootDAO.java | 7 + .../hibernate/VersionRootDAOHibernate.java | 13 + .../alfresco/service/cmr/avm/AVMService.java | 31 -- 11 files changed, 545 insertions(+), 181 deletions(-) diff --git a/config/alfresco/public-services-context.xml b/config/alfresco/public-services-context.xml index 6427584fa1..30f41312df 100644 --- a/config/alfresco/public-services-context.xml +++ b/config/alfresco/public-services-context.xml @@ -1058,6 +1058,9 @@ + + + diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index 51d94777b9..0f92e8aa58 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -105,8 +105,12 @@ public class AVMRepository { fLookupCount.set(1); String[] pathParts = SplitPath(path); - AVMStore rep = getAVMStoreByName(pathParts[0]); - return rep.createFile(pathParts[1], name); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + return store.createFile(pathParts[1], name); } /** @@ -119,8 +123,12 @@ public class AVMRepository { fLookupCount.set(1); String[] pathParts = SplitPath(path); - AVMStore rep = getAVMStoreByName(pathParts[0]); - rep.createFile(pathParts[1], name, data); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + store.createFile(pathParts[1], name, data); } /** @@ -132,8 +140,12 @@ public class AVMRepository { fLookupCount.set(1); String[] pathParts = SplitPath(path); - AVMStore rep = getAVMStoreByName(pathParts[0]); - rep.createDirectory(pathParts[1], name); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + store.createDirectory(pathParts[1], name); } /** @@ -157,6 +169,10 @@ public class AVMRepository // We need the store to do anything so... String [] pathParts = SplitPath(parent.getPath()); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } DirectoryNode dir = (DirectoryNode)node; DirectoryNode child = null; if (dir instanceof LayeredDirectoryNode) @@ -188,9 +204,12 @@ public class AVMRepository } fLookupCount.set(1); String[] pathParts = SplitPath(dstPath); - AVMStore rep = getAVMStoreByName(pathParts[0]); -// fSession.get().lock(rep, LockMode.UPGRADE); - rep.createLayeredDirectory(srcPath, pathParts[1], name); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + store.createLayeredDirectory(srcPath, pathParts[1], name); } /** @@ -203,8 +222,12 @@ public class AVMRepository { fLookupCount.set(1); String[] pathParts = SplitPath(dstPath); - AVMStore rep = getAVMStoreByName(pathParts[0]); - rep.createLayeredFile(srcPath, pathParts[1], name); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + store.createLayeredFile(srcPath, pathParts[1], name); } /** @@ -213,15 +236,10 @@ public class AVMRepository */ public void createAVMStore(String name) { - try + if (getAVMStoreByName(name) != null) { - getAVMStoreByName(name); throw new AVMExistsException("AVMStore exists: " + name); } - catch (AVMNotFoundException anf) - { - // Do nothing. - } // Newing up the object causes it to be written to the db. @SuppressWarnings("unused") AVMStore rep = new AVMStoreImpl(this, name); @@ -246,12 +264,32 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(srcPath); AVMStore srcRepo = getAVMStoreByName(pathParts[0]); + if (srcRepo == null) + { + throw new AVMNotFoundException("Store not found."); + } + if (version < 0) + { + version = srcRepo.createSnapshot(); + } Lookup sPath = srcRepo.lookup(version, pathParts[1], false, false); + if (sPath == null) + { + throw new AVMNotFoundException("Path not found."); + } // Lookup the destination directory. fLookupCount.set(1); pathParts = SplitPath(dstPath); AVMStore dstRepo = getAVMStoreByName(pathParts[0]); + if (dstRepo == null) + { + throw new AVMNotFoundException("Store not found."); + } Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true); + if (dPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dirNode = (DirectoryNode)dPath.getCurrentNode(); AVMNode srcNode = sPath.getCurrentNode(); AVMNode dstNode = null; @@ -291,8 +329,12 @@ public class AVMRepository { fLookupCount.set(1); String [] pathParts = SplitPath(path); - AVMStore rep = getAVMStoreByName(pathParts[0]); - return rep.getOutputStream(pathParts[1]); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + return store.getOutputStream(pathParts[1]); } /** @@ -313,7 +355,15 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(srcPath); AVMStore srcRepo = getAVMStoreByName(pathParts[0]); + if (srcRepo == null) + { + throw new AVMNotFoundException("Store not found."); + } Lookup sPath = srcRepo.lookupDirectory(-1, pathParts[1], true); + if (sPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode srcDir = (DirectoryNode)sPath.getCurrentNode(); AVMNode srcNode = srcDir.lookupChild(sPath, srcName, -1, true, false); if (srcNode == null) @@ -323,7 +373,15 @@ public class AVMRepository fLookupCount.set(1); pathParts = SplitPath(dstPath); AVMStore dstRepo = getAVMStoreByName(pathParts[0]); + if (dstRepo == null) + { + throw new AVMNotFoundException("Store not found."); + } Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true); + if (dPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dstDir = (DirectoryNode)dPath.getCurrentNode(); AVMNode dstNode = dstDir.lookupChild(dPath, dstName, -1, true, false); if (dstNode != null) @@ -425,8 +483,12 @@ public class AVMRepository { fLookupCount.set(1); String [] pathParts = SplitPath(dirPath); - AVMStore repo = getAVMStoreByName(pathParts[0]); - repo.uncover(pathParts[1], name); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + store.uncover(pathParts[1], name); } /** @@ -439,8 +501,12 @@ public class AVMRepository List result = new ArrayList(); for (String repName : repositories) { - AVMStore repo = getAVMStoreByName(repName); - result.add(repo.createSnapshot()); + AVMStore store = getAVMStoreByName(repName); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } + result.add(store.createSnapshot()); } return result; } @@ -453,6 +519,10 @@ public class AVMRepository public int createSnapshot(String storeName) { AVMStore store = getAVMStoreByName(storeName); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.createSnapshot(); } @@ -466,6 +536,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.removeNode(pathParts[1], name); } @@ -478,6 +552,10 @@ public class AVMRepository public void purgeAVMStore(String name) { AVMStore store = getAVMStoreByName(name); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } AVMNode root = store.getRoot(); root.setIsRoot(false); VersionRootDAO vrDAO = AVMContext.fgInstance.fVersionRootDAO; @@ -505,6 +583,10 @@ public class AVMRepository public void purgeVersion(String name, int version) { AVMStore store = getAVMStoreByName(name); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.purgeVersion(version); } @@ -519,6 +601,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getInputStream(version, pathParts[1]); } @@ -535,6 +621,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getListing(version, pathParts[1], includeDeleted); } @@ -550,6 +640,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getListingDirect(version, pathParts[1], includeDeleted); } @@ -612,6 +706,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getDeleted(version, pathParts[1]); } @@ -639,6 +737,10 @@ public class AVMRepository public AVMStoreDescriptor getAVMStore(String name) { AVMStore store = getAVMStoreByName(name); + if (store == null) + { + return null; + } return store.getDescriptor(); } @@ -650,6 +752,10 @@ public class AVMRepository public List getAVMStoreVersions(String name) { AVMStore store = getAVMStoreByName(name); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getVersions(); } @@ -664,6 +770,10 @@ public class AVMRepository public List getAVMStoreVersions(String name, Date from, Date to) { AVMStore store = getAVMStoreByName(name); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getVersions(from, to); } @@ -696,6 +806,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getIndirectionPath(version, pathParts[1]); } @@ -707,6 +821,10 @@ public class AVMRepository public int getLatestVersionID(String name) { AVMStore store = getAVMStoreByName(name); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getNextVersionID(); } @@ -717,12 +835,7 @@ public class AVMRepository */ private AVMStore getAVMStoreByName(String name) { - AVMStore store = AVMContext.fgInstance.fAVMStoreDAO.getByName(name); - if (store == null) - { - throw new AVMNotFoundException("AVMStore not found: " + name); - } - return store; + return AVMContext.fgInstance.fAVMStoreDAO.getByName(name); } /** @@ -768,8 +881,11 @@ public class AVMRepository } String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); - Lookup result = store.lookup(version, pathParts[1], false, includeDeleted); - return result; + if (store == null) + { + return null; + } + return store.lookup(version, pathParts[1], false, includeDeleted); } finally { @@ -780,6 +896,7 @@ public class AVMRepository } } + // TODO This should really return null for not found. /** * Lookup a descriptor from a directory descriptor. * @param dir The directory descriptor. @@ -814,7 +931,15 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } Lookup lookup = store.lookup(version, pathParts[1], false, false); + if (lookup == null) + { + throw new AVMNotFoundException("Path not found."); + } return new LayeringDescriptor(!lookup.getDirectlyContained(), lookup.getAVMStore().getDescriptor(), lookup.getFinalStore().getDescriptor()); @@ -834,6 +959,10 @@ public class AVMRepository } String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + return null; + } return store.lookupDirectory(version, pathParts[1], false); } @@ -861,6 +990,10 @@ public class AVMRepository fLookupCount.set(1); String[] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.makePrimary(pathParts[1]); } @@ -874,6 +1007,10 @@ public class AVMRepository fLookupCount.set(1); String[] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.retargetLayeredDirectory(pathParts[1], target); } @@ -918,6 +1055,10 @@ public class AVMRepository fLookupCount.set(1); String[] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.setOpacity(pathParts[1], opacity); } @@ -932,6 +1073,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.setNodeProperty(pathParts[1], name, value); } @@ -945,6 +1090,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.setNodeProperties(pathParts[1], properties); } @@ -960,6 +1109,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getNodeProperty(version, pathParts[1], name); } @@ -974,6 +1127,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getNodeProperties(version, pathParts[1]); } @@ -987,6 +1144,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.deleteNodeProperty(pathParts[1], name); } @@ -999,6 +1160,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.deleteNodeProperties(pathParts[1]); } @@ -1010,7 +1175,12 @@ public class AVMRepository */ public void setStoreProperty(String store, QName name, PropertyValue value) { - getAVMStoreByName(store).setProperty(name, value); + AVMStore st = getAVMStoreByName(store); + if (st == null) + { + throw new AVMNotFoundException("Store not found."); + } + st.setProperty(name, value); } /** @@ -1020,7 +1190,12 @@ public class AVMRepository */ public void setStoreProperties(String store, Map props) { - getAVMStoreByName(store).setProperties(props); + AVMStore st = getAVMStoreByName(store); + if (st == null) + { + throw new AVMNotFoundException("Store not found."); + } + st.setProperties(props); } /** @@ -1031,7 +1206,16 @@ public class AVMRepository */ public PropertyValue getStoreProperty(String store, QName name) { - return getAVMStoreByName(store).getProperty(name); + if (store == null) + { + throw new AVMBadArgumentException("Null store name."); + } + AVMStore st = getAVMStoreByName(store); + if (st == null) + { + throw new AVMNotFoundException("Store not found."); + } + return st.getProperty(name); } /** @@ -1042,8 +1226,13 @@ public class AVMRepository */ public Map queryStorePropertyKey(String store, QName keyPattern) { + AVMStore st = getAVMStoreByName(store); + if (st == null) + { + throw new AVMNotFoundException("Store not found."); + } List matches = - AVMContext.fgInstance.fAVMStorePropertyDAO.queryByKeyPattern(getAVMStoreByName(store), + AVMContext.fgInstance.fAVMStorePropertyDAO.queryByKeyPattern(st, keyPattern); Map results = new HashMap(); for (AVMStoreProperty prop : matches) @@ -1086,7 +1275,16 @@ public class AVMRepository */ public Map getStoreProperties(String store) { - return getAVMStoreByName(store).getProperties(); + if (store == null) + { + throw new AVMBadArgumentException("Null store name."); + } + AVMStore st = getAVMStoreByName(store); + if (st == null) + { + throw new AVMNotFoundException("Store not found."); + } + return st.getProperties(); } /** @@ -1096,17 +1294,12 @@ public class AVMRepository */ public void deleteStoreProperty(String store, QName name) { - getAVMStoreByName(store).deleteProperty(name); - } - - /** - * Get the AVMStoreDescriptor for an AVMStore. - * @param name The name of the AVMStore. - * @return The descriptor. - */ - public AVMStoreDescriptor getAVMStoreDescriptor(String name) - { - return getAVMStoreByName(name).getDescriptor(); + AVMStore st = getAVMStoreByName(store); + if (st == null) + { + throw new AVMNotFoundException("Store not found."); + } + st.deleteProperty(name); } /** @@ -1179,6 +1372,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getContentDataForWrite(pathParts[1]); } @@ -1192,6 +1389,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.setContentData(pathParts[1], data); } @@ -1214,6 +1415,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.addAspect(pathParts[1], aspectName); } @@ -1228,6 +1433,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getAspects(version, pathParts[1]); } @@ -1241,6 +1450,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.removeAspect(pathParts[1], aspectName); } @@ -1256,6 +1469,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.hasAspect(version, pathParts[1], aspectName); } @@ -1269,6 +1486,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.setACL(pathParts[1], acl); } @@ -1283,6 +1504,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } return store.getACL(version, pathParts[1]); } @@ -1297,6 +1522,10 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(parentPath); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } store.link(pathParts[1], name, toLink); } @@ -1353,8 +1582,16 @@ public class AVMRepository fLookupCount.set(1); String [] pathParts = SplitPath(path); AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found."); + } // Just force a copy if needed by looking up in write mode. Lookup lPath = store.lookup(-1, pathParts[1], true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); return node.getDescriptor(lPath); } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index 2f50eb4921..b45c72ec68 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -307,22 +307,6 @@ public class AVMServiceImpl implements AVMService fAVMRepository.createDirectory(path, name); } - /** - * Create a new directory, in an already copy on written node. - * This should only be used if you really know what you're doing. - * @param parent The parent node. - * @param name The name of the new directory. - * @return A descriptor for the newly created directory. - */ - public AVMNodeDescriptor createDirectory(AVMNodeDescriptor parent, String name) - { - if (parent == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.createDirectory(parent, name); - } - /** * Create a new layered file. It must not exist. * @param srcPath The src path. Ie the target for the layering. @@ -511,6 +495,10 @@ public class AVMServiceImpl implements AVMService try { Lookup lookup = fAVMRepository.lookup(version, path, includeDeleted); + if (lookup == null) + { + return null; + } return lookup.getCurrentNode().getDescriptor(lookup); } catch (AVMNotFoundException e) @@ -1082,42 +1070,6 @@ public class AVMServiceImpl implements AVMService fAVMRepository.link(parentPath, name, toLink); } - /** - * This is a more dangerous version of link, which assumes - * that copy on write has occurred for the parent node. This is - * an internal call. Don't use it if you don't know precisely - * what you are doing. - * @param parent The parent node. - * @param name The name to give the child. - * @param child The child node to link. - */ - public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child) - { - if (parent == null || child == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.link(parent, name, child); - } - - /** - * Flatten a direct child of a layered directory. This does - * the equivalent of removing the given child from the directory - * and then doing an uncover. This routine makes many dangerous - * assumptions and is only for use by AVMSyncService. Don't use it - * if you don't know precisely what you are doing. - * @param lDir The layered directory node. - * @param name The name to flatten. - */ - public void flatten(AVMNodeDescriptor lDir, String name) - { - if (lDir == null || name == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.flatten(lDir, name); - } - /** * Force copy on write of a path. * @param path The path to force. diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index edd18d6d8d..6fe2d05006 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -59,6 +59,61 @@ import org.alfresco.service.transaction.TransactionService; */ public class AVMServiceTest extends AVMServiceTestBase { + /** + * Test that an update forces a snapshot on the source. + */ + public void testUpdateSnapshot() + { + try + { + setupBasicTree(); + fService.createAVMStore("branch"); + fService.createBranch(-1, "main:/", "branch:/", "branch"); + // Modify some things in the branch. + fService.createFile("branch:/branch/a/b", "fing").close(); + fService.getFileOutputStream("branch:/branch/a/b/c/foo").close(); + fService.removeNode("branch:/branch/a/b/c", "bar"); + List diffs = + fSyncService.compare(-1, "branch:/branch", -1, "main:/"); + assertEquals(3, diffs.size()); + // Now update. + fSyncService.update(diffs, false, false, false, false); + diffs = fSyncService.compare(-1, "branch:/branch", -1, "main:/"); + assertEquals(0, diffs.size()); + fService.getFileOutputStream("branch:/branch/a/b/fing").close(); + assertTrue(fService.lookup(-1, "branch:/branch/a/b/fing").getId() != + fService.lookup(-1, "main:/a/b/fing").getId()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + fail(); + } + } + + /** + * Test that branching forces a snapshot on the source repository. + */ + public void testBranchSnapshot() + { + try + { + setupBasicTree(); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createBranch(-1, "main:/a", "main:/", "abranch"); + assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), + fService.lookup(-1, "main:/abranch/b/c/foo").getId()); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + assertTrue(fService.lookup(-1, "main:/a/b/c/foo").getId() != + fService.lookup(-1, "main:/abranch/b/c/foo").getId()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + fail(); + } + } + /** * Test bulk update. */ diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java index 24503a6582..a331b2820b 100644 --- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java @@ -141,7 +141,8 @@ public class AVMStoreImpl implements AVMStore, Serializable // If the root isn't new, we can't take a snapshot since nothing has changed. if (!fRoot.getIsNew()) { - throw new AVMExistsException("Already snapshotted."); + // So we just return the most recent snapshot. + return AVMContext.fgInstance.fVersionRootDAO.getMaxVersionID(this); } // Clear out the new nodes. List newInRep = AVMContext.fgInstance.fAVMNodeDAO.getNewInStore(this); @@ -150,11 +151,16 @@ public class AVMStoreImpl implements AVMStore, Serializable newGuy.setStoreNew(null); } // Make up a new version record. + String user = AVMContext.fgInstance.getAuthenticationComponent().getCurrentUserName(); + if (user == null) + { + user = AVMContext.fgInstance.getAuthenticationComponent().getSystemUserName(); + } VersionRoot versionRoot = new VersionRootImpl(this, fRoot, fNextVersionID, System.currentTimeMillis(), - "britt"); + user); AVMContext.fgInstance.fVersionRootDAO.save(versionRoot); // Increment the version id. fNextVersionID++; @@ -169,6 +175,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void createDirectory(String path, String name) { Lookup lPath = lookupDirectory(-1, path, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (dir.lookupChild(lPath, name, -1, true, false) != null) { @@ -202,6 +212,10 @@ public class AVMStoreImpl implements AVMStore, Serializable String name) { Lookup lPath = lookupDirectory(-1, dstPath, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (dir.lookupChild(lPath, name, -1, true, false) != null) { @@ -236,6 +250,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public OutputStream createFile(String path, String name) { Lookup lPath = lookupDirectory(-1, path, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (dir.lookupChild(lPath, name, -1, true, false) != null) { @@ -262,6 +280,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void createFile(String path, String name, File data) { Lookup lPath = lookupDirectory(-1, path, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (dir.lookupChild(lPath, name, -1, true, false) != null) { @@ -288,6 +310,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void createLayeredFile(String srcPath, String dstPath, String name) { Lookup lPath = lookupDirectory(-1, dstPath, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (dir.lookupChild(lPath, name, -1, true, false) != null) { @@ -354,6 +380,10 @@ public class AVMStoreImpl implements AVMStore, Serializable boolean includeDeleted) { Lookup lPath = lookupDirectory(version, path, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); Map listing = dir.getListing(lPath, includeDeleted); return translateListing(listing, lPath); @@ -369,6 +399,10 @@ public class AVMStoreImpl implements AVMStore, Serializable boolean includeDeleted) { Lookup lPath = lookupDirectory(version, path, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (lPath.isLayered() && dir.getType() != AVMNodeType.LAYERED_DIRECTORY) { @@ -407,6 +441,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public List getDeleted(int version, String path) { Lookup lPath = lookupDirectory(version, path, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); return dir.getDeletedNames(); } @@ -443,6 +481,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void removeNode(String path, String name) { Lookup lPath = lookupDirectory(-1, path, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (dir.lookupChild(lPath, name, -1, true, false) == null) { @@ -460,6 +502,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void uncover(String dirPath, String name) { Lookup lPath = lookup(-1, dirPath, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); if (node.getType() != AVMNodeType.LAYERED_DIRECTORY) { @@ -540,7 +586,7 @@ public class AVMStoreImpl implements AVMStore, Serializable Lookup result = new Lookup(this, fName); if (path.length() == 0) { - throw new AVMException("Invalid path: " + path); + return null; } while (path.startsWith("/")) { @@ -576,13 +622,13 @@ public class AVMStoreImpl implements AVMStore, Serializable AVMNode child = dir.lookupChild(result, pathElements[i], version, write, includeDeleted); if (child == null) { - throw new AVMNotFoundException("Not found: " + pathElements[i]); + return null; } // Every element that is not the last needs to be a directory. if (child.getType() != AVMNodeType.PLAIN_DIRECTORY && child.getType() != AVMNodeType.LAYERED_DIRECTORY) { - throw new AVMNotFoundException("Not a directory: " + pathElements[i]); + return null; } result.add(child, pathElements[i], write); dir = (DirectoryNode)result.getCurrentNode(); @@ -592,7 +638,7 @@ public class AVMStoreImpl implements AVMStore, Serializable includeDeleted); if (child == null) { - throw new AVMNotFoundException("Not found: " + pathElements[pathElements.length - 1]); + return null; } result.add(child, pathElements[pathElements.length - 1], write); return result; @@ -629,10 +675,14 @@ public class AVMStoreImpl implements AVMStore, Serializable // Just do a regular lookup and assert that the last element // is a directory. Lookup lPath = lookup(version, path, write, false); + if (lPath == null) + { + return null; + } if (lPath.getCurrentNode().getType() != AVMNodeType.PLAIN_DIRECTORY && lPath.getCurrentNode().getType() != AVMNodeType.LAYERED_DIRECTORY) { - throw new AVMWrongTypeException("Not a directory: " + path); + return null; } return lPath; } @@ -646,6 +696,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public String getIndirectionPath(int version, String path) { Lookup lPath = lookup(version, path, false, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) { @@ -665,7 +719,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void makePrimary(String path) { Lookup lPath = lookupDirectory(-1, path, true); -// lPath.acquireLocks(); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (!lPath.isLayered()) { @@ -683,7 +740,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void retargetLayeredDirectory(String path, String target) { Lookup lPath = lookupDirectory(-1, path, true); -// lPath.acquireLocks(); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); if (!lPath.isLayered()) { @@ -844,6 +904,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void setOpacity(String path, boolean opacity) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); if (!(node instanceof LayeredDirectoryNode)) { @@ -863,6 +927,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void setNodeProperty(String path, QName name, PropertyValue value) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); node.setProperty(name, value); } @@ -875,6 +943,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void setNodeProperties(String path, Map properties) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); node.setProperties(properties); } @@ -889,6 +961,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public PropertyValue getNodeProperty(int version, String path, QName name) { Lookup lPath = lookup(version, path, false, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); return node.getProperty(name); } @@ -902,6 +978,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public Map getNodeProperties(int version, String path) { Lookup lPath = lookup(version, path, false, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); return node.getProperties(); } @@ -914,6 +994,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void deleteNodeProperty(String path, QName name) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); node.deleteProperty(name); } @@ -925,6 +1009,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void deleteNodeProperties(String path) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); node.deleteProperties(); } @@ -999,6 +1087,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public ContentData getContentDataForRead(int version, String path) { Lookup lPath = lookup(version, path, false, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); if (!(node instanceof FileNode)) { @@ -1015,6 +1107,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public ContentData getContentDataForWrite(String path) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); if (!(node instanceof FileNode)) { @@ -1031,6 +1127,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void setContentData(String path, ContentData data) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); if (!(node instanceof FileNode)) { @@ -1047,6 +1147,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void addAspect(String path, QName aspectName) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); if (AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName)) { @@ -1068,6 +1172,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public List getAspects(int version, String path) { Lookup lPath = lookup(version, path, false, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); List names = AVMContext.fgInstance.fAVMAspectNameDAO.get(node); @@ -1087,6 +1195,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void removeAspect(String path, QName aspectName) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); AVMContext.fgInstance.fAVMAspectNameDAO.delete(node, aspectName); AspectDefinition def = AVMContext.fgInstance.getDictionaryService().getAspect(aspectName); @@ -1108,6 +1220,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public boolean hasAspect(int version, String path, QName aspectName) { Lookup lPath = lookup(version, path, false, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); return AVMContext.fgInstance.fAVMAspectNameDAO.exists(node, aspectName); } @@ -1120,6 +1236,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void setACL(String path, DbAccessControlList acl) { Lookup lPath = lookup(-1, path, true, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } AVMNode node = lPath.getCurrentNode(); node.setAcl(acl); } @@ -1133,6 +1253,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public DbAccessControlList getACL(int version, String path) { Lookup lPath = lookup(version, path, false, false); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } return lPath.getCurrentNode().getAcl(); } @@ -1145,6 +1269,10 @@ public class AVMStoreImpl implements AVMStore, Serializable public void link(String parentPath, String name, AVMNodeDescriptor toLink) { Lookup lPath = lookupDirectory(-1, parentPath, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path not found."); + } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); dir.link(lPath, name, toLink); } diff --git a/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java index 863cf6d8c7..84a095cf23 100644 --- a/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java @@ -46,6 +46,11 @@ public class AVMSyncServiceImpl implements AVMSyncService */ private AVMService fAVMService; + /** + * The AVMRepository. + */ + private AVMRepository fAVMRepository; + /** * Do nothing constructor. */ @@ -54,10 +59,7 @@ public class AVMSyncServiceImpl implements AVMSyncService } /** - * Set the AVM Service. For Spring. For now, at least, - * it's important to wire this using the unintercepted AVMServiceImpl, - * as AVMServiceImpl uses Runtime Exceptions for handling valid states - * that should not cause rollbacks. + * Set the AVM Service. For Spring. * @param avmService The AVMService reference. */ public void setAvmService(AVMService avmService) @@ -65,6 +67,11 @@ public class AVMSyncServiceImpl implements AVMSyncService fAVMService = avmService; } + public void setAvmRepository(AVMRepository avmRepository) + { + fAVMRepository = avmRepository; + } + /** * Get a difference list between two corresponding node trees. * @param srcVersion The version id for the source tree. @@ -280,7 +287,14 @@ public class AVMSyncServiceImpl implements AVMSyncService { throw new AVMSyncException("Malformed AVMDifference."); } - AVMNodeDescriptor srcDesc = fAVMService.lookup(diff.getSourceVersion(), + int colonOff = diff.getSourcePath().indexOf(':'); + if (colonOff == -1) + { + throw new AVMBadArgumentException("Invalid path."); + } + String storeName = diff.getSourcePath().substring(0, colonOff); + int version = fAVMService.createSnapshot(storeName); + AVMNodeDescriptor srcDesc = fAVMService.lookup(version, diff.getSourcePath(), true); if (srcDesc == null) { @@ -385,8 +399,6 @@ public class AVMSyncServiceImpl implements AVMSyncService fAVMService.link(parentPath, name, toLink); } - // TODO doesn't handle copies from non head nodes. - /** * Recursively copy a node into the given position. * @param parentPath The place to put it. @@ -417,12 +429,12 @@ public class AVMSyncServiceImpl implements AVMSyncService // If it's a file or deleted simply link it in. if (toCopy.isFile() || toCopy.isDeleted() || toCopy.isPlainDirectory()) { - fAVMService.link(parent, name, toCopy); + fAVMRepository.link(parent, name, toCopy); return; } // Otherwise make a directory in the target parent, and recursiveCopy all the source // children into it. - AVMNodeDescriptor newParentDesc = fAVMService.createDirectory(parent, name); + AVMNodeDescriptor newParentDesc = fAVMRepository.createDirectory(parent, name); fgLogger.error(newParentDesc); Map children = fAVMService.getDirectoryListing(toCopy, true); @@ -613,14 +625,14 @@ public class AVMSyncServiceImpl implements AVMSyncService // We've found an identity so flatten it. if (topNode.getId() == bottomNode.getId()) { - fAVMService.flatten(layer, name); + fAVMRepository.flatten(layer, name); } else { // Otherwise recursively flatten the children. if (flatten(topNode, bottomNode)) { - fAVMService.flatten(layer, name); + fAVMRepository.flatten(layer, name); } else { diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java index cb8badfdae..c9dff89bb9 100644 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java @@ -25,7 +25,6 @@ import java.util.SortedMap; import java.util.TreeMap; import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMCycleException; import org.alfresco.service.cmr.avm.AVMException; import org.alfresco.service.cmr.avm.AVMExistsException; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; @@ -316,18 +315,14 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec } else { - try + Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath)); + if (lookup != null) { - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath)); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); listing = dir.getListing(lookup, includeDeleted); } - catch (AVMException re) + else { - if (re instanceof AVMCycleException) - { - throw re; - } // It's OK for an indirection to dangle. listing = new HashMap(); } @@ -406,9 +401,9 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec // If we are not opaque, get the underlying base listing. if (!fOpacity) { - try + Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, dir.getIndirection()); + if (lookup != null) { - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, dir.getIndirection()); DirectoryNode dirNode = (DirectoryNode)lookup.getCurrentNode(); Map listing = dirNode.getListing(lookup, includeDeleted); for (String name : listing.keySet()) @@ -418,13 +413,6 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec lookup.getCurrentIndirection())); } } - catch (AVMException e) - { - if (e instanceof AVMCycleException) - { - throw e; - } - } } List children = AVMContext.fgInstance.fChildEntryDAO.getByParent(this); for (ChildEntry child : children) @@ -489,20 +477,16 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec return null; } // Not here so check our indirection. - try + Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath)); + if (lookup != null) { - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath)); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); AVMNode retVal = dir.lookupChild(lookup, name, -1, false, includeDeleted); lPath.setFinalStore(lookup.getFinalStore()); return retVal; } - catch (AVMException re) + else { - if (re instanceof AVMCycleException) - { - throw re; - } return null; } } @@ -535,9 +519,9 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec { return null; } - try + Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, mine.getIndirection()); + if (lookup != null) { - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, mine.getIndirection()); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); AVMNode child = dir.lookupChild(lookup, name, -1, false, includeDeleted); if (child == null) @@ -546,12 +530,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec } return child.getDescriptor(lookup); } - catch (AVMException e) + else { - if (e instanceof AVMCycleException) - { - throw e; - } return null; } } diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java index adcd459af0..3385740d3c 100644 --- a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java @@ -79,6 +79,10 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode { // LayeredFileNodes are always copied. Lookup lookup = AVMRepository.GetInstance().lookup(-1, fIndirection, false); + if (lookup == null) + { + throw new AVMException("Unbacked layered file node."); + } AVMNode indirect = lookup.getCurrentNode(); if (indirect.getType() != AVMNodeType.LAYERED_FILE && indirect.getType() != AVMNodeType.PLAIN_FILE) @@ -250,6 +254,10 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode public ContentData getContentData(Lookup lPath) { Lookup lookup = lPath.getAVMStore().getAVMRepository().lookup(-1, getIndirection(), false); + if (lookup == null) + { + throw new AVMException("Invalid target."); + } AVMNode node = lookup.getCurrentNode(); if (!(node instanceof FileNode)) { diff --git a/source/java/org/alfresco/repo/avm/VersionRootDAO.java b/source/java/org/alfresco/repo/avm/VersionRootDAO.java index c9cba6e2fd..af8cf55c39 100644 --- a/source/java/org/alfresco/repo/avm/VersionRootDAO.java +++ b/source/java/org/alfresco/repo/avm/VersionRootDAO.java @@ -68,4 +68,11 @@ public interface VersionRootDAO * @return The highest numbered version. */ public VersionRoot getMaxVersion(AVMStore store); + + /** + * Get the highest numbered id from all the versions in a store. + * @param store The store. + * @return The highest numbered id. + */ + public Integer getMaxVersionID(AVMStore store); } diff --git a/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java index ce2519461a..d7a22ff2e7 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java +++ b/source/java/org/alfresco/repo/avm/hibernate/VersionRootDAOHibernate.java @@ -141,4 +141,17 @@ class VersionRootDAOHibernate extends HibernateDaoSupport implements "(select max(v.versionID) from VersionRootImpl v)"); return (VersionRoot)query.uniqueResult(); } + + /** + * Get the highest numbered id from all the versions in a store. + * @param store The store. + * @return The highest numbered id. + */ + public Integer getMaxVersionID(AVMStore store) + { + Query query = getSession().createQuery("select max(vr.versionID) from VersionRootImpl vr " + + "where vr.avmStore = :store"); + query.setEntity("store", store); + return (Integer)query.uniqueResult(); + } } diff --git a/source/java/org/alfresco/service/cmr/avm/AVMService.java b/source/java/org/alfresco/service/cmr/avm/AVMService.java index dac0db83a1..83b434a625 100644 --- a/source/java/org/alfresco/service/cmr/avm/AVMService.java +++ b/source/java/org/alfresco/service/cmr/avm/AVMService.java @@ -192,15 +192,6 @@ public interface AVMService */ public void createDirectory(String path, String name); - /** - * Create a new directory, in an already copy on written node. - * This should only be used if you really know what you're doing. - * @param parent The parent node. - * @param name The name of the new directory. - * @return A descriptor for the newly created directory. - */ - public AVMNodeDescriptor createDirectory(AVMNodeDescriptor parent, String name); - /** * Create a new layered file. * @param targetPath The simple absolute path that the new file will point at. @@ -695,28 +686,6 @@ public interface AVMService */ public void link(String parentPath, String name, AVMNodeDescriptor toLink); - /** - * This is a more dangerous version of link, which assumes - * that copy on write has occurred for the parent node. This is - * an internal call. Don't use it if you don't know precisely - * what you are doing. - * @param parent The parent node. - * @param name The name to give the child. - * @param child The child node to link. - */ - public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child); - - /** - * Flatten a direct child of a layered directory. This does - * the equivalent of removing the given child from the directory - * and then doing an uncover. This routine makes many dangerous - * assumptions and is only for use by AVMSyncService. Don't use it - * if you don't know precisely what you are doing. - * @param lDir The layered directory node. - * @param name The name to flatten. - */ - public void flatten(AVMNodeDescriptor lDir, String name); - /** * Force copy on write of a path. * @param path The path to force.