From 1b4c08d1d4c275f1eb42010c11e6c622c879afe8 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Thu, 18 May 2006 18:18:46 +0000 Subject: [PATCH] More cleanup, fixing, and general futzing. A checkpoint. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2920 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/repo/avm/FileContent.java | 3 +- .../repo/avm/LayeredDirectoryNode.java | 56 +++++++++++++---- .../alfresco/repo/avm/LayeredFileNode.java | 63 +++++++++++++++++-- source/java/org/alfresco/repo/avm/Lookup.java | 27 ++++---- .../alfresco/repo/avm/PlainDirectoryNode.java | 32 +++++++--- .../org/alfresco/repo/avm/PlainFileNode.java | 19 ++++-- .../alfresco/repo/avm/SuperRepository.java | 2 +- .../repo/avm/hibernate/ContentBeanImpl.java | 2 +- .../repo/avm/hibernate/DirectoryEntry.java | 35 +++++++++++ .../repo/avm/impl/RepositoryImpl.java | 26 +++++++- .../repo/avm/impl/SuperRepositoryImpl.java | 2 + 11 files changed, 218 insertions(+), 49 deletions(-) diff --git a/source/java/org/alfresco/repo/avm/FileContent.java b/source/java/org/alfresco/repo/avm/FileContent.java index 9821c051b0..3e1b6111ac 100644 --- a/source/java/org/alfresco/repo/avm/FileContent.java +++ b/source/java/org/alfresco/repo/avm/FileContent.java @@ -59,7 +59,6 @@ public class FileContent public FileContent(ContentBean data) { fData = data; - } /** @@ -69,6 +68,7 @@ public class FileContent public FileContent(SuperRepository superRepo) { fData = new ContentBeanImpl(superRepo.issueContentID()); + fData.setRefCount(1); BufferedOutputStream out = new BufferedOutputStream(getOutputStream(superRepo)); // Make an empty file. try @@ -90,6 +90,7 @@ public class FileContent public FileContent(FileContent other, SuperRepository superRepo) { fData = new ContentBeanImpl(superRepo.issueContentID()); + fData.setRefCount(1); // Copy the contents from other to this. BufferedInputStream in = new BufferedInputStream(other.getInputStream(superRepo)); BufferedOutputStream out = new BufferedOutputStream(this.getOutputStream(superRepo)); diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java index bfcf09b3a5..d4e72fd1bc 100644 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java @@ -93,8 +93,10 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered Repository repos) { LayeredDirectoryNodeBean thatBean = (LayeredDirectoryNodeBean)other.getDataBean(); + // Copy the basic attributes and update. BasicAttributesBean attrs = new BasicAttributesBeanImpl(thatBean.getBasicAttributes()); long time = System.currentTimeMillis(); + attrs.setCreateDate(time); attrs.setModDate(time); attrs.setAccessDate(time); attrs.setLastModifier("britt"); @@ -109,6 +111,7 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered attrs, -1, other.getUnderlying()); + setDataBean(fData); fData.setAdded(thatBean.getAdded()); fData.setDeleted(thatBean.getDeleted()); fData.setPrimaryIndirection(thatBean.getPrimaryIndirection()); @@ -141,24 +144,48 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered attrs, -1, null); - // TODO Is this right? - fData.setAdded(other.getListing(lPath, -1)); + setDataBean(fData); + // TODO Is this right? I don't think so. + // fData.setAdded(other.getListing(lPath, -1)); fData.setPrimaryIndirection(false); repos.getSuperRepository().getSession().save(fData); } - // TODO Something. + /** + * Create a new layered directory based on a directory we are being named from + * that is in not in the layer of the source lookup. + * @param dir The directory + * @param repo The repository + * @param srcLookup The source lookup. + * @param name The name of the target. + */ public LayeredDirectoryNode(DirectoryNode dir, Repository repo, Lookup srcLookup, String name) { -/* - fAdded = new HashMap(); - fDeleted = new HashSet(); - fProxied = srcLookup.getIndirectionPath() + "/" + name; - fIsPrimaryIndirection = true; -*/ + // Make BasicAttributes and set them correctly. + BasicAttributesBean attrs = new BasicAttributesBeanImpl(dir.getDataBean().getBasicAttributes()); + long time = System.currentTimeMillis(); + attrs.setCreateDate(time); + attrs.setModDate(time); + attrs.setAccessDate(time); + attrs.setCreator("britt"); + attrs.setLastModifier("britt"); + repo.getSuperRepository().getSession().save(attrs); + fData = new LayeredDirectoryNodeBeanImpl(repo.getSuperRepository().issueID(), + -1, + -1, + null, + null, + null, + repo.getDataBean(), + attrs, + -1, + srcLookup.getIndirectionPath() + "/" + name); + setDataBean(fData); + fData.setPrimaryIndirection(true); + repo.getSuperRepository().getSession().save(fData); } /** @@ -229,7 +256,6 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered { LayeredDirectoryNode dir = (LayeredDirectoryNode)parent; setLayerID(dir.getLayerID()); - // TODO Is this right? setRepository(parent.getRepository()); } } @@ -245,6 +271,8 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered { return null; } + // Capture the repository. + Repository repo = lPath.getRepository(); // Otherwise we do an actual copy. LayeredDirectoryNode newMe = null; long newBranchID = lPath.getHighestBranch(); @@ -253,19 +281,19 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered if (hasPrimaryIndirection()) { newMe = new LayeredDirectoryNode(lPath.getIndirectionPath(), - getRepository()); + repo); } else { newMe = new LayeredDirectoryNode((String)null, - getRepository()); + repo); newMe.setPrimaryIndirection(false); } } else { newMe = new LayeredDirectoryNode(this, - getRepository()); + repo); newMe.setLayerID(getLayerID()); } @@ -274,6 +302,8 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered return newMe; } + // TODO Start around here. + /** * Insert a child node without COW. * @param name The name to give the child. diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNode.java b/source/java/org/alfresco/repo/avm/LayeredFileNode.java index ddb69497e8..2e922177aa 100644 --- a/source/java/org/alfresco/repo/avm/LayeredFileNode.java +++ b/source/java/org/alfresco/repo/avm/LayeredFileNode.java @@ -43,6 +43,7 @@ public class LayeredFileNode extends FileNode implements Layered setDataBean(fData); } + // TODO Is this ever used? /** * Basically a copy constructor. * @param other The file to make a copy of. @@ -50,15 +51,65 @@ public class LayeredFileNode extends FileNode implements Layered */ public LayeredFileNode(LayeredFileNode other, Repository repo) { - // TODO Something. + long time = System.currentTimeMillis(); + BasicAttributesBean attrs = + new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes()); + attrs.setCreateDate(time); + attrs.setModDate(time); + attrs.setAccessDate(time); + attrs.setCreator("britt"); + attrs.setLastModifier("britt"); + repo.getSuperRepository().getSession().save(attrs); + fData = + new LayeredFileNodeBeanImpl(repo.getSuperRepository().issueID(), + -1L, + -1L, + null, + null, + null, + repo.getDataBean(), + attrs, + other.fData.getIndirection()); + repo.getSuperRepository().getSession().save(fData); + setDataBean(fData); } + // TODO I'm not at all sure that these are the right semantics. + /** + * Create a new one in a layered context, when it is the result of + * a renaming. + * @param file The node we are being made from. + * @param repos The Repository. + * @param srcLookup The lookup for the source parent directory. We + * need this to get calculate the correct indirection information. + * @param name The name + */ public LayeredFileNode(FileNode file, - Repository repos, - Lookup srcLookup, - String name) + Repository repos, + Lookup srcLookup, + String name) { - // TODO Something. + long time = System.currentTimeMillis(); + BasicAttributesBean attrs = + new BasicAttributesBeanImpl(file.getDataBean().getBasicAttributes()); + attrs.setCreateDate(time); + attrs.setModDate(time); + attrs.setAccessDate(time); + attrs.setCreator("britt"); + attrs.setLastModifier("britt"); + repos.getSuperRepository().getSession().save(attrs); + fData = + new LayeredFileNodeBeanImpl(repos.getSuperRepository().issueID(), + -1L, + -1L, + null, + null, + null, + repos.getDataBean(), + attrs, + srcLookup.getIndirectionPath() + "/" + name); + repos.getSuperRepository().getSession().save(fData); + setDataBean(fData); } /** @@ -108,6 +159,8 @@ public class LayeredFileNode extends FileNode implements Layered public AVMNode possiblyCopy(Lookup lPath) { // LayeredFileNodes are always copied. + // TODO This is busted. Need to set the PlainFileNode contents + // to share with underlying file node. PlainFileNode newMe = new PlainFileNode(getRepository()); newMe.setAncestor(this); return newMe; diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java index 165833a655..d67411faf4 100644 --- a/source/java/org/alfresco/repo/avm/Lookup.java +++ b/source/java/org/alfresco/repo/avm/Lookup.java @@ -75,7 +75,9 @@ public class Lookup private int fPosition; /** - * Create a new instance. + * Create a new one. + * @param repository The Repository that's being looked in. + * @param repName The name of that Repsository. */ public Lookup(Repository repository, String repName) { @@ -145,7 +147,8 @@ public class Lookup } /** - * Set the current node to one higher in the lookup. + * Set the current node to one higher in the lookup. This is used + * repeatedly during copy on write. */ public void upCurrentNode() { @@ -178,6 +181,8 @@ public class Lookup { return true; } + // Walk up the containment chain and determine if each parent-child + // relationship is one of direct containment. while (pos > 1) { DirectoryNode dir = (DirectoryNode)fComponents.get(pos - 1).getNode(); @@ -248,19 +253,17 @@ public class Lookup } LayeredDirectoryNode oNode = (LayeredDirectoryNode)node; - if (oNode.getLayerID() == fTopLayer.getLayerID()) + if (oNode.getLayerID() == fTopLayer.getLayerID() && + oNode.hasPrimaryIndirection()) { - if (oNode.hasPrimaryIndirection()) + StringBuilder builder = new StringBuilder(); + builder.append(oNode.getUnderlying()); + for (int i = pos + 1; i <= fPosition; i++) { - StringBuilder builder = new StringBuilder(); - builder.append(oNode.getUnderlying()); - for (int i = pos + 1; i <= fPosition; i++) - { - builder.append("/"); - builder.append(fComponents.get(i).getName()); - } - return builder.toString(); + builder.append("/"); + builder.append(fComponents.get(i).getName()); } + return builder.toString(); } } // TODO This is gross. There has to be a neater way to do this. diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java index 7c7ec9b1aa..aa539c62bf 100644 --- a/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java +++ b/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java @@ -28,8 +28,8 @@ import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBean; import org.alfresco.repo.avm.hibernate.PlainDirectoryNodeBeanImpl; /** + * A plain directory. No monkey tricks except for possiblyCopy. * @author britt - * */ public class PlainDirectoryNode extends DirectoryNode { @@ -44,7 +44,9 @@ public class PlainDirectoryNode extends DirectoryNode */ public PlainDirectoryNode(Repository repo) { + // Make up initial BasicAttributes. long time = System.currentTimeMillis(); + // TODO figure out how to get user information from context. BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt", "britt", "britt", @@ -62,10 +64,12 @@ public class PlainDirectoryNode extends DirectoryNode attrs, false); repo.getSuperRepository().getSession().save(fData); + setDataBean(fData); } /** - * Make one up from its bean data. + * Make one up from its bean data. Used when a PlainDirectory is + * restored from the database. * @param data The bean data. */ public PlainDirectoryNode(PlainDirectoryNodeBean data) @@ -82,11 +86,15 @@ public class PlainDirectoryNode extends DirectoryNode public PlainDirectoryNode(PlainDirectoryNode other, Repository repos) { + // Make up appropriate BasicAttributes. long time = System.currentTimeMillis(); + // TODO Need to figure out how to get user information from context. BasicAttributesBean attrs = new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes()); attrs.setModDate(time); attrs.setCreateDate(time); attrs.setAccessDate(time); + attrs.setCreator("britt"); + attrs.setLastModifier("britt"); repos.getSuperRepository().getSession().save(attrs); fData = new PlainDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(), -1, @@ -110,6 +118,8 @@ public class PlainDirectoryNode extends DirectoryNode */ public boolean addChild(String name, AVMNode child, Lookup lPath) { + // No, if a child with the given name exists. Note that uniqueness + // of names is built into the AVM, as opposed to being configurable. if (fData.getChildren().containsKey(name)) { return false; @@ -117,7 +127,7 @@ public class PlainDirectoryNode extends DirectoryNode DirectoryNode toModify = (DirectoryNode)copyOnWrite(lPath); toModify.putChild(name, child); child.setParent(toModify); - child.setRepository(toModify.getRepository()); + child.setRepository(lPath.getRepository()); return true; } @@ -128,10 +138,11 @@ public class PlainDirectoryNode extends DirectoryNode */ public boolean directlyContains(AVMNode node) { - return fData.getChildren().containsValue(node.getDataBean()); + // TODO This is inefficient; maybe use a two way map. + DirectoryEntry entry = new DirectoryEntry(node.getType(), node.getDataBean()); + return fData.getChildren().containsValue(entry); } - /** * Get a directory listing. * @param lPath The lookup path. @@ -140,6 +151,8 @@ public class PlainDirectoryNode extends DirectoryNode */ public Map getListing(Lookup lPath, int version) { + // Maybe this is pointless, but it's nice to be able to iterate + // over entries in a defined order. return new TreeMap(fData.getChildren()); } @@ -177,6 +190,7 @@ public class PlainDirectoryNode extends DirectoryNode */ public boolean removeChild(String name, Lookup lPath) { + // Can't remove it if it's not there. if (!fData.getChildren().containsKey(name)) { return false; @@ -196,6 +210,8 @@ public class PlainDirectoryNode extends DirectoryNode fData.getChildren().put(name, new DirectoryEntry(node.getType(), node.getDataBean())); } + // TODO I don't think this is at all necessary in the world without + // mounted VirtualRepositories. /** * Set repository after copy on write. * @param parent The parent after copy on write. @@ -222,13 +238,15 @@ public class PlainDirectoryNode extends DirectoryNode // Otherwise do an actual copy. DirectoryNode newMe = null; long newBranchID = lPath.getHighestBranch(); + // In a layered context a copy on write creates a new + // layered directory. if (lPath.isLayered()) { - newMe = new LayeredDirectoryNode(this, getRepository(), lPath); + newMe = new LayeredDirectoryNode(this, lPath.getRepository(), lPath); } else { - newMe = new PlainDirectoryNode(this, getRepository()); + newMe = new PlainDirectoryNode(this, lPath.getRepository()); } newMe.setAncestor(this); newMe.setBranchID(newBranchID); diff --git a/source/java/org/alfresco/repo/avm/PlainFileNode.java b/source/java/org/alfresco/repo/avm/PlainFileNode.java index 36f3db27dd..6beedadfd4 100644 --- a/source/java/org/alfresco/repo/avm/PlainFileNode.java +++ b/source/java/org/alfresco/repo/avm/PlainFileNode.java @@ -25,8 +25,8 @@ import org.alfresco.repo.avm.hibernate.PlainFileNodeBean; import org.alfresco.repo.avm.hibernate.PlainFileNodeBeanImpl; /** + * A plain old file. Contains a Content object. * @author britt - * */ public class PlainFileNode extends FileNode { @@ -47,11 +47,12 @@ public class PlainFileNode extends FileNode /** * Make one from just a repository. + * This is the constructor used when a brand new plain file is being made. * @param repos A Repository. */ public PlainFileNode(Repository repos) { - ContentBean content = new ContentBeanImpl(repos.getSuperRepository().issueContentID()); + FileContent content = new FileContent(repos.getSuperRepository()); long time = System.currentTimeMillis(); BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt", "britt", @@ -68,7 +69,7 @@ public class PlainFileNode extends FileNode null, repos.getDataBean(), attrs, - content); + content.getDataBean()); content.setRefCount(1); // Transitive persistence should take care of content. repos.getSuperRepository().getSession().save(fData); @@ -83,11 +84,15 @@ public class PlainFileNode extends FileNode public PlainFileNode(PlainFileNode other, Repository repos) { + // Setup sensible BasicAttributes. long time = System.currentTimeMillis(); + // TODO Figure out how to get user from context. BasicAttributesBean attrs = new BasicAttributesBeanImpl(other.getDataBean().getBasicAttributes()); attrs.setCreateDate(time); attrs.setModDate(time); attrs.setAccessDate(time); + attrs.setCreator("britt"); + attrs.setLastModifier("britt"); repos.getSuperRepository().getSession().save(attrs); fData = new PlainFileNodeBeanImpl(repos.getSuperRepository().issueID(), -1, @@ -103,6 +108,7 @@ public class PlainFileNode extends FileNode setDataBean(fData); } + // TODO I believe this is unnecessary (bhp) /** * Handle setting repository after a COW. * @param parent The possibly new parent directory. @@ -154,11 +160,12 @@ public class PlainFileNode extends FileNode */ public FileContent getContentForWrite(Repository repo) { + FileContent fc = new FileContent(fData.getContent()); if (fData.getContent().getRefCount() > 1) { - fData.setContent(new ContentBeanImpl(repo.getSuperRepository().issueContentID())); - // Need to copy the underlying file data. + fc = new FileContent(fc, repo.getSuperRepository()); + fData.setContent(fc.getDataBean()); } - return new FileContent(fData.getContent()); + return fc; } } diff --git a/source/java/org/alfresco/repo/avm/SuperRepository.java b/source/java/org/alfresco/repo/avm/SuperRepository.java index 2f48b8bac0..bb3d5e36d9 100644 --- a/source/java/org/alfresco/repo/avm/SuperRepository.java +++ b/source/java/org/alfresco/repo/avm/SuperRepository.java @@ -28,7 +28,7 @@ import org.hibernate.Session; * A SuperRepository is responsible for the high level implemenation of all * operations on Repositories. It is responsible for issuing Node ids, branch ids, * and layer ids. Repositories themselves are responsible for issuing version ids. - * Paths in super repositories are of the form "repositoryname:/a/b/c/d + * Paths in super repositories are of the form "repositoryname:a/b/c/d". * @author britt */ public interface SuperRepository diff --git a/source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java b/source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java index 426109fe2f..f1e9f3553a 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java +++ b/source/java/org/alfresco/repo/avm/hibernate/ContentBeanImpl.java @@ -19,8 +19,8 @@ package org.alfresco.repo.avm.hibernate; /** + * Shared Content between files. * @author britt - * */ public class ContentBeanImpl implements ContentBean { diff --git a/source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java b/source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java index a3365a559b..dfb8e1b6c1 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java +++ b/source/java/org/alfresco/repo/avm/hibernate/DirectoryEntry.java @@ -105,4 +105,39 @@ public class DirectoryEntry { return fType.name(); } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (!(obj instanceof DirectoryEntry)) + { + return false; + } + return fChild.equals(((DirectoryEntry)obj).fChild); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + return fChild.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "[" + fType.name() + "] " + fChild.getId(); + } } diff --git a/source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java b/source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java index 23241f56e9..e8a8f69fea 100644 --- a/source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java +++ b/source/java/org/alfresco/repo/avm/impl/RepositoryImpl.java @@ -76,6 +76,7 @@ public class RepositoryImpl implements Repository fData = new RepositoryBeanImpl(name, null); fSuper.getSession().save(fData); long time = System.currentTimeMillis(); + // TODO Obviously we have to figure out how to get users from context. BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt", "britt", "britt", @@ -175,7 +176,6 @@ public class RepositoryImpl implements Repository { newDir = new PlainDirectoryNode(this); } - // TODO Untangle when you are going to set a new version id. newDir.setVersion(getLatestVersion() + 1); this.setNew(newDir); dir.addChild(name, newDir, lPath); @@ -197,11 +197,15 @@ public class RepositoryImpl implements Repository new LayeredDirectoryNode(srcPath, this); if (lPath.isLayered()) { + // When a layered directory is made inside of a layered context, + // it gets its layer id from the topmost layer in its lookup + // path. LayeredDirectoryNode top = lPath.getTopLayer(); newDir.setLayerID(top.getLayerID()); } else { + // Otherwise we issue a brand new layer id. newDir.setLayerID(fSuper.issueLayerID()); } dir.addChild(name, newDir, lPath); @@ -237,6 +241,7 @@ public class RepositoryImpl implements Repository { throw new AlfrescoRuntimeException("Child exists: " + name); } + // TODO Reexamine decision to not check validity of srcPath. LayeredFileNode newFile = new LayeredFileNode(srcPath, this); dir.addChild(dstPath, newFile, lPath); @@ -291,6 +296,7 @@ public class RepositoryImpl implements Repository throw new AlfrescoRuntimeException("Not a file: " + path); } FileNode file = (FileNode)node; + file = (FileNode)file.copyOnWrite(lPath); FileContent content = file.getContentForWrite(this); return content.getOutputStream(fSuper); } @@ -356,13 +362,17 @@ public class RepositoryImpl implements Repository // Make a new version of source directly to be slid. LayeredDirectoryNode dstNode = new LayeredDirectoryNode((LayeredDirectoryNode)srcNode, this); - // Relookup the destination. + // Relookup the destination, since the lookup have been invalidated + // by the src copy on write. dPath = lookup(-1, dstPath); dstDir = (DirectoryNode)dPath.getCurrentNode(); dstDir.addChild(dstName, dstNode, dPath); } - // TODO Should this be propagated out to SuperRepository. + // TODO This is problematic. As time goes on this returns + // larger and larger data sets. Perhaps what we should do is + // provide methods for getting versions by date range, n most + // recent etc. /* (non-Javadoc) * @see org.alfresco.repo.avm.Repository#getVersions() */ @@ -392,13 +402,16 @@ public class RepositoryImpl implements Repository */ public Lookup lookup(int version, String path) { + // Make up a Lookup to hold the results. Lookup result = new Lookup(this, fData.getName()); if (path.length() == 0) { throw new AlfrescoRuntimeException("Invalid path: " + path); } String[] pathElements = path.split("/"); + // Grab the root node to start the lookup. DirectoryNode dir = null; + // Versions less than 0 mean get current. if (version < 0) { dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(fData.getRoot()); @@ -412,11 +425,14 @@ public class RepositoryImpl implements Repository } dir = (DirectoryNode)AVMNodeFactory.CreateFromBean(bean); } + // Add an entry for the root. result.add(dir, ""); if (pathElements.length == 0) { return result; } + // Now look up each path element in sequence up to one + // before the end. for (int i = 0; i < pathElements.length - 1; i++) { AVMNode child = dir.lookupChild(result, pathElements[i], version); @@ -424,6 +440,7 @@ public class RepositoryImpl implements Repository { throw new AlfrescoRuntimeException("Not found: " + pathElements[i]); } + // Every element that is not the last needs to be a directory. if (!(child instanceof DirectoryNode)) { throw new AlfrescoRuntimeException("Not a directory: " + pathElements[i]); @@ -431,6 +448,7 @@ public class RepositoryImpl implements Repository dir = (DirectoryNode)child; result.add(dir, pathElements[i]); } + // Now look up the last element. AVMNode child = dir.lookupChild(result, pathElements[pathElements.length - 1], version); if (child == null) { @@ -445,6 +463,8 @@ public class RepositoryImpl implements Repository */ public Lookup lookupDirectory(int version, String path) { + // Just do a regular lookup and assert that the last element + // is a directory. Lookup lPath = lookup(version, path); if (!(lPath.getCurrentNode() instanceof DirectoryNode)) { diff --git a/source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java b/source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java index 254228575d..f69fefd7f0 100644 --- a/source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java +++ b/source/java/org/alfresco/repo/avm/impl/SuperRepositoryImpl.java @@ -76,6 +76,8 @@ public class SuperRepositoryImpl implements SuperRepository */ private String fStorage; + // TODO Issuers are handled in a repugnant manner here. Something better + // would be nice. /** * Make a new one, initialized with the session. * @param session The session for this operation.