You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2007/02/13 10:31:53 UTC

svn commit: r506927 [8/8] - in /jackrabbit/trunk/contrib/spi: jcr2spi/ jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/ jcr2spi...

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java Tue Feb 13 01:31:36 2007
@@ -23,10 +23,10 @@
 import org.apache.jackrabbit.jcr2spi.SessionImpl;
 import org.apache.jackrabbit.jcr2spi.ItemLifeCycleListener;
 import org.apache.jackrabbit.jcr2spi.LazyItemIterator;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
-import org.apache.jackrabbit.jcr2spi.state.entry.ChildNodeEntry;
-import org.apache.jackrabbit.jcr2spi.state.PropertyState;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.NameException;
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
@@ -44,12 +44,10 @@
 import javax.jcr.Item;
 import javax.jcr.Node;
 import javax.jcr.Property;
-import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.ConstraintViolationException;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collection;
 
 /**
  * <code>VersionHistoryImpl</code>...
@@ -58,23 +56,18 @@
 
     private static Logger log = LoggerFactory.getLogger(VersionHistoryImpl.class);
 
-    private final NodeState vhState;
-    private final NodeState labelNodeState;
+    private final NodeEntry vhEntry;
+    private final NodeEntry labelNodeEntry;
 
     public VersionHistoryImpl(ItemManager itemMgr, SessionImpl session,
-                              NodeState state, NodeDefinition definition,
-                              ItemLifeCycleListener[] listeners) throws VersionException {
-        super(itemMgr, session, state, definition, listeners);
-        this.vhState = state;
+                              NodeState state, ItemLifeCycleListener[] listeners)
+        throws VersionException {
+        super(itemMgr, session, state, listeners);
+        this.vhEntry = (NodeEntry) state.getHierarchyEntry();
 
         // retrieve nodestate of the jcr:versionLabels node
-        if (state.hasChildNodeEntry(QName.JCR_VERSIONLABELS)) {
-            ChildNodeEntry lnEntry = state.getChildNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
-            try {
-                labelNodeState = lnEntry.getNodeState();
-            } catch (ItemStateException e) {
-                throw new VersionException("nt:versionHistory requires a mandatory, autocreated child node jcr:versionLabels.");
-            }
+        if (vhEntry.hasNodeEntry(QName.JCR_VERSIONLABELS)) {
+            labelNodeEntry = vhEntry.getNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
         } else {
             throw new VersionException("nt:versionHistory requires a mandatory, autocreated child node jcr:versionLabels.");
         }
@@ -100,17 +93,13 @@
      */
     public Version getRootVersion() throws RepositoryException {
         checkStatus();
-        try {
-            if (vhState.hasChildNodeEntry(QName.JCR_ROOTVERSION)) {
-                NodeState vState = vhState.getChildNodeEntry(QName.JCR_ROOTVERSION, Path.INDEX_DEFAULT).getNodeState();
-                return (Version) itemMgr.getItem(vState);
-            } else {
-                String msg = "Unexpected error: VersionHistory state does not contain a root version child node entry.";
-                log.error(msg);
-                throw new RepositoryException(msg);
-            }
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
+        if (vhEntry.hasNodeEntry(QName.JCR_ROOTVERSION)) {
+            NodeEntry vEntry = vhEntry.getNodeEntry(QName.JCR_ROOTVERSION, Path.INDEX_DEFAULT);
+            return (Version) itemMgr.getItem(vEntry);
+        } else {
+            String msg = "Unexpected error: VersionHistory state does not contain a root version child node entry.";
+            log.error(msg);
+            throw new RepositoryException(msg);
         }
     }
 
@@ -122,20 +111,17 @@
      */
     public VersionIterator getAllVersions() throws RepositoryException {
         checkStatus();
-        Iterator childIter = vhState.getChildNodeEntries().iterator();
-        List versionStates = new ArrayList();
+        refreshEntry(vhEntry);
+        Iterator childIter = vhEntry.getNodeEntries();
+        List versionEntries = new ArrayList();
         // all child-nodes except from jcr:versionLabels point to Versions.
         while (childIter.hasNext()) {
-            ChildNodeEntry entry = (ChildNodeEntry) childIter.next();
-            if (!QName.JCR_VERSIONLABELS.equals(entry.getName())) {
-                try {
-                    versionStates.add(entry.getNodeState());
-                } catch (ItemStateException e) {
-                    throw new RepositoryException(e);
-                }
+            NodeEntry entry = (NodeEntry) childIter.next();
+            if (!QName.JCR_VERSIONLABELS.equals(entry.getQName())) {
+                versionEntries.add(entry);
             }
         }
-        return new LazyItemIterator(itemMgr, versionStates);
+        return new LazyItemIterator(itemMgr, versionEntries.iterator());
     }
 
     /**
@@ -149,7 +135,7 @@
     public Version getVersion(String versionName) throws VersionException, RepositoryException {
         checkStatus();
         NodeState vState = getVersionState(versionName);
-        return (Version) itemMgr.getItem(vState);
+        return (Version) itemMgr.getItem(vState.getHierarchyEntry());
     }
 
     /**
@@ -162,7 +148,7 @@
     public Version getVersionByLabel(String label) throws RepositoryException {
         checkStatus();
         NodeState vState = getVersionStateByLabel(getQLabel(label));
-        return (Version) itemMgr.getItem(vState);
+        return (Version) itemMgr.getItem(vState.getHierarchyEntry());
     }
 
     /**
@@ -179,7 +165,7 @@
         QName qLabel = getQLabel(label);
         NodeState vState = getVersionState(versionName);
         // delegate to version manager that operates on workspace directely
-        session.getVersionManager().addVersionLabel(vhState, vState, qLabel, moveLabel);
+        session.getVersionManager().addVersionLabel((NodeState) getItemState(), vState, qLabel, moveLabel);
     }
 
     /**
@@ -194,7 +180,7 @@
         QName qLabel = getQLabel(label);
         NodeState vState = getVersionStateByLabel(getQLabel(label));
         // delegate to version manager that operates on workspace directely
-        session.getVersionManager().removeVersionLabel(vhState, vState, qLabel);
+        session.getVersionManager().removeVersionLabel((NodeState) getItemState(), vState, qLabel);
     }
 
     /**
@@ -306,7 +292,7 @@
         VersionException, RepositoryException {
         checkStatus();
         NodeState vState = getVersionState(versionName);
-        session.getVersionManager().removeVersion(vhState, vState);
+        session.getVersionManager().removeVersion((NodeState) getItemState(), vState);
     }
 
     //---------------------------------------------------------------< Item >---
@@ -322,7 +308,7 @@
             // since all version histories are referenceable, protected and live
             // in the same workspace, a simple comparison of the UUIDs is sufficient.
             VersionHistoryImpl other = ((VersionHistoryImpl) otherItem);
-            return vhState.getUniqueID().equals(other.vhState.getUniqueID());
+            return vhEntry.getUniqueID().equals(other.vhEntry.getUniqueID());
         }
         return false;
     }
@@ -339,13 +325,32 @@
         throw new ConstraintViolationException("VersionHistory is protected");
     }
 
+    /**
+     * Always returns false
+     *
+     * @throws RepositoryException
+     * @see NodeImpl#isWritable()
+     */
+    protected boolean isWritable() throws RepositoryException {
+        super.isWritable();
+        return false;
+    }
     //------------------------------------------------------------< private >---
     /**
      *
      * @return
      */
-    private QName[] getQLabels() {
-        Collection labelQNames = labelNodeState.getPropertyNames();
+    private QName[] getQLabels() throws RepositoryException {
+        refreshEntry(labelNodeEntry);
+        List labelQNames = new ArrayList();
+        Iterator it = labelNodeEntry.getPropertyEntries();
+        while (it.hasNext()) {
+            PropertyEntry pe = (PropertyEntry) it.next();
+            if (QName.JCR_PRIMARYTYPE.equals(pe.getQName())) {
+                continue;
+            }
+            labelQNames.add(pe.getQName());
+        }
         return (QName[]) labelQNames.toArray(new QName[labelQNames.size()]);
     }
 
@@ -359,7 +364,8 @@
     private NodeState getVersionState(String versionName) throws VersionException, RepositoryException {
         try {
             QName vQName = NameFormat.parse(versionName, session.getNamespaceResolver());
-            ChildNodeEntry vEntry = vhState.getChildNodeEntry(vQName, Path.INDEX_DEFAULT);
+            refreshEntry(vhEntry);
+            NodeEntry vEntry = vhEntry.getNodeEntry(vQName, Path.INDEX_DEFAULT);
             if (vEntry == null) {
                 throw new VersionException("Version '" + versionName + "' does not exist in this version history.");
             } else {
@@ -381,16 +387,12 @@
      * @throws RepositoryException
      */
     private NodeState getVersionStateByLabel(QName qLabel) throws VersionException, RepositoryException {
-        if (labelNodeState.hasPropertyName(qLabel)) {
-            // retrieve reference property value -> and convert it to a NodeId
-            try {
-                PropertyState pState = labelNodeState.getPropertyState(qLabel);
-                Node version = ((Property) itemMgr.getItem(pState)).getNode();
-                return getVersionState(version.getName());
-            } catch (ItemStateException e) {
-                // should not occur. existance of property state has been checked
-                throw new RepositoryException(e);
-            }
+        refreshEntry(labelNodeEntry);
+        if (labelNodeEntry.hasPropertyEntry(qLabel)) {
+            // retrieve reference property value -> and retrieve referenced node
+            PropertyEntry pEntry = labelNodeEntry.getPropertyEntry(qLabel);
+            Node version = ((Property) itemMgr.getItem(pEntry)).getNode();
+            return getVersionState(version.getName());
         } else {
             throw new VersionException("Version with label '" + qLabel + "' does not exist.");
         }
@@ -424,6 +426,15 @@
     private void checkValidVersion(Version version) throws VersionException, RepositoryException {
         if (!version.getContainingHistory().isSame(this)) {
             throw new VersionException("Specified version '" + version.getName() + "' is not part of this history.");
+        }
+    }
+
+    private void refreshEntry(NodeEntry entry) throws RepositoryException {
+        // TODO: check again.. is this correct? or should NodeEntry be altered
+        try {
+            entry.getNodeState();
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
         }
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java Tue Feb 13 01:31:36 2007
@@ -32,7 +32,6 @@
 import javax.jcr.Node;
 import javax.jcr.Item;
 import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.ConstraintViolationException;
 import java.util.Calendar;
 
@@ -44,8 +43,8 @@
     private static Logger log = LoggerFactory.getLogger(VersionImpl.class);
 
     public VersionImpl(ItemManager itemMgr, SessionImpl session, NodeState state,
-                       NodeDefinition definition, ItemLifeCycleListener[] listeners) {
-        super(itemMgr, session, state, definition, listeners);
+                       ItemLifeCycleListener[] listeners) {
+        super(itemMgr, session, state, listeners);
     }
 
     //------------------------------------------------------------< Version >---
@@ -114,6 +113,8 @@
 
     //-----------------------------------------------------------< ItemImpl >---
     /**
+     * Always throws ConstraintViolationException since the version storage is
+     * protected.
      *
      * @throws UnsupportedRepositoryOperationException
      * @throws ConstraintViolationException
@@ -124,6 +125,16 @@
         throw new ConstraintViolationException("Version is protected");
     }
 
+    /**
+     * Always returns false
+     *
+     * @throws RepositoryException
+     * @see NodeImpl#isWritable()
+     */
+    protected boolean isWritable() throws RepositoryException {
+        super.isWritable();
+        return false;
+    }
     //------------------------------------------------------------< private >---
     /**
      *

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java Tue Feb 13 01:31:36 2007
@@ -19,6 +19,7 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.apache.jackrabbit.spi.IdIterator;
 
 import javax.jcr.RepositoryException;
@@ -169,4 +170,18 @@
      * @see javax.jcr.Node#doneMerge(Version)
      */
     public void resolveMergeConflict(NodeState nodeState, NodeState versionState, boolean done) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException;
+
+    /**
+     *
+     * @param versionState
+     * @return
+     */
+    public NodeEntry getVersionableNodeState(NodeState versionState) throws RepositoryException;
+
+    /**
+     *
+     * @param versionableState
+     * @return
+     */
+    public NodeEntry getVersionHistoryNodeState(NodeState versionableState) throws RepositoryException;
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java Tue Feb 13 01:31:36 2007
@@ -17,9 +17,9 @@
 package org.apache.jackrabbit.jcr2spi.version;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.state.Status;
 import org.apache.jackrabbit.jcr2spi.state.PropertyState;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
-import org.apache.jackrabbit.jcr2spi.state.Status;
 import org.apache.jackrabbit.jcr2spi.operation.Operation;
 import org.apache.jackrabbit.jcr2spi.operation.Checkout;
 import org.apache.jackrabbit.jcr2spi.operation.Checkin;
@@ -30,6 +30,7 @@
 import org.apache.jackrabbit.jcr2spi.operation.RemoveLabel;
 import org.apache.jackrabbit.jcr2spi.operation.RemoveVersion;
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -39,6 +40,7 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.spi.IdIterator;
+import org.apache.jackrabbit.spi.NodeId;
 
 /**
  * <code>VersionManagerImpl</code>...
@@ -55,13 +57,13 @@
 
     public void checkin(NodeState nodeState) throws RepositoryException {
         NodeState wspState = getWorkspaceState(nodeState);
-        Operation ci = Checkin.create(wspState);
+        Operation ci = Checkin.create(wspState, this);
         workspaceManager.execute(ci);
     }
 
     public void checkout(NodeState nodeState) throws RepositoryException {
         NodeState wspState = getWorkspaceState(nodeState);
-        Operation co = Checkout.create(wspState);
+        Operation co = Checkout.create(wspState, this);
         workspaceManager.execute(co);
     }
 
@@ -79,28 +81,29 @@
             return true;
         }
 
-        NodeState wspState = getWorkspaceState(nodeState);
+        NodeEntry nodeEntry = nodeState.getNodeEntry();
         try {
-            /**
-             * FIXME should not only rely on existence of jcr:isCheckedOut property
-             * but also verify that node.isNodeType("mix:versionable")==true;
-             * this would have a negative impact on performance though...
-             */
-            while (!wspState.hasPropertyName(QName.JCR_ISCHECKEDOUT)) {
-                NodeState parentState = wspState.getParent();
-                if (parentState == null) {
+            // NOTE: since the hierarchy might not be completely loaded or some
+            // entry might even not be accessible, the check may not detect
+            // a checked-in parent. ok, as long as the 'server' find out upon
+            // save or upon executing the workspace operation.
+            while (!nodeEntry.hasPropertyEntry(QName.JCR_ISCHECKEDOUT)) {
+                NodeEntry parent = nodeEntry.getParent();
+                if (parent == null) {
                     // reached root state without finding a jcr:isCheckedOut property
                     return true;
                 }
-                wspState = parentState;
+                nodeEntry = parent;
             }
-            PropertyState propState = wspState.getPropertyState(QName.JCR_ISCHECKEDOUT);
+            PropertyState propState = nodeEntry.getPropertyEntry(QName.JCR_ISCHECKEDOUT).getPropertyState();
             Boolean b = Boolean.valueOf(propState.getValue().getString());
             return b.booleanValue();
         } catch (ItemStateException e) {
-            // should not occur
-            throw new RepositoryException(e);
+            // error while accessing jcr:isCheckedOut property state.
+            // -> assume that checkedOut status is ok. see above for general
+            // notes about the capabilities of the jcr2spi implementation.
         }
+        return true;
     }
 
     public void checkIsCheckedOut(NodeState nodeState) throws VersionException, RepositoryException {
@@ -111,7 +114,7 @@
 
     public void removeVersion(NodeState versionHistoryState, NodeState versionState) throws RepositoryException {
         NodeState wspVersionState = getWorkspaceState(versionState);
-        Operation op = RemoveVersion.create(wspVersionState);
+        Operation op = RemoveVersion.create(wspVersionState, getWorkspaceState(versionHistoryState), this);
         workspaceManager.execute(op);
     }
 
@@ -148,7 +151,7 @@
 
     public IdIterator merge(NodeState nodeState, String workspaceName, boolean bestEffort) throws RepositoryException {
         NodeState wspState = getWorkspaceState(nodeState);
-        Merge op = Merge.create(wspState, workspaceName, bestEffort);
+        Merge op = Merge.create(wspState, workspaceName, bestEffort, this);
         workspaceManager.execute(op);
         return op.getFailedIds();
     }
@@ -158,6 +161,31 @@
         NodeState wspVState = getWorkspaceState(versionState);
         Operation op = ResolveMergeConflict.create(wspState, wspVState, done);
         workspaceManager.execute(op);
+    }
+
+    public NodeEntry getVersionableNodeState(NodeState versionState) throws RepositoryException {
+        try {
+            NodeState ns = versionState.getChildNodeState(QName.JCR_FROZENNODE, Path.INDEX_DEFAULT);
+            PropertyState ps = ns.getPropertyState(QName.JCR_FROZENUUID);
+            String uniqueID = ps.getValue().toString();
+
+            NodeId versionableId = workspaceManager.getIdFactory().createNodeId(uniqueID);
+            return (NodeEntry) workspaceManager.getHierarchyManager().getHierarchyEntry(versionableId);
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    public NodeEntry getVersionHistoryNodeState(NodeState versionableState) throws RepositoryException {
+        try {
+            PropertyState ps = versionableState.getPropertyState(QName.JCR_VERSIONHISTORY);
+            String uniqueID = ps.getValue().toString();
+            NodeId vhId = workspaceManager.getIdFactory().createNodeId(uniqueID);
+            return (NodeEntry) workspaceManager.getHierarchyManager().getHierarchyEntry(vhId);
+        } catch (ItemStateException e) {
+            // should not occur
+            throw new RepositoryException(e);
+        }
     }
 
     //------------------------------------------------------------< private >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java Tue Feb 13 01:31:36 2007
@@ -20,13 +20,15 @@
 import org.apache.jackrabbit.jcr2spi.state.PropertyState;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.state.SessionItemStateManager;
-import org.apache.jackrabbit.jcr2spi.state.entry.ChildNodeEntry;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.NoSuchItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateValidator;
 import org.apache.jackrabbit.jcr2spi.state.Status;
 import org.apache.jackrabbit.jcr2spi.SessionImpl;
 import org.apache.jackrabbit.jcr2spi.SessionListener;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
 import org.apache.jackrabbit.jcr2spi.util.ReferenceChangeTracker;
 import org.apache.jackrabbit.jcr2spi.util.LogUtil;
 import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
@@ -169,10 +171,11 @@
            return;
        }
 
+       NodeEntry parentEntry = (NodeEntry) parent.getHierarchyEntry();
        NodeState nodeState = null;
-       if (parent.hasChildNodeEntry(nodeInfo.getName())) {
+       if (parentEntry.hasNodeEntry(nodeInfo.getName())) {
            // a valid child node with that name already exists...
-           ChildNodeEntry entry = parent.getChildNodeEntry(nodeInfo.getName(), Path.INDEX_DEFAULT);
+           NodeEntry entry = parentEntry.getNodeEntry(nodeInfo.getName(), Path.INDEX_DEFAULT);
            NodeState existing = null;
            try {
                existing = entry.getNodeState();
@@ -208,13 +211,16 @@
                // potential uuid conflict
                try {
                    NodeId conflictingId = session.getIdFactory().createNodeId(nodeInfo.getUUID());
-                   NodeState conflicting = (NodeState) stateMgr.getItemState(conflictingId);
-                   nodeState = resolveUUIDConflict(parent, conflicting, nodeInfo);
+                   HierarchyEntry conflicting = session.getHierarchyManager().getHierarchyEntry(conflictingId);
+                   // assert that the entry is available
+                   conflicting.getItemState();
+
+                   nodeState = resolveUUIDConflict(parent, (NodeEntry) conflicting, nodeInfo);
                } catch (NoSuchItemStateException e) {
                    // no conflict: create new with given uuid
                    nodeState = importNode(nodeInfo, parent);
                } catch (ItemStateException e) {
-                   String msg = "Internal error: failed to retrieve state of " + nodeInfo.getUUID().toString();
+                   String msg = "Internal error: failed to retrieve node state";
                    log.debug(msg);
                    throw new RepositoryException(msg, e);
                }
@@ -313,8 +319,9 @@
      * @return
      * @throws RepositoryException
      */
-    NodeState resolveUUIDConflict(NodeState parent, NodeState conflicting,
-                                  NodeInfo nodeInfo) throws RepositoryException {
+    NodeState resolveUUIDConflict(NodeState parent, NodeEntry conflicting,
+                                  NodeInfo nodeInfo)
+        throws ItemExistsException, RepositoryException, ItemStateException {
         NodeState nodeState;
         switch (uuidBehavior) {
             case ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW:
@@ -339,7 +346,7 @@
             case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING:
                 // make sure conflicting node is not importTarget or an ancestor thereof
                 Path p0 = importTarget.getQPath();
-                Path p1 = conflicting.getQPath();
+                Path p1 = conflicting.getPath();
                 try {
                     if (p1.equals(p0) || p1.isAncestorOf(p0)) {
                         msg = "cannot remove ancestor node";
@@ -353,23 +360,24 @@
                     throw new RepositoryException(msg, e);
                 }
                 // do remove conflicting (recursive) including validation check
-                Operation op = Remove.create(conflicting);
+                Operation op = Remove.create(conflicting.getNodeState(), parent);
                 stateMgr.execute(op);
                 // create new with given uuid:
                 nodeState = importNode(nodeInfo, parent);
                 break;
 
             case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING:
-                // 'replace' current parent with parent of conflicting
-                parent = conflicting.getParent();
-                if (parent == null) {
+                if (conflicting.getNodeState().isRoot()) {
                     msg = "Root node cannot be replaced";
                     log.debug(msg);
                     throw new RepositoryException(msg);
                 }
-                
+
+                // 'replace' current parent with parent of conflicting
+                parent = conflicting.getParent().getNodeState();
+
                 // do remove conflicting (recursive), including validation checks
-                op = Remove.create(conflicting);
+                op = Remove.create(conflicting.getNodeState(), parent);
                 stateMgr.execute(op);
                 // create new with given uuid at same location as conflicting
                 nodeState = importNode(nodeInfo, parent);
@@ -430,7 +438,7 @@
 
                     Operation ap = AddProperty.create(parent, newName, conflicting.getType(), propDef, conflicting.getValues());
                     stateMgr.execute(ap);
-                    Operation rm = Remove.create(conflicting);
+                    Operation rm = Remove.create(conflicting, parent);
                     stateMgr.execute(rm);
                 }
             } catch (ItemStateException e) {
@@ -455,12 +463,12 @@
             // retrieve id of state that has been created during execution of AddNode
             NodeState childState;
             try {
-                List cne = parent.getChildNodeEntries(nodeInfo.getName());
+                List cne = parent.getNodeEntry().getNodeEntries(nodeInfo.getName());
                 if (def.allowsSameNameSiblings()) {
                     // TODO TOBEFIXED find proper solution. problem with same-name-siblings
-                    childState = ((ChildNodeEntry)cne.get(cne.size()-1)).getNodeState();
+                    childState = ((NodeEntry)cne.get(cne.size()-1)).getNodeState();
                 } else {
-                    childState = ((ChildNodeEntry)cne.get(0)).getNodeState();
+                    childState = ((NodeEntry)cne.get(0)).getNodeState();
                 }
             } catch (ItemStateException e) {
                 // should not occur, since nodestate is retrieved from cne-list
@@ -490,10 +498,12 @@
         PropertyState propState = null;
         QPropertyDefinition def;
 
-        if (parentState.hasPropertyName(propName)) {
+        NodeEntry parentEntry = (NodeEntry) parentState.getHierarchyEntry();
+        PropertyEntry pEntry = parentEntry.getPropertyEntry(propName);
+        if (pEntry != null) {
             // a property with that name already exists...
             try {
-                PropertyState existing = parentState.getPropertyState(propName);
+                PropertyState existing = pEntry.getPropertyState();
                 def = existing.getDefinition();
                 if (def.isProtected()) {
                     // skip protected property
@@ -546,7 +556,7 @@
             Operation ap = AddProperty.create(parentState, propName, targetType, def, values);
             stateMgr.execute(ap);
             try {
-                propState = parentState.getPropertyState(propName);
+                propState = parentEntry.getPropertyEntry(propName).getPropertyState();
             } catch (ItemStateException e) {
                 // should not occur since prop-state has been created before
                 throw new RepositoryException(e);
@@ -558,7 +568,7 @@
         }
 
         // store reference for later resolution
-        if (propState != null && propState.getType() == PropertyType.REFERENCE) {
+        if (propState.getType() == PropertyType.REFERENCE) {
             refTracker.processedReference(propState);
         }
     }
@@ -636,4 +646,4 @@
             throw new RepositoryException(msg, e);
         }
     }
-}
\ No newline at end of file
+}

Modified: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ItemInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ItemInfo.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ItemInfo.java (original)
+++ jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ItemInfo.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.spi;
 
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
 
 /**
  * <code>ItemInfo</code>...
@@ -37,4 +38,10 @@
      * @return Return true if this ItemInfo denotes a node, false otherwise
      */
     public boolean denotesNode();
+
+    /**
+     * @return Return the <code>Path</code> of the Item represented by this
+     * item info.
+     */
+    public Path getPath();
 }

Modified: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java (original)
+++ jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java Tue Feb 13 01:31:36 2007
@@ -28,4 +28,11 @@
     public boolean isDeep();
 
     public boolean isSessionScoped();
+
+    /**
+     * Returns the <code>NodeID</code> of the lock-holding Node.
+     *
+     * @return the <code>NodeID</code> of the lock-holding Node.
+     */
+    public NodeId getNodeId();
 }

Modified: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java (original)
+++ jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java Tue Feb 13 01:31:36 2007
@@ -41,7 +41,6 @@
 import javax.jcr.ReferentialIntegrityException;
 import javax.jcr.query.InvalidQueryException;
 import java.util.Map;
-import java.util.Collection;
 import java.util.Iterator;
 import java.io.InputStream;
 

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ItemInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ItemInfoImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ItemInfoImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ItemInfoImpl.java Tue Feb 13 01:31:36 2007
@@ -18,6 +18,13 @@
 
 import org.apache.jackrabbit.spi.ItemInfo;
 import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.name.Path;
+import org.apache.jackrabbit.name.PathFormat;
+import org.apache.jackrabbit.name.NamespaceResolver;
+import org.apache.jackrabbit.name.MalformedPathException;
+import org.apache.jackrabbit.webdav.property.DavPropertySet;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -29,13 +36,25 @@
     private static Logger log = LoggerFactory.getLogger(ItemInfoImpl.class);
 
     private final NodeId parentId;
+    private final Path path;
 
-    public ItemInfoImpl(NodeId parentId) {
+    public ItemInfoImpl(NodeId parentId, DavPropertySet propSet, NamespaceResolver nsResolver)
+        throws MalformedPathException {
         // set parentId
         this.parentId = parentId;
+
+        DavProperty pathProp = propSet.get(ItemResourceConstants.JCR_PATH);
+        String jcrPath = pathProp.getValue().toString();
+        path = PathFormat.parse(jcrPath, nsResolver);
+
     }
 
     public NodeId getParentId() {
         return parentId;
+    }
+
+
+    public Path getPath() {
+        return path;
     }
 }

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java Tue Feb 13 01:31:36 2007
@@ -15,21 +15,13 @@
 */
 package org.apache.jackrabbit.spi2dav;
 
-import org.apache.jackrabbit.webdav.lock.LockDiscovery;
 import org.apache.jackrabbit.webdav.lock.ActiveLock;
-import org.apache.jackrabbit.webdav.lock.Type;
-import org.apache.jackrabbit.webdav.lock.Scope;
 import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
 import org.apache.jackrabbit.spi.LockInfo;
 import org.apache.jackrabbit.spi.NodeId;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
-import javax.jcr.lock.LockException;
-import javax.jcr.RepositoryException;
-import java.util.List;
-import java.util.Iterator;
-
 /**
  * <code>LockInfoImpl</code>...
  */
@@ -37,26 +29,12 @@
 
     private static Logger log = LoggerFactory.getLogger(LockInfoImpl.class);
 
-    private ActiveLock activeLock;
+    private final ActiveLock activeLock;
+    private final NodeId nodeId;
 
-    public LockInfoImpl(LockDiscovery ld, NodeId nodeId) throws LockException, RepositoryException {
-        List activeLocks = (List) ld.getValue();
-        Iterator it = activeLocks.iterator();
-        while (it.hasNext()) {
-            ActiveLock l = (ActiveLock) it.next();
-            Scope sc = l.getScope();
-            if (l.getType() == Type.WRITE && (sc == Scope.EXCLUSIVE || sc == ItemResourceConstants.EXCLUSIVE_SESSION)) {
-                if (activeLock != null) {
-                    throw new RepositoryException("Node " + nodeId + " contains multiple exclusive write locks.");
-                } else {
-                    activeLock = l;
-                }
-            }
-        }
-
-        if (activeLock == null) {
-            throw new LockException("No lock present on node " + nodeId);
-        }
+    public LockInfoImpl(ActiveLock activeLock, NodeId nodeId) {
+        this.activeLock = activeLock;
+        this.nodeId = nodeId;
     }
 
     public String getLockToken() {
@@ -73,5 +51,9 @@
 
     public boolean isSessionScoped() {
         return activeLock.getScope() == ItemResourceConstants.EXCLUSIVE_SESSION;
+    }
+
+    public NodeId getNodeId() {
+        return nodeId;
     }
 }

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java Tue Feb 13 01:31:36 2007
@@ -25,6 +25,7 @@
 import org.apache.jackrabbit.name.NameFormat;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.Path;
+import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.spi.NodeInfo;
 import org.apache.jackrabbit.spi.IdIterator;
 import org.apache.jackrabbit.spi.NodeId;
@@ -56,8 +57,8 @@
     private final List propertyIds = new ArrayList();
 
     public NodeInfoImpl(NodeId id, NodeId parentId, DavPropertySet propSet,
-                        NamespaceResolver nsResolver) throws RepositoryException {
-        super(parentId);
+                        NamespaceResolver nsResolver) throws RepositoryException, MalformedPathException {
+        super(parentId, propSet, nsResolver);
 
         // set id
         this.id = id;

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/PropertyInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/PropertyInfoImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/PropertyInfoImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/PropertyInfoImpl.java Tue Feb 13 01:31:36 2007
@@ -22,6 +22,7 @@
 import org.apache.jackrabbit.webdav.property.DavPropertySet;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.value.ValueFormat;
 import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.jackrabbit.spi.PropertyInfo;
@@ -53,9 +54,9 @@
     public PropertyInfoImpl(PropertyId id, NodeId parentId, DavPropertySet propSet,
                             NamespaceResolver nsResolver, ValueFactory valueFactory,
                             QValueFactory qValueFactory)
-        throws RepositoryException, DavException, IOException {
+        throws RepositoryException, DavException, IOException, MalformedPathException {
 
-        super(parentId);
+        super(parentId, propSet, nsResolver);
         // set id
         this.id = id;
 

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Tue Feb 13 01:31:36 2007
@@ -78,6 +78,7 @@
 import org.apache.jackrabbit.webdav.lock.Scope;
 import org.apache.jackrabbit.webdav.lock.Type;
 import org.apache.jackrabbit.webdav.lock.LockDiscovery;
+import org.apache.jackrabbit.webdav.lock.ActiveLock;
 import org.apache.jackrabbit.webdav.transaction.TransactionConstants;
 import org.apache.jackrabbit.webdav.transaction.TransactionInfo;
 import org.apache.jackrabbit.webdav.xml.DomUtil;
@@ -106,6 +107,7 @@
 import org.apache.jackrabbit.name.IllegalNameException;
 import org.apache.jackrabbit.name.UnknownPrefixException;
 import org.apache.jackrabbit.name.AbstractNamespaceResolver;
+import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.spi.Batch;
 import org.apache.jackrabbit.spi.RepositoryService;
 import org.apache.jackrabbit.spi.SessionInfo;
@@ -242,9 +244,9 @@
         }
     }
 
-    private static boolean isLockMethod(DavMethod method) {
+    private static boolean isUnLockMethod(DavMethod method) {
         int code = DavMethods.getMethodCode(method.getName());
-        return DavMethods.DAV_LOCK == code || DavMethods.DAV_UNLOCK == code;
+        return DavMethods.DAV_UNLOCK == code;
     }
 
     private static void initMethod(DavMethod method, SessionInfo sessionInfo, boolean addIfHeader) {
@@ -374,7 +376,7 @@
      */
     private void execute(DavMethod method, SessionInfo sessionInfo) throws RepositoryException {
         try {
-            initMethod(method, sessionInfo, !isLockMethod(method));
+            initMethod(method, sessionInfo, !isUnLockMethod(method));
 
             getClient(sessionInfo).executeMethod(method);
             method.checkSuccess();
@@ -717,6 +719,7 @@
         nameSet.add(ItemResourceConstants.JCR_MIXINNODETYPES);
         nameSet.add(ItemResourceConstants.JCR_REFERENCES);
         nameSet.add(ItemResourceConstants.JCR_UUID);
+        nameSet.add(ItemResourceConstants.JCR_PATH);
         nameSet.add(DavPropertyName.RESOURCETYPE);
 
         DavMethodBase method = null;
@@ -746,6 +749,12 @@
             }
 
             DavPropertySet propSet = nodeResponse.getProperties(DavServletResponse.SC_OK);
+            Object type = propSet.get(DavPropertyName.RESOURCETYPE).getValue();
+            if (type == null) {
+                // the given id points to a Property instead of a Node
+                throw new ItemNotFoundException("No node for id " + nodeId);
+            }
+
             NodeId parentId = getParentId(propSet, sessionInfo);
             NodeId id = uriResolver.buildNodeId(parentId, nodeResponse, sessionInfo.getWorkspaceName());
 
@@ -777,6 +786,8 @@
             throw new RepositoryException(e);
         } catch (DavException e) {
             throw ExceptionConverter.generate(e);
+        } catch (MalformedPathException e) {
+            throw new RepositoryException(e);
         } finally {
             if (method != null) {
                 method.releaseConnection();
@@ -797,6 +808,7 @@
         nameSet.add(ItemResourceConstants.JCR_MIXINNODETYPES);
         nameSet.add(ItemResourceConstants.JCR_REFERENCES);
         nameSet.add(ItemResourceConstants.JCR_UUID);
+        nameSet.add(ItemResourceConstants.JCR_PATH);
         nameSet.add(DavPropertyName.RESOURCETYPE);
 
         DavMethodBase method = null;
@@ -856,6 +868,7 @@
         nameSet.add(ItemResourceConstants.JCR_TYPE);
         nameSet.add(ItemResourceConstants.JCR_VALUE);
         nameSet.add(ItemResourceConstants.JCR_VALUES);
+        nameSet.add(ItemResourceConstants.JCR_PATH);
         nameSet.add(DavPropertyName.RESOURCETYPE);
 
         PropFindMethod method = null;
@@ -870,7 +883,6 @@
                 throw new ItemNotFoundException("Unable to retrieve the property with id " + propertyId);
             }
 
-
             DavPropertySet propSet = responses[0].getProperties(DavServletResponse.SC_OK);
             NodeId parentId = getParentId(propSet, sessionInfo);
             PropertyId id = uriResolver.buildPropertyId(parentId, responses[0], sessionInfo.getWorkspaceName());
@@ -883,6 +895,8 @@
             throw new RepositoryException(e);
         } catch (DavException e) {
             throw ExceptionConverter.generate(e);
+        } catch (MalformedPathException e) {
+            throw new RepositoryException(e);
         } finally {
             if (method != null) {
                 method.releaseConnection();
@@ -996,6 +1010,7 @@
         // set of Dav-properties to be retrieved
         DavPropertyNameSet nameSet = new DavPropertyNameSet();
         nameSet.add(DavPropertyName.LOCKDISCOVERY);
+        nameSet.add(ItemResourceConstants.JCR_PARENT);
 
         PropFindMethod method = null;
         try {
@@ -1015,11 +1030,12 @@
             DavPropertySet ps = responses[0].getProperties(DavServletResponse.SC_OK);
             if (ps.contains(DavPropertyName.LOCKDISCOVERY)) {
                 DavProperty p = ps.get(DavPropertyName.LOCKDISCOVERY);
-                return new LockInfoImpl(LockDiscovery.createFromXml(p.toXml(domFactory)), nodeId);
-            } else {
+                LockDiscovery ld = LockDiscovery.createFromXml(p.toXml(domFactory));
+                NodeId parentId = getParentId(ps, sessionInfo);
+                return retrieveLockInfo(ld, sessionInfo, nodeId, parentId);
+            }  else {
                 throw new LockException("No Lock present on node with id " + nodeId);
             }
-
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {
@@ -1046,7 +1062,7 @@
             sessionInfo.addLockToken(lockToken);
 
             LockDiscovery disc = method.getResponseAsLockDiscovery();
-            return new LockInfoImpl(disc, nodeId);
+            return retrieveLockInfo(disc, sessionInfo, nodeId, null);
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {
@@ -1082,6 +1098,40 @@
         execute(method, sessionInfo);
 
         sessionInfo.removeLockToken(lockToken);
+    }
+
+    private LockInfo retrieveLockInfo(LockDiscovery lockDiscovery, SessionInfo sessionInfo,
+                                      NodeId nodeId, NodeId parentId)
+        throws LockException, RepositoryException {
+        List activeLocks = (List) lockDiscovery.getValue();
+        Iterator it = activeLocks.iterator();
+        ActiveLock activeLock = null;
+        while (it.hasNext()) {
+            ActiveLock l = (ActiveLock) it.next();
+            Scope sc = l.getScope();
+            if (l.getType() == Type.WRITE && (sc == Scope.EXCLUSIVE || sc == ItemResourceConstants.EXCLUSIVE_SESSION)) {
+                if (activeLock != null) {
+                    throw new RepositoryException("Node " + nodeId + " contains multiple exclusive write locks.");
+                } else {
+                    activeLock = l;
+                }
+            }
+        }
+        if (activeLock == null) {
+            throw new LockException("No lock present on node " + nodeId);
+        }
+        if (activeLock.isDeep() && parentId != null) {
+            // try if lock is inherited
+            try {
+                return getLockInfo(sessionInfo, parentId);
+            } catch (LockException e) {
+                // no lock on parent
+                return new LockInfoImpl(activeLock, nodeId);
+            }
+        }
+        // no deep lock or parentID == null or lock is not present on parent
+        // -> nodeID is lockHolding Id.
+        return new LockInfoImpl(activeLock, nodeId);
     }
 
     /**