From e5eb45da0fd4adb0d3353357b48a80e4d1c3c7ef Mon Sep 17 00:00:00 2001 From: Britt Park Date: Tue, 18 Jul 2006 19:08:21 +0000 Subject: [PATCH] Introducing a new API call into AVMService: LayeringDescriptor getLayeringInfo(version, path); LayeringDescriptor has three methods: isBackground() Is the looked up node a background node. getPathAVMStore() Gets a descriptor for the store the path was looked up in. getNativeAVMStore() Gets the store that the actual node was found in. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3348 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/repo/avm/AVMRepository.java | 17 ++++ .../org/alfresco/repo/avm/AVMService.java | 8 ++ .../org/alfresco/repo/avm/AVMServiceImpl.java | 26 ++++++ .../org/alfresco/repo/avm/AVMServiceTest.java | 43 ++++++++++ .../repo/avm/LayeredDirectoryNodeImpl.java | 4 +- .../alfresco/repo/avm/LayeringDescriptor.java | 83 +++++++++++++++++++ source/java/org/alfresco/repo/avm/Lookup.java | 48 +++++++++-- .../HibernateRetryingTransaction.java | 1 + 8 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 source/java/org/alfresco/repo/avm/LayeringDescriptor.java diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index b536ef00a7..cef468a20e 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -733,6 +733,23 @@ class AVMRepository return dirNode.lookupChild(dir, name); } + /** + * Get information about layering of a path. + * @param version The version to look under. + * @param path The full avm path. + * @return A LayeringDescriptor. + */ + public LayeringDescriptor getLayeringInfo(int version, String path) + { + fLookupCount.set(1); + String [] pathParts = SplitPath(path); + AVMStore store = getAVMStoreByName(pathParts[0], false); + Lookup lookup = store.lookup(version, pathParts[1], false); + return new LayeringDescriptor(!lookup.getDirectlyContained(), + lookup.getAVMStore().getDescriptor(), + lookup.getFinalStore().getDescriptor()); + } + /** * Lookup a directory specifically. * @param version The version to look under. diff --git a/source/java/org/alfresco/repo/avm/AVMService.java b/source/java/org/alfresco/repo/avm/AVMService.java index cadf2a1d17..c0fd1b964f 100644 --- a/source/java/org/alfresco/repo/avm/AVMService.java +++ b/source/java/org/alfresco/repo/avm/AVMService.java @@ -298,4 +298,12 @@ public interface AVMService */ public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, AVMNodeDescriptor right); + + /** + * Get layering information about a path. + * @param version The version to look under. + * @param path The full AVM path. + * @return A LayeringDescriptor. + */ + public LayeringDescriptor getLayeringInfo(int version, String path); } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index f26ba79a00..49e8fa4360 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -972,6 +972,32 @@ public class AVMServiceImpl implements AVMService fTransaction.perform(doit, true); } + /** + * Get layering information about a path. + * @param version The version to look under. + * @param path The full AVM path. + * @return A LayeringDescriptor. + */ + public LayeringDescriptor getLayeringInfo(final int version, final String path) + { + if (path == null) + { + throw new AVMBadArgumentException("Null path: " + path); + } + class TxnCallback implements RetryingTransactionCallback + { + public LayeringDescriptor descriptor; + + public void perform() + { + descriptor = fAVMRepository.getLayeringInfo(version, path); + } + } + TxnCallback doit = new TxnCallback(); + fTransaction.perform(doit, false); + return doit.descriptor; + } + /** * Get the common ancestor of two nodes if one exists. * @param left The first node. diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index acd07dfa49..177b2912e0 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -36,6 +36,49 @@ import org.alfresco.repo.avm.util.BulkLoader; */ public class AVMServiceTest extends AVMServiceTestBase { + /** + * Test layering info. + */ + public void testLayeringInfo() + { + try + { + setupBasicTree(); + fService.createAVMStore("layer"); + fService.createLayeredDirectory("main:/a", "layer:/", "alayer"); + fService.createSnapshot("layer"); + LayeringDescriptor info = fService.getLayeringInfo(-1, "layer:/alayer"); + assertFalse(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("layer", info.getNativeAVMStore().getName()); + info = fService.getLayeringInfo(-1, "layer:/alayer/b/c"); + assertTrue(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("main", info.getNativeAVMStore().getName()); + fService.createFile("layer:/alayer/b", "figs").close(); + fService.createSnapshot("layer"); + info = fService.getLayeringInfo(-1, "layer:/alayer/b/figs"); + assertFalse(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("layer", info.getNativeAVMStore().getName()); + info = fService.getLayeringInfo(-1, "layer:/alayer/b/c"); + assertTrue(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("main", info.getNativeAVMStore().getName()); + fService.createLayeredDirectory("layer:/alayer/b", "layer:/", "blayer"); + fService.createSnapshot("layer"); + info = fService.getLayeringInfo(-1, "layer:/blayer/c"); + assertEquals("main", info.getNativeAVMStore().getName()); + info = fService.getLayeringInfo(-1, "layer:/blayer/figs"); + assertEquals("layer", info.getNativeAVMStore().getName()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + fail(); + } + } + /** * Another test of renaming in a layer. */ diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java index fb4da89283..f9df3867fa 100644 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java @@ -429,7 +429,9 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec { Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath)); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); - return dir.lookupChild(lookup, name, -1, false); + AVMNode retVal = dir.lookupChild(lookup, name, -1, false); + lPath.setFinalStore(lookup.getFinalStore()); + return retVal; } catch (AVMException re) { diff --git a/source/java/org/alfresco/repo/avm/LayeringDescriptor.java b/source/java/org/alfresco/repo/avm/LayeringDescriptor.java new file mode 100644 index 0000000000..12cc10ac95 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/LayeringDescriptor.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.repo.avm; + +/** + * A value class containing information about the layering state of a looked up + * node. + * @author britt + */ +public class LayeringDescriptor +{ + /** + * Whether the node is a background node. + */ + private boolean fIsBackground; + + /** + * The store descriptor for the top level lookup. + */ + private AVMStoreDescriptor fContainingStore; + + /** + * The store descriptor for the layer on which the node was finally found. + */ + private AVMStoreDescriptor fFinalStore; + + /** + * Make one up. + * @param isBackground + * @param containingStore + * @param finalStore + */ + public LayeringDescriptor(boolean isBackground, + AVMStoreDescriptor containingStore, + AVMStoreDescriptor finalStore) + { + fIsBackground = isBackground; + fContainingStore = containingStore; + fFinalStore = finalStore; + } + + /** + * Get the store that the original path is in. + * @return An AVMStoreDescriptor. + */ + public AVMStoreDescriptor getPathAVMStore() + { + return fContainingStore; + } + + /** + * Get the store that the final node was in. + * @return An AVMStoreDescriptor. + */ + public AVMStoreDescriptor getNativeAVMStore() + { + return fFinalStore; + } + + /** + * Is the node a background node. + * @return Whether the node is a background node. + */ + public boolean isBackground() + { + return fIsBackground; + } +} diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java index eed9dfd95a..92d29af0ba 100644 --- a/source/java/org/alfresco/repo/avm/Lookup.java +++ b/source/java/org/alfresco/repo/avm/Lookup.java @@ -43,6 +43,11 @@ class Lookup */ private List fComponents; + /** + * The final store in resolving layers. + */ + private AVMStore fFinalStore; + /** * Whether, at this point, a layered node has been hit. * Used while building a Lookup. @@ -96,6 +101,7 @@ class Lookup fLowestLayerIndex = -1; fNeedsCopying = false; fDirectlyContained = true; + fFinalStore = store; } /** @@ -110,6 +116,11 @@ class Lookup LookupComponent comp = new LookupComponent(); comp.setName(name); comp.setNode(node); + if (fPosition >= 0 && fDirectlyContained && + fComponents.get(fPosition).getNode().getType() == AVMNodeType.LAYERED_DIRECTORY) + { + fDirectlyContained = ((DirectoryNode)fComponents.get(fPosition).getNode()).directlyContains(node); + } if (!write) { if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) @@ -128,11 +139,6 @@ class Lookup fPosition++; return; } - if (fPosition >= 0 && fDirectlyContained && - fComponents.get(fPosition).getNode().getType() == AVMNodeType.LAYERED_DIRECTORY) - { - fDirectlyContained = ((DirectoryNode)fComponents.get(fPosition).getNode()).directlyContains(node); - } if (!node.getIsNew()) { fNeedsCopying = true; @@ -331,8 +337,40 @@ class Lookup return builder.toString(); } + /** + * Gets the final name in the lookup. + * @return The final name in the lookup. + */ public String getBaseName() { return fComponents.get(fPosition).getName(); } + + /** + * Set the final store the lookup occurred in. + * @param store The store to set. + */ + public void setFinalStore(AVMStore store) + { + fFinalStore = store; + } + + /** + * Get the final store traversed during lookup. + * @return The final store traversed. + */ + public AVMStore getFinalStore() + { + return fFinalStore; + } + + /** + * Get whether the node looked up is directly contained from the + * original root. + * @return Whether the node looked up is directly contained. + */ + public boolean getDirectlyContained() + { + return fDirectlyContained; + } } diff --git a/source/java/org/alfresco/repo/avm/hibernate/HibernateRetryingTransaction.java b/source/java/org/alfresco/repo/avm/hibernate/HibernateRetryingTransaction.java index efa140e5ed..4893272555 100644 --- a/source/java/org/alfresco/repo/avm/hibernate/HibernateRetryingTransaction.java +++ b/source/java/org/alfresco/repo/avm/hibernate/HibernateRetryingTransaction.java @@ -40,6 +40,7 @@ import org.springframework.transaction.TransactionStatus; public class HibernateRetryingTransaction extends HibernateTemplate implements RetryingTransaction { private static Logger fgLogger = Logger.getLogger(HibernateRetryingTransaction.class); + /** * The transaction manager. */