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 2006/08/11 16:00:03 UTC

svn commit: r430791 [1/3] - in /jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: ./ lock/ name/ nodetype/ operation/ query/ state/ util/ version/ xml/

Author: angela
Date: Fri Aug 11 07:00:00 2006
New Revision: 430791

URL: http://svn.apache.org/viewvc?rev=430791&view=rev
Log:
work in progress

jcr2spi
- HierarchyManager: fixing methods with ItemId param
- HierarchyManagerImpl(s): removing unused methods
- ItemManagerImpl: replacing NodeId as cacheKey
- ItemImpl: remove ISM field

jcr2spi/xml
- ImporterImpl renamed to SessionImporter (used for s-import only)
- xml import: Use UUID String instead of creating NodeIds
- ReferenceChangeTracker: remove usage of spi NodeId

jcr2spi/state
- SessionItemStateManager: ValueFactory not needed since QPropertyDefinition returns qualified values.

jcr2spi/util
- LogUtil: add 'saveGetJCRName' utility method

jcr2spi/locking
- locking: LockManager to use NodeState instead of NodeId
- locking: removing locktoken from Session checks if Session is lock holder

jcr2spi/query
- NodeIteratorImpl: fix commented code, that allows to retrieve
  search results from IdIterator returned from QueryInfo
- minor reformatting, javadoc

Added:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java   (with props)
Removed:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/DefaultIdKeyMap.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/IdKeyMap.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/ImporterImpl.java
Modified:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/name/CachingNamespaceResolver.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/PropertyDefinitionImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/NodeIteratorImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/RowIteratorImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeReferences.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/LogUtil.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/ReferenceChangeTracker.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewImportHandler.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/ImportHandler.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/Importer.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SysViewImportHandler.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/TargetImportHandler.java

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManager.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManager.java Fri Aug 11 07:00:00 2006
@@ -17,10 +17,8 @@
 package org.apache.jackrabbit.jcr2spi;
 
 import org.apache.jackrabbit.name.Path;
-import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
 
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.PathNotFoundException;
@@ -52,16 +50,6 @@
     Path getQPath(ItemState itemState) throws ItemNotFoundException, RepositoryException;
 
     /**
-     * Returns the qualified name of the specified item state.
-     *
-     * @param itemState state of item whose name should be returned
-     * @return
-     * @throws ItemNotFoundException
-     * @throws RepositoryException
-     */
-    QName getQName(ItemState itemState) throws ItemNotFoundException, RepositoryException;
-
-    /**
      * Returns the depth of the specified item which is equivalent to
      * <code>getQPath(id).getAncestorCount()</code>. The depth reflects the
      * absolute hierarchy level.
@@ -74,19 +62,19 @@
 
     /**
      * Returns the depth of the specified descendant relative to the given
-     * ancestor. If <code>ancestorId</code> and <code>descendantId</code>
-     * denote the same item 0 is returned. If <code>ancestorId</code> does not
+     * ancestor. If <code>ancestor</code> and <code>descendant</code>
+     * denote the same item 0 is returned. If <code>ancestor</code> does not
      * denote an ancestor -1 is returned.
      *
-     * @param ancestorId ancestor id
-     * @param descendantId descendant id
-     * @return the relative depth; -1 if <code>ancestorId</code> does not
-     *         denote an ancestor of the item denoted by <code>descendantId</code>
-     *         (or itself).
-     * @throws ItemNotFoundException if either of the specified id's does not
-     *                               denote an existing item.
-     * @throws RepositoryException   if another error occurs
+     * @param ancestor NodeState that must be an ancestor of the descendant
+     * @param descendant ItemState
+     * @return the relative depth; -1 if <code>ancestor</code> does not
+     * denote an ancestor of the item denoted by <code>descendant</code>
+     * (or itself).
+     * @throws ItemNotFoundException If either of the specified id's does not
+     * denote an existing item.
+     * @throws RepositoryException If another error occurs.
      */
-    int getRelativeDepth(NodeId ancestorId, ItemId descendantId)
+    int getRelativeDepth(NodeState ancestor, ItemState descendant)
             throws ItemNotFoundException, RepositoryException;
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java Fri Aug 11 07:00:00 2006
@@ -26,7 +26,6 @@
 import org.apache.jackrabbit.jcr2spi.util.LogUtil;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.spi.NodeId;
-import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.MalformedPathException;
@@ -46,6 +45,7 @@
 
     // TODO: TO-BE-FIXED. With SPI_ItemId rootId must not be stored separately
     protected final NodeId rootNodeId;
+
     protected final ItemStateManager itemStateManager;
     // used for outputting user-friendly paths and names
     protected final NamespaceResolver nsResolver;
@@ -58,41 +58,8 @@
         this.nsResolver = nsResolver;
     }
 
-    public NodeId getRootNodeId() {
-        return rootNodeId;
-    }
-
     //---------------------------------------------------------< overridables >
-    /**
-     * Return an item state, given its item id.
-     * <p/>
-     * Low-level hook provided for specialized derived classes.
-     *
-     * @param id item id
-     * @return item state
-     * @throws NoSuchItemStateException if the item does not exist
-     * @throws ItemStateException       if an error occurs
-     * @see ZombieHierarchyManager#getItemState(ItemId)
-     */
-    protected ItemState getItemState(ItemId id)
-            throws NoSuchItemStateException, ItemStateException {
-        return itemStateManager.getItemState(id);
-    }
-
-    /**
-     * Determines whether an item state for a given item id exists.
-     * <p/>
-     * Low-level hook provided for specialized derived classes.
-     *
-     * @param id item id
-     * @return <code>true</code> if an item state exists, otherwise
-     *         <code>false</code>
-     * @see ZombieHierarchyManager#hasItemState(ItemId)
-     */
-    protected boolean hasItemState(ItemId id) {
-        return itemStateManager.hasItemState(id);
-    }
-
+    // TODO: review the overridables as soon as status of ZombiHierarchyManager is clear
     /**
      * Returns the <code>parentUUID</code> of the given item.
      * <p/>
@@ -106,6 +73,7 @@
         return state.getParent().getNodeId();
     }
 
+    // TODO: review the overridables as soon as status of ZombiHierarchyManager is clear
     /**
      *
      * @param state
@@ -115,6 +83,7 @@
         return state.getParent();
     }
 
+    // TODO: review the overridables as soon as status of ZombiHierarchyManager is clear
     /**
      * Returns the <code>ChildNodeEntry</code> of <code>parent</code> with the
      * specified <code>uuid</code> or <code>null</code> if there's no such entry.
@@ -133,6 +102,7 @@
         return parent.getChildNodeEntry(id);
     }
 
+    // TODO: review the overridables as soon as status of ZombiHierarchyManager is clear
     /**
      * Returns the <code>ChildNodeEntry</code> of <code>parent</code> with the
      * specified <code>name</code> and <code>index</code> or <code>null</code>
@@ -221,7 +191,6 @@
      */
     protected void buildPath(Path.PathBuilder builder, ItemState state)
             throws ItemStateException, RepositoryException {
-
         // shortcut
         if (state.getId().equals(rootNodeId)) {
             builder.addRoot();
@@ -313,31 +282,6 @@
     }
 
     /**
-     * @see HierarchyManager#getQName(ItemState)
-     */
-    public QName getQName(ItemState itemState)
-            throws ItemNotFoundException, RepositoryException {
-        if (itemState.isNode()) {
-            NodeState parentState = itemState.getParent();
-            if (parentState == null) {
-                // shortcut. the given state represents the root or an orphaned node
-                return QName.ROOT;
-            }
-
-            NodeId nodeId = ((NodeState)itemState).getNodeId();
-            ChildNodeEntry entry = getChildNodeEntry(parentState, nodeId);
-            if (entry == null) {
-                String msg = "failed to resolve name of " + nodeId;
-                log.debug(msg);
-                throw new RepositoryException(msg);
-            }
-            return entry.getName();
-        } else {
-            return ((PropertyState)itemState).getQName();
-        }
-    }
-
-    /**
      * @see HierarchyManager#getDepth(ItemState)
      */
     public int getDepth(ItemState itemState) throws ItemNotFoundException, RepositoryException {
@@ -352,38 +296,25 @@
     }
 
     /**
-     * {@inheritDoc}
+     * @see HierarchyManager#getRelativeDepth(NodeState, ItemState)
      */
-    public int getRelativeDepth(NodeId ancestorId, ItemId descendantId)
+    public int getRelativeDepth(NodeState ancestor, ItemState descendant)
             throws ItemNotFoundException, RepositoryException {
-        if (ancestorId.equals(descendantId)) {
+        if (ancestor.equals(descendant)) {
             return 0;
         }
         int depth = 1;
-        try {
-            ItemState state = getItemState(descendantId);
-            NodeId parentId = getParentId(state);
-            while (parentId != null) {
-                if (parentId.equals(ancestorId)) {
-                    return depth;
-                }
-                depth++;
-                state = getItemState(parentId);
-                parentId = getParentId(state);
+        NodeState parent = descendant.getParent();
+        while (parent != null) {
+            if (parent.equals(ancestor)) {
+                return depth;
             }
-            // not an ancestor
-            return -1;
-        } catch (NoSuchItemStateException nsise) {
-            String msg = "failed to determine depth of " + descendantId
-                    + " relative to " + ancestorId;
-            log.debug(msg);
-            throw new ItemNotFoundException(msg, nsise);
-        } catch (ItemStateException ise) {
-            String msg = "failed to determine depth of " + descendantId
-                    + " relative to " + ancestorId;
-            log.debug(msg);
-            throw new RepositoryException(msg, ise);
+            depth++;
+            descendant = parent;
+            parent = descendant.getParent();
         }
+        // not an ancestor
+        return -1;
     }
 }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java Fri Aug 11 07:00:00 2006
@@ -18,7 +18,6 @@
 
 import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
-import org.apache.jackrabbit.jcr2spi.state.SessionItemStateManager;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.StaleItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateValidator;
@@ -72,7 +71,7 @@
     private int status;
     private ItemState state;
 
-    protected SessionItemStateManager itemStateMgr;
+    // protected fields for VersionImpl and VersionHistoryImpl
     protected ItemManager itemMgr;
     protected SessionImpl session;
 
@@ -84,9 +83,6 @@
     public ItemImpl(ItemManager itemManager, SessionImpl session, ItemState state,
                     ItemLifeCycleListener[] listeners) {
         this.session = session;
-        //DIFF JACKRABBIT: rep = (RepositoryImpl) session.getRepository();
-        //DIFF JACKRABBIT: stateMgr = session.getSessionItemStateManager();
-        itemStateMgr = session.getSessionItemStateManager();
 
         this.itemMgr = itemManager;
         this.state = state;
@@ -236,7 +232,7 @@
         // check state of this instance
         checkStatus();
         try {
-            itemStateMgr.save(getItemState());
+            session.getSessionItemStateManager().save(getItemState());
         } catch (StaleItemStateException e) {
             throw new InvalidItemStateException(e);
         } catch (ItemStateException e) {
@@ -274,7 +270,7 @@
         }
         // reset all transient modifications from this item and its decendants.
         try {
-            itemStateMgr.undo(state);
+            session.getSessionItemStateManager().undo(state);
         } catch (ItemStateException e) {
             String msg = "Unable to update item (" + safeGetJCRPath() + ")";
             log.debug(msg);
@@ -291,7 +287,7 @@
 
         // validation checks are performed within remove operation
         Operation rm = Remove.create(getItemState());
-        itemStateMgr.execute(rm);
+        session.getSessionItemStateManager().execute(rm);
     }
 
     //-----------------------------------------------------< ItemStateListener >

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java Fri Aug 11 07:00:00 2006
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.jcr2spi;
 
+import javax.jcr.Item;
+
 /**
  * The <code>ItemLifeCycleListener</code> interface allows an implementing
  * object to be informed about changes on an <code>Item</code> instance.
@@ -29,20 +31,20 @@
      *
      * @param item the instance which has been created
      */
-    public void itemCreated(ItemImpl item);
+    public void itemCreated(Item item);
 
     /**
-     * Called when an <code>ItemImpl</code> instance has been invalidated
+     * Called when an <code>Item</code> instance has been invalidated
      * (i.e. it has been temporarily rendered 'invalid').
      * <p/>
-     * Note that most <code>{@link javax.jcr.Item}</code>,
+     * Note that most methods of <code>{@link javax.jcr.Item}</code>,
      * <code>{@link javax.jcr.Node}</code> and <code>{@link javax.jcr.Property}</code>
-     * methods will throw an <code>InvalidItemStateException</code> when called
+     * will throw an <code>InvalidItemStateException</code> when called
      * on an 'invalidated' item.
      *
      * @param item the instance which has been discarded
      */
-    void itemInvalidated(ItemImpl item);
+    void itemInvalidated(Item item);
 
     /**
      * Called when an <code>ItemImpl</code> instance has been destroyed
@@ -55,5 +57,5 @@
      *
      * @param item the instance which has been destroyed
      */
-    void itemDestroyed(ItemImpl item);
+    void itemDestroyed(Item item);
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java Fri Aug 11 07:00:00 2006
@@ -56,7 +56,7 @@
  * <p/>
  * The <code>ItemManagerImpl</code>'s responsabilities are:
  * <ul>
- * <li>providing access to <code>Item</code> instances by <code>ItemId</code>
+ * <li>providing access to <code>Item</code> instances by <code>ItemState</code>
  * whereas <code>Node</code> and <code>Item</code> are only providing relative access.
  * <li>returning the instance of an existing <code>Node</code> or <code>Property</code>,
  * given its absolute path.
@@ -78,12 +78,14 @@
 
     private final SessionImpl session;
 
-    //private final ItemStateManager itemStateMgr;
     private final HierarchyManager hierMgr;
 
-    // TODO: TO-BE-FIXED. With SPI_ItemId simple map cannot be used any more
     /**
-     * A cache for item instances created by this <code>ItemManagerImpl</code>
+     * A cache for item instances created by this <code>ItemManagerImpl</code>.
+     * // DIFF JR:
+     * The <code>ItemState</code>s act as keys for the map. In contrast to
+     * o.a.j.core the item state are copied to transient space for reading and
+     * will therefor not change upon transient modifications.
      */
     private Map itemCache;
 
@@ -96,8 +98,8 @@
     ItemManagerImpl(HierarchyManager hierMgr, SessionImpl session) {
         this.hierMgr = hierMgr;
         this.session = session;
-        // setup item cache with weak references to items
-        itemCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK);
+        /* Setup item cache with weak keys (ItemState) and weak values (Item).*/
+        itemCache = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK);
     }
 
     //--------------------------------------------------------< ItemManager >---
@@ -165,9 +167,8 @@
      * @see ItemManager#getItem(ItemState)
      */
     public Item getItem(ItemState itemState) throws ItemNotFoundException, AccessDeniedException, RepositoryException {
-        ItemId id = itemState.getId();
         // first try to access item from cache
-        ItemImpl item = retrieveItem(id);
+        Item item = retrieveItem(itemState);
         // not yet in cache, need to create instance
         if (item == null) {
             // check privileges
@@ -251,38 +252,50 @@
 
     //----------------------------------------------< ItemLifeCycleListener >---
     /**
-     * @see ItemLifeCycleListener#itemCreated(ItemImpl)
+     * @see ItemLifeCycleListener#itemCreated(Item)
      */
-    public void itemCreated(ItemImpl item) {
+    public void itemCreated(Item item) {
+        if (!(item instanceof ItemImpl)) {
+            String msg = "Incompatible Item object: " + ItemImpl.class.getName() + " expected.";
+            throw new IllegalArgumentException(msg);
+        }
         if (log.isDebugEnabled()) {
             log.debug("created item " + item);
         }
         // add instance to cache
-        cacheItem(item);
+        cacheItem(((ItemImpl)item).getItemState(), item);
     }
 
     /**
-     * @see ItemLifeCycleListener#itemInvalidated(ItemImpl)
+     * @see ItemLifeCycleListener#itemInvalidated(Item)
      */
-    public void itemInvalidated(ItemImpl item) {
+    public void itemInvalidated(Item item) {
+        if (!(item instanceof ItemImpl)) {
+            String msg = "Incompatible Item object: " + ItemImpl.class.getName() + " expected.";
+            throw new IllegalArgumentException(msg);
+        }
         if (log.isDebugEnabled()) {
             log.debug("invalidated item " + item);
         }
         // remove instance from cache
-        evictItem(item.getId());
+        evictItem(((ItemImpl)item).getItemState());
     }
 
     /**
-     * @see ItemLifeCycleListener#itemDestroyed(ItemImpl)
+     * @see ItemLifeCycleListener#itemDestroyed(Item)
      */
-    public void itemDestroyed(ItemImpl item) {
+    public void itemDestroyed(Item item) {
+        if (!(item instanceof ItemImpl)) {
+            String msg = "Incompatible Item object: " + ItemImpl.class.getName() + " expected.";
+            throw new IllegalArgumentException(msg);
+        }
         if (log.isDebugEnabled()) {
             log.debug("destroyed item " + item);
         }
         // we're no longer interested in this item
-        item.removeLifeCycleListener(this);
+        ((ItemImpl)item).removeLifeCycleListener(this);
         // remove instance from cache
-        evictItem(item.getId());
+        evictItem(((ItemImpl)item).getItemState());
     }
 
     //-----------------------------------------------------------< Dumpable >---
@@ -290,25 +303,27 @@
      * @see Dumpable#dump(PrintStream)
      */
     public void dump(PrintStream ps) {
-        ps.println("ItemManagerImpl (" + this + ")");
+        ps.println("ItemManager (" + this + ")");
         ps.println();
         ps.println("Items in cache:");
         ps.println();
         Iterator iter = itemCache.keySet().iterator();
         while (iter.hasNext()) {
-            ItemId id = (ItemId) iter.next();
-            ItemImpl item = (ItemImpl) itemCache.get(id);
+            ItemState state = (ItemState) iter.next();
+            Item item = (Item) itemCache.get(state);
             if (item.isNode()) {
                 ps.print("Node: ");
             } else {
                 ps.print("Property: ");
             }
-            if (item.getItemState().isTransient()) {
-                ps.print("transient ");
+            if (item.isNew()) {
+                ps.print("new ");
+            } else if (item.isModified()) {
+                ps.print("modified ");
             } else {
-                ps.print("          ");
+                ps.print("- ");
             }
-            ps.println(id + "\t" + LogUtil.safeGetJCRPath(item.getItemState(), session.getNamespaceResolver(), hierMgr) + " (" + item + ")");
+            ps.println(state.getId() + "\t" + LogUtil.safeGetJCRPath(state, session.getNamespaceResolver(), hierMgr) + " (" + item + ")");
         }
     }
 
@@ -325,15 +340,21 @@
         if (!session.getAccessManager().canRead(id)) {
             if (removeFromCache) {
                 // clear cache
-                ItemImpl item = retrieveItem(id);
+                Item item = retrieveItem(state);
                 if (item != null) {
-                    evictItem(id);
+                    evictItem(state);
                 }
             }
             throw new AccessDeniedException("cannot read item " + id);
         }
     }
 
+    /**
+     *
+     * @param state
+     * @return
+     * @throws RepositoryException
+     */
     private NodeImpl createNodeInstance(NodeState state) throws RepositoryException {
         // 1. get definition of the specified node
         QNodeDefinition qnd = state.getDefinition(session.getNodeTypeRegistry());
@@ -357,6 +378,12 @@
         }
     }
 
+    /**
+     * 
+     * @param state
+     * @return
+     * @throws RepositoryException
+     */
     private PropertyImpl createPropertyInstance(PropertyState state)
             throws RepositoryException {
         // 1. get definition for the specified property
@@ -373,44 +400,42 @@
     }
 
     //-------------------------------------------------< item cache methods >---
-
-    /**
-     * Returns an item reference from the cache.
-     *
-     * @param id id of the item that should be retrieved.
-     * @return the item reference stored in the corresponding cache entry
-     *         or <code>null</code> if there's no corresponding cache entry.
-     */
-    private ItemImpl retrieveItem(ItemId id) {
-        return (ItemImpl) itemCache.get(id);
-    }
-
     /**
      * Puts the reference of an item in the cache with
      * the item's path as the key.
      *
      * @param item the item to cache
      */
-    private void cacheItem(ItemImpl item) {
-        ItemId id = item.getId();
-        if (itemCache.containsKey(id)) {
-            log.warn("overwriting cached item " + id);
+    private void cacheItem(ItemState state, Item item) {
+        if (itemCache.containsKey(state)) {
+            log.warn("overwriting cached item " + state);
         }
         if (log.isDebugEnabled()) {
-            log.debug("caching item " + id);
+            log.debug("caching item " + state);
         }
-        itemCache.put(id, item);
+        itemCache.put(state, item);
+    }
+
+    /**
+     * Returns an item reference from the cache.
+     *
+     * @param state State of the item that should be retrieved.
+     * @return the item reference stored in the corresponding cache entry
+     *         or <code>null</code> if there's no corresponding cache entry.
+     */
+    private Item retrieveItem(ItemState state) {
+        return (Item) itemCache.get(state);
     }
 
     /**
      * Removes a cache entry for a specific item.
      *
-     * @param id id of the item to remove from the cache
+     * @param itemState state of the item to remove from the cache
      */
-    private void evictItem(ItemId id) {
+    private void evictItem(ItemState itemState) {
         if (log.isDebugEnabled()) {
-            log.debug("removing item " + id + " from cache");
+            log.debug("removing item " + itemState + " from cache");
         }
-        itemCache.remove(id);
+        itemCache.remove(itemState);
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java Fri Aug 11 07:00:00 2006
@@ -38,6 +38,7 @@
 import org.apache.jackrabbit.jcr2spi.state.PropertyState;
 import org.apache.jackrabbit.jcr2spi.state.NoSuchItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeManagerImpl;
 import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeConflictException;
@@ -50,6 +51,7 @@
 import org.apache.jackrabbit.jcr2spi.operation.Update;
 import org.apache.jackrabbit.jcr2spi.lock.LockManager;
 import org.apache.jackrabbit.jcr2spi.version.VersionImpl;
+import org.apache.jackrabbit.jcr2spi.util.LogUtil;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.NodeId;
@@ -110,16 +112,15 @@
         super(itemMgr, session, state, listeners);
         this.definition = definition;
         QName nodeTypeName = state.getNodeTypeName();
-        // paranoid sanity check
+        // make sure the nodetype name is valid
         if (session.getNodeTypeManager().hasNodeType(nodeTypeName)) {
             primaryTypeName = nodeTypeName;
         } else {
-            /**
-             * todo need proper way of handling inconsistent/corrupt node type references
-             * e.g. 'flag' nodes that refer to non-registered node types
-             */
-            log.warn("Fallback to nt:unstructured due to unknown node type '" + nodeTypeName + "' of node " + safeGetJCRPath());
-            primaryTypeName = QName.NT_UNSTRUCTURED;
+            // DIFF JR: jr defines nt:unstructured as fallback.
+            // should not occur. Since nodetypes are defined by the 'server'
+            // its not possible to determine a fallback nodetype that is
+            // always available.
+            throw new IllegalArgumentException("Unknown nodetype " + LogUtil.saveGetJCRName(nodeTypeName, session.getNamespaceResolver()));
         }
     }
 
@@ -132,11 +133,11 @@
         QName qName = getQName();
         try {
             return NameFormat.format(getQName(), session.getNamespaceResolver());
-        } catch (NoPrefixDeclaredException npde) {
+        } catch (NoPrefixDeclaredException e) {
             // should never get here...
-            String msg = "internal error: encountered unregistered namespace " + qName.getNamespaceURI();
+            String msg = "Internal error while resolving qualified name " + qName.toString();
             log.debug(msg);
-            throw new RepositoryException(msg, npde);
+            throw new RepositoryException(msg, e);
         }
     }
 
@@ -148,7 +149,7 @@
         // check if root node
         NodeState parentState = getItemState().getParent();
         if (parentState == null) {
-            String msg = "root node doesn't have a parent";
+            String msg = "Root node doesn't have a parent.";
             log.debug(msg);
             throw new ItemNotFoundException(msg);
         }
@@ -204,10 +205,11 @@
         try {
             Item parent = itemMgr.getItem(parentPath);
             if (!parent.isNode()) {
-                String msg = "Cannot add a node to property " + parentPath;
+                String msg = "Cannot add a node to property " + LogUtil.safeGetJCRPath(parentPath, session.getNamespaceResolver());
                 log.debug(msg);
                 throw new ConstraintViolationException(msg);
             } else if (!(parent instanceof NodeImpl)) {
+                // should never occur
                 String msg = "Incompatible Node object: " + parent + "(" + safeGetJCRPath() + ")";
                 log.debug(msg);
                 throw new RepositoryException(msg);
@@ -242,10 +244,10 @@
         }
         // check existence
         if (!hasNode(srcChildRelPath)) {
-            throw new ItemNotFoundException(safeGetJCRPath() + " has no child node with name " + srcChildRelPath);
+            throw new ItemNotFoundException("Node " + safeGetJCRPath() + " has no child node with name " + srcChildRelPath);
         }
         if (destChildRelPath != null && !hasNode(destChildRelPath)) {
-            throw new ItemNotFoundException(safeGetJCRPath() + " has no child node with name " + destChildRelPath);
+            throw new ItemNotFoundException("Node " + safeGetJCRPath() + " has no child node with name " + destChildRelPath);
         }
 
         Path.PathElement srcName = getReorderPath(srcChildRelPath).getNameElement();
@@ -253,7 +255,7 @@
 
         NodeState nState = getNodeState();
         Operation op = ReorderNodes.create(nState, srcName, beforeName);
-        itemStateMgr.execute(op);
+        session.getSessionItemStateManager().execute(op);
     }
 
     /**
@@ -282,7 +284,7 @@
         } else {
             if (value == null) {
                 // create and remove property is a nop.
-                // TODO: check if is correct to avoid any validation exception that way
+                // TODO: check if is correct to avoid any validation exception
                 prop = null;
             } else {
                 // new property to be added
@@ -320,7 +322,7 @@
         } else {
             if (values == null) {
                 // create and remove property is a nop.
-                // TODO: check if is correct to avoid any validation exception that way
+                // TODO: check if is correct to avoid any validation exception
                 prop = null;
             } else {
                 // new property to be added
@@ -438,21 +440,16 @@
      */
     public NodeIterator getNodes() throws RepositoryException {
         checkStatus();
-        /**
-         * IMPORTANT:
-         * an implementation of Node.getNodes()
-         * must not use a class derived from TraversingElementVisitor
-         * to traverse the hierarchy because this would lead to an infinite
-         * recursion!
-         */
+        // NOTE: Don't use a class derived from TraversingElementVisitor to traverse
+        // the child nodes because this would lead to an infinite recursion.
         try {
             return itemMgr.getChildNodes(getNodeState());
         } catch (ItemNotFoundException infe) {
-            String msg = "failed to list the child nodes of " + safeGetJCRPath();
+            String msg = "Failed to list the child nodes of " + safeGetJCRPath();
             log.debug(msg);
             throw new RepositoryException(msg, infe);
         } catch (AccessDeniedException ade) {
-            String msg = "failed to list the child nodes of " + safeGetJCRPath();
+            String msg = "Failed to list the child nodes of " + safeGetJCRPath();
             log.debug(msg);
             throw new RepositoryException(msg, ade);
         }
@@ -517,14 +514,14 @@
         checkStatus();
         String name = getPrimaryNodeType().getPrimaryItemName();
         if (name == null) {
-            throw new ItemNotFoundException("No primary item present on Node " + getPath());
+            throw new ItemNotFoundException("No primary item present on Node " + safeGetJCRPath());
         }
         if (hasProperty(name)) {
             return getProperty(name);
         } else if (hasNode(name)) {
             return getNode(name);
         } else {
-            throw new ItemNotFoundException("Primary item " + name + " does not exist on Node " + getPath());
+            throw new ItemNotFoundException("Primary item " + name + " does not exist on Node " + safeGetJCRPath());
         }
     }
 
@@ -536,6 +533,7 @@
         if (!isNodeType(QName.MIX_REFERENCEABLE)) {
             throw new UnsupportedRepositoryOperationException();
         }
+        // Node is referenceable -> NodeId must contain a UUID part
         return getNodeState().getNodeId().getUUID();
     }
 
@@ -560,6 +558,7 @@
     public PropertyIterator getReferences() throws RepositoryException {
         checkStatus();
         try {
+            ItemStateManager itemStateMgr = session.getItemStateManager();
             if (itemStateMgr.hasNodeReferences(getNodeId())) {
                 NodeReferences refs = itemStateMgr.getNodeReferences(getNodeId());
                 // refs.getReferences() returns a list of Property states
@@ -570,7 +569,7 @@
                 return IteratorHelper.EMPTY;
             }
         } catch (ItemStateException e) {
-            String msg = "Unable to retrieve REFERENCE properties that refer to " + getPath();
+            String msg = "Unable to retrieve REFERENCE properties that refer to " + safeGetJCRPath();
             log.debug(msg);
             throw new RepositoryException(msg, e);
         }
@@ -674,7 +673,7 @@
         // perform the operation
         PropertyId mixinPId = session.getIdFactory().createPropertyId(getNodeId(), QName.JCR_MIXINTYPES);
         Operation op = SetMixin.create(mixinPId, allMixins);
-        itemStateMgr.execute(op);
+        session.getSessionItemStateManager().execute(op);
     }
 
     /**
@@ -709,7 +708,7 @@
         if (mixin.isNodeType(QName.MIX_REFERENCEABLE) && !entRemaining.includesNodeType(QName.MIX_REFERENCEABLE)) {
             PropertyIterator iter = getReferences();
             if (iter.hasNext()) {
-                throw new ConstraintViolationException(mixinName + " can not be removed: the node is being referenced through at least one property of type REFERENCE");
+                throw new ConstraintViolationException("Mixin type " + mixinName + " can not be removed: the node is being referenced through at least one property of type REFERENCE");
             }
         }
 
@@ -717,7 +716,7 @@
         QName[] mixins = (QName[]) remainingMixins.toArray(new QName[remainingMixins.size()]);
         PropertyId mixinPId = session.getIdFactory().createPropertyId(getNodeId(), QName.JCR_MIXINTYPES);
         Operation op = SetMixin.create(mixinPId, mixins);
-        itemStateMgr.execute(op);
+        session.getSessionItemStateManager().execute(op);
     }
 
     /**
@@ -736,10 +735,10 @@
             // then make sure the new mixin would not conflict.
             return isValidMixin(new QName[] {getQName(mixinName)});
         } catch (RepositoryException e) {
-            log.debug("Cannot add mixin '" + mixinName + "' for the following reason: " + e.getMessage());
+            log.debug("Cannot add mixin '" + mixinName + "': " + e.getMessage());
             return false;
         } catch (NodeTypeConflictException e) {
-            log.debug("Cannot add mixin '" + mixinName + "' for the following reason: " + e.getMessage());
+            log.debug("Cannot add mixin '" + mixinName + "': " + e.getMessage());
             return false;
         }
     }
@@ -761,9 +760,10 @@
         checkIsLocked();
         // DIFF JR
         if (isCheckedOut()) {
-            session.getVersionManager().checkin(getNodeId());
+            session.getVersionManager().checkin(getNodeState());
         } else {
-            log.debug("Node " + getPath() + " is already checked in.");
+            // nothing to do
+            log.debug("Node " + safeGetJCRPath() + " is already checked in.");
         }
         return getBaseVersion();
     }
@@ -776,9 +776,10 @@
         checkIsLocked();
         // DIFF JR
         if (!isCheckedOut()) {
-            session.getVersionManager().checkout(getNodeId());
+            session.getVersionManager().checkout(getNodeState());
         } else {
-            log.debug("Node " + getPath() + " is already checked out.");
+            // nothing to do
+            log.debug("Node " + safeGetJCRPath() + " is already checked out.");
         }
     }
 
@@ -813,7 +814,7 @@
 
         // check if checked out
         if (!isCheckedOut()) {
-            String msg = "Unable to finish merge. Node is checked-in: " + safeGetJCRPath();
+            String msg = "Unable to resolve merge conflict. Node is checked-in: " + safeGetJCRPath();
             log.error(msg);
             throw new VersionException(msg);
         }
@@ -827,7 +828,7 @@
             }
         }
         if (!isConflicting) {
-            String msg = "Unable to finish merge. Specified version is not in jcr:mergeFailed property: " + safeGetJCRPath();
+            String msg = "Unable to resolve merge conflict. Specified version is not in jcr:mergeFailed property: " + safeGetJCRPath();
             log.error(msg);
             throw new VersionException(msg);
         }
@@ -835,7 +836,7 @@
         if (version instanceof VersionImpl) {
             session.getVersionManager().resolveMergeConflict(getNodeId(), (NodeId) ((VersionImpl)version).getId(), done);
         } else {
-            throw new RepositoryException("Unexpected error: Failed to retrieve a valid ID for version " + version.getPath());
+            throw new RepositoryException("Incompatible Version object :" + version);
         }
     }
 
@@ -885,10 +886,12 @@
                     if (state.isNode()) {
                         failedStates.add(state);
                     } else {
-                        throw new RepositoryException("Unexpected error: NodeState expected.");
+                        // should not occur
+                        throw new RepositoryException("Merge failed with internal error: NodeState expected.");
                     }
                 } catch (ItemStateException e) {
-                    throw new RepositoryException("Unexpected error", e);
+                    // should not occur
+                    throw new RepositoryException(e);
                 }
             }
             return new LazyItemIterator(itemMgr, failedStates);
@@ -941,11 +944,11 @@
                 }
             }
             return correspondingPath;
-        } catch (NameException be) {
+        } catch (NameException e) {
             // should never get here...
-            String msg = "internal error: failed to determine relative path";
-            log.error(msg, be);
-            throw new RepositoryException(msg, be);
+            String msg = "Internal error: failed to determine relative path";
+            log.error(msg, e);
+            throw new RepositoryException(msg, e);
         } finally {
             if (srcSession != null) {
                 // we don't need the other session anymore, logout
@@ -966,7 +969,7 @@
         if (isNew()) {
             return true;
         }
-        return session.getVersionManager().isCheckedOut(getNodeId());
+        return session.getVersionManager().isCheckedOut(getNodeState());
     }
 
     /**
@@ -1008,11 +1011,11 @@
             Path nPath = getQPath(relPath);
             Path parentPath = nPath.getAncestor(1);
             NodeId nId;
-            if (session.getItemManager().itemExists(parentPath)) {
+            if (itemMgr.itemExists(parentPath)) {
                 // If the would-be parent of the location relPath is actually a
                 // property, or if a node type restriction would be violated,
                 // then a ConstraintViolationException is thrown.
-                Item parent = session.getItemManager().getItem(parentPath);
+                Item parent = itemMgr.getItem(parentPath);
                 if (parent.isNode()) {
                     try {
                         Path relQPath = parentPath.computeRelativePath(nPath);
@@ -1093,7 +1096,7 @@
         checkIsLockable();
         checkHasPendingChanges();
 
-        return session.getLockManager().lock(getNodeId(), this, isDeep, isSessionScoped);
+        return session.getLockManager().lock(getNodeState(), isDeep, isSessionScoped);
     }
 
     /**
@@ -1104,7 +1107,7 @@
         checkSupportedOption(Repository.OPTION_LOCKING_SUPPORTED);
         checkStatus();
 
-        return session.getLockManager().getLock(getNodeId());
+        return session.getLockManager().getLock(getNodeState());
     }
 
     /**
@@ -1114,7 +1117,7 @@
         checkIsLockable();
         checkHasPendingChanges();
 
-        session.getLockManager().unlock(getNodeId());
+        session.getLockManager().unlock(getNodeState());
     }
 
     /**
@@ -1132,7 +1135,7 @@
         } else {
             // DIFF JR: no separate LockManager.holdsLock
             LockManager lMgr = session.getLockManager();
-            return (lMgr.isLocked(getNodeId()) && lMgr.getLock(getNodeId()).getNode().isSame(this));
+            return (lMgr.isLocked(getNodeState()) && lMgr.getLock(getNodeState()).getNode().isSame(this));
         }
     }
 
@@ -1144,7 +1147,7 @@
         checkSupportedOption(Repository.OPTION_LOCKING_SUPPORTED);
         checkStatus();
 
-        return session.getLockManager().isLocked(getNodeId());
+        return session.getLockManager().isLocked(getNodeState());
     }
 
     //--------------------------------------------------------< public impl >---
@@ -1176,7 +1179,20 @@
      * @see ItemImpl#getQName()
      */
     QName getQName() throws RepositoryException {
-        return session.getHierarchyManager().getQName(getNodeState());
+        NodeState parentState = getNodeState().getParent();
+        if (parentState == null) {
+            // shortcut. the given state represents the root or an orphaned node
+            return QName.ROOT;
+        }
+
+        NodeId nodeId = getNodeState().getNodeId();
+        ChildNodeEntry entry = parentState.getChildNodeEntry(nodeId);
+        if (entry == null) {
+            String msg = "Failed to retrieve qualified name of Node " + nodeId;
+            log.debug(msg);
+            throw new RepositoryException(msg);
+        }
+        return entry.getName();
     }
 
 
@@ -1242,7 +1258,7 @@
             return;
         }
         // perform check
-        session.getLockManager().checkLock(getNodeId());
+        session.getLockManager().checkLock(getNodeState());
     }
 
     /**
@@ -1289,7 +1305,7 @@
         // validation check are performed by item state manager
         // NOTE: uuid is generated while creating new state.
         Operation an = AddNode.create(getNodeState(), nodeName, nodeTypeName, null);
-        itemStateMgr.execute(an);
+        session.getSessionItemStateManager().execute(an);
 
         // retrieve id of state that has been created during execution of AddNode
         NodeState childState;
@@ -1405,7 +1421,7 @@
         throws PathNotFoundException, ConstraintViolationException, RepositoryException {
         PropertyId newPId = session.getIdFactory().createPropertyId(getNodeId(), qName);
         Operation op = AddProperty.create(newPId, type, def, qvs);
-        itemStateMgr.execute(op);
+        session.getSessionItemStateManager().execute(op);
         return getProperty(qName);
     }
 
@@ -1440,18 +1456,18 @@
             QName mixinName = mixinNames[i];
             NodeType mixin = ntMgr.getNodeType(mixinName);
             if (!mixin.isMixin()) {
-                log.error(mixinName + ": not a mixin node type");
+                log.error(mixin.getName() + ": not a mixin node type");
                 return false;
             }
             NodeTypeImpl primaryType = ntMgr.getNodeType(primaryTypeName);
             // DIFF JR: replaced 'isDerivedFrom' by 'isNodeType'
             if (primaryType.isNodeType(mixinName)) {
-                log.error(mixinName + ": already contained in primary node type");
+                log.error(mixin.getName() + ": already contained in primary node type");
                 return false;
             }
             // check if adding new mixin conflicts with existing nodetypes
             if (entExisting.includesNodeType(mixinName)) {
-                log.error(mixinName + ": already contained in mixin types");
+                log.error(mixin.getName() + ": already contained in mixin types");
                 return false;
             }
         }
@@ -1653,6 +1669,7 @@
                                                                 int type,
                                                                 boolean multiValued)
             throws ConstraintViolationException, RepositoryException {
-        return session.getValidator().getApplicablePropertyDefinition(propertyName, type, multiValued, getNodeState());
+        ItemStateValidator validator = session.getValidator();
+        return validator.getApplicablePropertyDefinition(propertyName, type, multiValued, getNodeState());
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/PropertyImpl.java Fri Aug 11 07:00:00 2006
@@ -544,7 +544,7 @@
 
         // modify the state of this property
         Operation op = SetPropertyValue.create(getPropertyState(), qValues, valueType);
-        itemStateMgr.execute(op);
+        session.getSessionItemStateManager().execute(op);
     }
 
     /**

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java Fri Aug 11 07:00:00 2006
@@ -30,7 +30,7 @@
 import org.apache.jackrabbit.jcr2spi.xml.DocViewSAXEventGenerator;
 import org.apache.jackrabbit.jcr2spi.xml.SysViewSAXEventGenerator;
 import org.apache.jackrabbit.jcr2spi.xml.ImportHandler;
-import org.apache.jackrabbit.jcr2spi.xml.ImporterImpl;
+import org.apache.jackrabbit.jcr2spi.xml.SessionImporter;
 import org.apache.jackrabbit.jcr2spi.xml.Importer;
 import org.apache.jackrabbit.jcr2spi.lock.LockManager;
 import org.apache.jackrabbit.jcr2spi.version.VersionManager;
@@ -439,8 +439,8 @@
 
         Path parentPath = getQPath(parentAbsPath);
         // DIFF JR: check for writable parent is performed within importer
-        Importer importer = new ImporterImpl(parentPath, this, getHierarchyManager(), itemStateManager, validator, getIdFactory(), uuidBehavior, false);
-        return new ImportHandler(importer, getNamespaceResolver(), workspace.getNamespaceRegistry(), getIdFactory());
+        Importer importer = new SessionImporter(parentPath, this, itemStateManager, uuidBehavior);
+        return new ImportHandler(importer, getNamespaceResolver(), workspace.getNamespaceRegistry());
     }
 
     // DIFF JR: dont cast getImportContentHandler to 'ImportHandler' check for instanceof ErrorHandler
@@ -583,7 +583,7 @@
         // notify listeners that session is about to be closed
         notifyLoggingOut();
 
-        // dispose name resolver
+        // dispose name nsResolver
         nsMappings.dispose();
         // dispose session item state manager
         itemStateManager.dispose();
@@ -707,7 +707,7 @@
     }
 
     protected SessionItemStateManager createSessionItemStateManager(NodeId rootId, UpdatableItemStateManager workspaceStateManager, NamespaceResolver nsResolver) {
-        return new SessionItemStateManager(rootId, workspaceStateManager, getIdFactory(), valueFactory, getValidator(), nsResolver);
+        return new SessionItemStateManager(rootId, workspaceStateManager, getIdFactory(), getValidator(), nsResolver);
     }
 
     protected ItemManager createItemManager(HierarchyManager hierarchyMgr) {
@@ -754,11 +754,13 @@
         return itemManager;
     }
 
-    ItemStateValidator getValidator() {
+    // TODO public for SessionImport only. review
+    public ItemStateValidator getValidator() {
         return validator;
     }
 
-    IdFactory getIdFactory() {
+    // TODO public for SessionImport only. review
+    public IdFactory getIdFactory() {
         return workspace.getIdFactory();
     }
 
@@ -775,6 +777,7 @@
         return ntManager;
     }
 
+    // TODO public for SessionImport only. review
     public NodeTypeRegistry getNodeTypeRegistry() {
         return workspace.getNodeTypeRegistry();
     }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java Fri Aug 11 07:00:00 2006
@@ -252,7 +252,8 @@
     public QueryManager getQueryManager() throws RepositoryException {
         session.checkIsAlive();
         if (qManager == null) {
-            qManager = new QueryManagerImpl(session, session.getNamespaceResolver(), session.getItemManager(), wspManager);
+            qManager = new QueryManagerImpl(session, session.getNamespaceResolver(),
+                session.getItemManager(), session.getItemStateManager(), wspManager);
         }
         return qManager;
     }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java Fri Aug 11 07:00:00 2006
@@ -17,13 +17,10 @@
 package org.apache.jackrabbit.jcr2spi;
 
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
-import org.apache.jackrabbit.jcr2spi.state.NoSuchItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.name.NamespaceResolver;
-import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.spi.NodeId;
 
@@ -47,36 +44,6 @@
                                   NamespaceResolver nsResolver) {
         super(rootNodeId, provider, nsResolver);
         this.attic = attic;
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * Delivers state from attic if such exists, otherwise calls base class.
-     */
-    protected ItemState getItemState(ItemId id)
-            throws NoSuchItemStateException, ItemStateException {
-        // always check attic first
-        if (attic.hasItemState(id)) {
-            return attic.getItemState(id);
-        }
-        // delegate to base class
-        return super.getItemState(id);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * Returns <code>true</code>  if there's state on the attic for the
-     * requested item; otherwise delegates to base class.
-     */
-    protected boolean hasItemState(ItemId id) {
-        // always check attic first
-        if (attic.hasItemState(id)) {
-            return true;
-        }
-        // delegate to base class
-        return super.hasItemState(id);
     }
 
     /**

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java Fri Aug 11 07:00:00 2006
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.jcr2spi.lock;
 
-import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -24,7 +24,6 @@
 import javax.jcr.lock.LockException;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.Node;
 
 /**
  * <code>DefaultLockManager</code>...
@@ -33,23 +32,23 @@
 
     private static Logger log = LoggerFactory.getLogger(DefaultLockManager.class);
 
-    public Lock lock(NodeId nodeId, Node node, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
+    public Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }
 
-    public Lock getLock(NodeId nodeId) throws LockException, RepositoryException {
+    public Lock getLock(NodeState nodeState) throws LockException, RepositoryException {
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }
 
-    public void unlock(NodeId nodeId) throws LockException, RepositoryException {
+    public void unlock(NodeState nodeState) throws LockException, RepositoryException {
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }
 
-    public boolean isLocked(NodeId nodeId) throws RepositoryException {
+    public boolean isLocked(NodeState nodeState) throws RepositoryException {
         return false;
     }
 
-    public void checkLock(NodeId nodeId) throws LockException, RepositoryException {
+    public void checkLock(NodeState nodeState) throws LockException, RepositoryException {
         // nothing to do since locking is not supported
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java Fri Aug 11 07:00:00 2006
@@ -17,9 +17,9 @@
 package org.apache.jackrabbit.jcr2spi.lock;
 
 import javax.jcr.RepositoryException;
-import javax.jcr.Node;
 
-import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
+
 import javax.jcr.lock.Lock;
 import javax.jcr.lock.LockException;
 
@@ -27,15 +27,12 @@
  * Defines the functionality needed for locking and unlocking nodes.
  */
 public interface LockManager {
-
-    // TODO Review usage of NodeId
-
+    
     /**
      * Lock a node. Checks whether the node is not locked and then
      * returns a lock object for this node.
      *
-     * @param nodeId node id.
-     * @param node
+     * @param nodeState
      * @param isDeep whether the lock applies to this node only
      * @param isSessionScoped whether the lock is session scoped
      * @return lock object
@@ -43,43 +40,42 @@
      *         node is locked and <code>isDeep</code> is <code>true</code>
      * @see javax.jcr.Node#lock
      */
-    // TODO review params
-    Lock lock(NodeId nodeId, Node node, boolean isDeep, boolean isSessionScoped)
+    Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped)
         throws LockException, RepositoryException;
 
     /**
      * Returns the Lock object that applies to a node. This may be either a lock
      * on this node itself or a deep lock on a node above this node.
      *
-     * @param nodeId
+     * @param nodeState
      * @return lock object
      * @throws LockException if this node is not locked
      * @see javax.jcr.Node#getLock
      */
-    Lock getLock(NodeId nodeId) throws LockException, RepositoryException;
+    Lock getLock(NodeState nodeState) throws LockException, RepositoryException;
 
     /**
      * Removes the lock on a node.
      *
-     * @param nodeId
+     * @param nodeState
      * @throws LockException if this node is not locked or the session does not
      * have the correct lock token
      * @see javax.jcr.Node#unlock
      */
-    void unlock(NodeId nodeId) throws LockException, RepositoryException;
+    void unlock(NodeState nodeState) throws LockException, RepositoryException;
 
     /**
      * Returns <code>true</code> if this node is locked either as a result
      * of a lock held by this node or by a deep lock on a node above this
      * node; otherwise returns <code>false</code>.
      *
-     * @param nodeId
+     * @param nodeState
      * @return <code>true</code> if this node is locked either as a result
      * of a lock held by this node or by a deep lock on a node above this
      * node; otherwise returns <code>false</code>
      * @see javax.jcr.Node#isLocked
      */
-    boolean isLocked(NodeId nodeId) throws RepositoryException;
+    boolean isLocked(NodeState nodeState) throws RepositoryException;
 
     /**
      * Check whether the node given is locked by somebody else than the
@@ -88,11 +84,11 @@
      * contains the lock token for the lock. If the node is not locked at
      * all this method returns silently.
      *
-     * @param nodeId to check
+     * @param nodeState
      * @throws LockException if write access to the specified node is not allowed
      * @throws RepositoryException if some other error occurs
      */
-    void checkLock(NodeId nodeId) throws LockException, RepositoryException;
+    void checkLock(NodeState nodeState) throws LockException, RepositoryException;
 
     /**
      *

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java Fri Aug 11 07:00:00 2006
@@ -19,21 +19,16 @@
 import org.apache.jackrabbit.jcr2spi.ItemManager;
 import org.apache.jackrabbit.jcr2spi.SessionListener;
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
-import org.apache.jackrabbit.jcr2spi.IdKeyMap;
-import org.apache.jackrabbit.jcr2spi.DefaultIdKeyMap;
 import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
 import org.apache.jackrabbit.jcr2spi.operation.Operation;
 import org.apache.jackrabbit.jcr2spi.operation.LockOperation;
 import org.apache.jackrabbit.jcr2spi.operation.LockRelease;
 import org.apache.jackrabbit.jcr2spi.operation.LockRefresh;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.spi.EventIterator;
 import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.spi.LockInfo;
-import org.apache.jackrabbit.spi.NodeId;
-import org.apache.jackrabbit.spi.ItemId;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -45,6 +40,8 @@
 import javax.jcr.Session;
 
 import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
 
 /**
  * <code>LockManagerImpl</code>...
@@ -57,29 +54,40 @@
     private final ItemManager itemManager;
 
     /**
-     * Internal map holding all locks that where created by
-     * {@link #lock(NodeId, Node, boolean, boolean)}
-     * or accessed by {@link #getLock(NodeId)} until they end their life by
-     * an unlock (be it by the current Session or external reported by means
-     * of events).
+     * Map holding all locks that where created by this <code>Session</code> upon
+     * calls to {@link LockManager#lock(NodeState,boolean,boolean)} or to
+     * {@link LockManager#getLock(NodeState)}. The map entries are removed
+     * only if a lock ends his life by {@link Node#unlock()} or by implicit
+     * unlock upon {@link Session#logout()}.
      */
-    // TODO: TO-BE-FIXED. With SPI_ItemId simple map cannot be used any more
-    private final IdKeyMap lockMap = new DefaultIdKeyMap();
+    private final Map lockMap;
 
     public LockManagerImpl(WorkspaceManager wspManager, ItemManager itemManager) {
         this.wspManager = wspManager;
         this.itemManager = itemManager;
+        // use hard references in order to make sure, that entries refering
+        // to locks created by the current session are not removed.
+        lockMap = new HashMap();
     }
 
     /**
-     * @see LockManager#lock(NodeId, Node, boolean, boolean)
+     * @see LockManager#lock(NodeState,boolean,boolean)
      */
-    public Lock lock(NodeId nodeId, Node node, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
+    public Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
+        // retrieve node first
+        Node lhNode;
+        Item item = itemManager.getItem(nodeState);
+        if (item.isNode()) {
+            lhNode = (Node) item;
+        } else {
+            throw new RepositoryException("Internal error: ItemManager returned Property from NodeState");
+        }
+
         // execute the operation
-        Operation op = LockOperation.create(nodeId, isDeep, isSessionScoped);
+        Operation op = LockOperation.create(nodeState.getNodeId(), isDeep, isSessionScoped);
         wspManager.execute(op);
 
-        Lock lock = new LockImpl(nodeId, node, isSessionScoped);
+        Lock lock = new LockImpl(nodeState, lhNode, isSessionScoped);
         return lock;
     }
 
@@ -90,86 +98,89 @@
      * Note, that the flag indicating session-scoped lock cannot be retrieved
      * and the lock will always report 'false'.
      *
-     * @see LockManager#getLock(NodeId)
+     * @see LockManager#getLock(NodeState)
+     * @param nodeState
      */
-    public Lock getLock(NodeId nodeId) throws LockException, RepositoryException {
-        // shortcut: check if node holds a lock and lock has been accessed before
-        if (lockMap.containsKey(nodeId)) {
-            return (Lock) lockMap.get(nodeId);
+    public Lock getLock(NodeState nodeState) throws LockException, RepositoryException {
+        // shortcut: check if lock has been accessed before
+        if (lockMap.containsKey(nodeState)) {
+            return (Lock) lockMap.get(nodeState);
         }
 
         // try to retrieve parent state that holds a lock.
-        NodeState lockHoldingState = getLockHoldingState(nodeId);
+        NodeState lockHoldingState = getLockHoldingState(nodeState);
         if (lockHoldingState == null) {
-            throw new LockException("Node with id '" + nodeId + "' is not locked.");
+            throw new LockException("Node with id '" + nodeState.getNodeId() + "' is not locked.");
         } else {
-            NodeId lhNodeId = lockHoldingState.getNodeId();
-            // check again lockMap with id of lockholding node
-            if (lockMap.containsKey(lhNodeId)) {
-                return (Lock) lockMap.get(lhNodeId);
+            // check lockMap again with the lockholding state
+            if (lockMap.containsKey(lockHoldingState)) {
+                return (Lock) lockMap.get(lockHoldingState);
             }
 
-            // retrieve lock holding node. not that this may fail if the session
+            // retrieve lock holding node. note that this may fail if the session
             // does not have permission to see this node.
             Item lockHoldingNode = itemManager.getItem(lockHoldingState);
             // TODO: we don;t know if lock is session scoped -> set flag to false
             // TODO: ev. add 'isSessionScoped' to RepositoryService lock-call.
-            Lock l = new LockImpl(lhNodeId, (Node)lockHoldingNode, false);
+            Lock l = new LockImpl(lockHoldingState, (Node)lockHoldingNode, false);
             return l;
         }
     }
 
     /**
-     * @see LockManager#unlock(NodeId)
+     * @see LockManager#unlock(NodeState)
+     * @param nodeState
      */
-    public void unlock(NodeId nodeId) throws LockException, RepositoryException {
+    public void unlock(NodeState nodeState) throws LockException, RepositoryException {
         // execute the operation. Note, that its possible that the session is
         // lock holder and still the lock was never accessed. thus the lockMap
-        // does not provide sufficient information.
-        Operation op = LockRelease.create(nodeId);
+        // does not provide sufficient and relyable information.
+        Operation op = LockRelease.create(nodeState.getNodeId());
         wspManager.execute(op);
 
         // if unlock was successfull: clean up lock map and lock life cycle
         // in case the corresponding Lock object exists (and thus has been
         // added to the map.
-        if (lockMap.containsKey(nodeId)) {
-            LockImpl l = (LockImpl) lockMap.remove(nodeId);
+        if (lockMap.containsKey(nodeState)) {
+            LockImpl l = (LockImpl) lockMap.remove(nodeState);
             l.unlocked();
         }
     }
 
     /**
-     * @see LockManager#isLocked(NodeId)
+     * @see LockManager#isLocked(NodeState)
+     * @param nodeState
      */
-    public boolean isLocked(NodeId nodeId) throws RepositoryException {
+    public boolean isLocked(NodeState nodeState) throws RepositoryException {
         // shortcut: check if a given node holds a lock and lock has been
         // accessed before (thus is known to the manager).
-        if (lockMap.containsKey(nodeId)) {
+        if (lockMap.containsKey(nodeState)) {
             return true;
         } else {
             // check if any lock is present (checking lock-specific properties)
-            LockInfo lInfo = getLockInfo(nodeId);
+            LockInfo lInfo = getLockInfo(nodeState);
             return lInfo != null;
         }
     }
 
     /**
-     * @see LockManager#checkLock(NodeId)
+     * @see LockManager#checkLock(NodeState)
+     * @param nodeState
      */
-    public void checkLock(NodeId nodeId) throws LockException, RepositoryException {
+    public void checkLock(NodeState nodeState) throws LockException, RepositoryException {
         LockInfo lInfo;
         // shortcut: check if a given node holds a lock and lock has been
         // accessed before (thus is known to the manager).
-        if (lockMap.containsKey(nodeId)) {
-            lInfo = ((LockImpl)lockMap.get(nodeId)).lockInfo;
+        if (lockMap.containsKey(nodeState)) {
+            lInfo = ((LockImpl)lockMap.get(nodeState)).lockInfo;
         } else {
             // check if any lock is present (checking lock-specific properties)
-            lInfo = getLockInfo(nodeId);
+            lInfo = getLockInfo(nodeState);
         }
 
         if (lInfo != null && lInfo.getLockToken() == null) {
             // lock is present and token is null -> session is not lock-holder.
-            throw new LockException("Node with id '" + nodeId + "' is locked.");
+            throw new LockException("Node with id '" + nodeState + "' is locked.");
         }
     }
 
@@ -209,19 +220,27 @@
         // JSR170 v. 1.0.1 defines that the token of a session-scoped lock may
         // not be moved over to another session. thus removal ist not possible
         // and the lock is always present in the lock map.
-        NodeId key = null;
         Iterator it = lockMap.values().iterator();
-        while (it.hasNext() && key == null) {
+        boolean found = false;
+        // loop over cached locks to determine if the token belongs to a session
+        // scoped lock, in which case the removal must fail immediately.
+        while (it.hasNext() && !found) {
             LockImpl l = (LockImpl) it.next();
-            // break as soon as the lock associated with the given token is found.
             if (lt.equals(l.getLockToken())) {
+                // break as soon as the lock associated with the given token was found.
+                found = true;
                 if (l.isSessionScoped()) {
                     throw new LockException("Cannot remove lock token associated with a session scoped lock.");
                 }
-                key = l.nodeId;
             }
         }
 
+        if (!found) {
+            String msg = "Unable to remove lock token: lock is held by another session.";
+            log.warn(msg);
+            throw new RepositoryException(msg);
+        }
+
         // remove lock token from sessionInfo
         wspManager.removeLockToken(lt);
         // inform about this lt being removed from this session
@@ -236,13 +255,13 @@
      */
     public void loggingOut(Session session) {
         // remove any session scoped locks:
-        ItemId[] ids = (ItemId[]) lockMap.keySet().toArray(new ItemId[lockMap.size()]);
-        for (int i = 0; i < ids.length; i++) {
-            NodeId nId = (NodeId) ids[i];
-            LockImpl l = (LockImpl) lockMap.get(nId);
+        NodeState[] lhStates = (NodeState[]) lockMap.keySet().toArray(new NodeState[lockMap.size()]);
+        for (int i = 0; i < lhStates.length; i++) {
+            NodeState nState = (NodeState) lhStates[i];
+            LockImpl l = (LockImpl) lockMap.get(nState);
             if (l.isSessionScoped()) {
                 try {
-                    unlock(nId);
+                    unlock(nState);
                 } catch (RepositoryException e) {
                     log.error("Error while unlocking session scoped lock. Cleaning up local lock status.");
                     // at least clean up local lock map and the locks life cycle
@@ -268,48 +287,42 @@
     //------------------------------------------------------------< private >---
     /**
      *
-     * @param nodeId
+     * @param nodeState
      * @return
      * @throws LockException
      * @throws RepositoryException
      */
-    private LockInfo getLockInfo(NodeId nodeId) throws RepositoryException {
+    private LockInfo getLockInfo(NodeState nodeState) throws RepositoryException {
         try {
-            return wspManager.getLockInfo(nodeId);
+            return wspManager.getLockInfo(nodeState.getNodeId());
         } catch (LockException e) {
-            log.debug("No lock present on node with id '" + nodeId + "'", e);
+            log.debug("No lock present on node with id '" + nodeState.getNodeId() + "'", e);
             return null;
         }
     }
 
     /**
+     * Search nearest ancestor that is locked. Returns <code>null</code> if no
+     * lock ancestor could be found.
      *
-     * @param nodeId
-     * @return
-     * @throws RepositoryException
+     * @param nodeState <code>NodeState</code> from which searching starts.
+     * @return lock ancestor node or <code>null</code>.
      */
-    private NodeState getLockHoldingState(NodeId nodeId) throws RepositoryException {
-        try {
-            NodeState nodeState = (NodeState) wspManager.getItemState(nodeId);
-            // search nearest ancestor that is locked
-            /**
-             * FIXME should not only rely on existence of jcr:lockOwner property
-             * but also verify that node.isNodeType("mix:lockable")==true;
-             * this would have a negative impact on performance though...
-             */
-            while (!nodeState.hasPropertyName(QName.JCR_LOCKOWNER)) {
-                NodeState parentState = nodeState.getParent();
-                if (parentState == null) {
-                    // reached root state without finding a locked node
-                    return null;
-                }
-                nodeState = parentState;
+    private NodeState getLockHoldingState(NodeState nodeState) {
+        /**
+         * FIXME should not only rely on existence of jcr:lockIsDeep property
+         * but also verify that node.isNodeType("mix:lockable")==true;
+         * this would have a negative impact on performance though...
+         */
+        while (!nodeState.hasPropertyName(QName.JCR_LOCKISDEEP)) {
+            NodeState parentState = nodeState.getParent();
+            if (parentState == null) {
+                // reached root state without finding a locked node
+                return null;
             }
-            return nodeState;
-        } catch (ItemStateException e) {
-            // should not occur
-            throw new RepositoryException(e);
+            nodeState = parentState;
         }
+        return nodeState;
     }
 
     //----------------------------< Notification about modified lock-tokens >---
@@ -350,7 +363,7 @@
      */
     private class LockImpl implements Lock, InternalEventListener, LockTokenListener {
 
-        private final NodeId nodeId;
+        private final NodeState lockHoldingState;
         private final Node node;
         private final boolean isSessionScoped;
 
@@ -359,25 +372,25 @@
 
         /**
          *
-         * @param lockHoldingId The Id of the lock holding <code>Node</code>.
+         * @param lockHoldingState The NodeState of the lock holding <code>Node</code>.
          * @param lockHoldingNode the lock holding <code>Node</code> itself.
          * @param lockHoldingNode
          */
-        public LockImpl(NodeId lockHoldingId, Node lockHoldingNode, boolean isSessionScoped) throws LockException, RepositoryException {
-            this.nodeId = lockHoldingId;
+        public LockImpl(NodeState lockHoldingState, Node lockHoldingNode, boolean isSessionScoped) throws LockException, RepositoryException {
+            this.lockHoldingState = lockHoldingState;
             this.node = lockHoldingNode;
             this.isSessionScoped = isSessionScoped;
 
             // retrieve lock info from wsp-manager, in order to get the complete
             // lockInfo including lock-token, which is not available from the
             // child properties nor from the original lock request.
-            this.lockInfo = wspManager.getLockInfo(nodeId);
+            this.lockInfo = wspManager.getLockInfo(lockHoldingState.getNodeId());
 
             // register as internal listener to the wsp manager in order to get
             // informed if this lock ends his life.
             wspManager.addEventListener(this);
             // store lock in the map
-            lockMap.put(nodeId, this);
+            lockMap.put(lockHoldingState, this);
         }
 
         /**
@@ -436,12 +449,12 @@
                 throw new LockException("Session does not hold lock.");
             } else {
                 // lock is still alive -> send refresh-lock operation.
-                Operation op = LockRefresh.create(nodeId);
+                Operation op = LockRefresh.create(lockHoldingState.getNodeId());
                 wspManager.execute(op);
             }
         }
 
-        //----------------------------------------------< InternalEventListener >---
+        //------------------------------------------< InternalEventListener >---
         /**
          *
          * @param events
@@ -449,20 +462,20 @@
          */
         public void onEvent(EventIterator events, boolean isLocal) {
             if (!isLive) {
-                // since only we only monitor the removal of the lock (by means
-                // of deletion of the jcr:lockOwner property, we are not interested
+                // since we only monitor the removal of the lock (by means
+                // of deletion of the jcr:lockIsDeep property, we are not interested
                 // if the lock is not active any more.
                 return;
             }
 
             while (events.hasNext()) {
                 Event ev = events.nextEvent();
-                // if the jcr:lockOwner property related to this Lock got removed,
+                // if the jcr:lockIsDeep property related to this Lock got removed,
                 // we assume that the lock has been released.
-                if (ev.getType() == Event.PROPERTY_REMOVED &&
-                    nodeId.equals(ev.getParentId()) &&
-                    QName.JCR_LOCKOWNER.equals(ev.getQPath().getNameElement().getName())) {
-                    // TODO: check if removal jcr:lockIsDeep must be checked as well.
+                // TODO: not correct to compare nodeIds
+                if (ev.getType() == Event.PROPERTY_REMOVED
+                    && QName.JCR_LOCKISDEEP.equals(ev.getQPath().getNameElement().getName())
+                    && lockHoldingState.getNodeId().equals(ev.getParentId())) {
 
                     // this lock has been release by someone else (and not by
                     // a call to LockManager#unlock -> clean up and set isLive
@@ -470,19 +483,26 @@
                     unlocked();
                     break;
                 }
+                // TODO: JSR 283 defines that Lock-Owner is reset upon moved lt
             }
         }
 
+        //----------------------------------------------< LockTokenListener >---
         /**
+         * A lock token as been added to the current Session. If this Lock
+         * object is not yet hold by the Session (thus does not know whether
+         * the new lock token belongs to it), it must reload the LockInfo
+         * from the server.
          *
          * @param lockToken
          * @throws LockException
          * @throws RepositoryException
+         * @see LockTokenListener#lockTokenAdded(String)
          */
         public void lockTokenAdded(String lockToken) throws LockException, RepositoryException {
             if (getLockToken() == null) {
                 // could be that this affects this lock and session became
-                // lock holder -> releoad info
+                // lock holder -> releoad info to assert.
                 reloadLockInfo();
             }
         }
@@ -492,10 +512,11 @@
          * @param lockToken
          * @throws LockException
          * @throws RepositoryException
+         * @see LockTokenListener#lockTokenRemoved(String)
          */
         public void lockTokenRemoved(String lockToken) throws LockException, RepositoryException {
-            // reload lock info, if session gave away its lock-holder state
-            // for this lock
+            // reload lock info, if session gave away its lock-holder status
+            // for this lock.
             if (lockToken.equals(getLockToken())) {
                 reloadLockInfo();
             }
@@ -503,14 +524,13 @@
 
         //--------------------------------------------------------< private >---
         /**
+         * Reload the lockInfo from the server.
          *
          * @throws LockException
          * @throws RepositoryException
          */
         private void reloadLockInfo() throws LockException, RepositoryException {
-            // re-check with server, since Session.addLockToken will not
-            // automatically result in an update of the lock-map.
-            lockInfo = wspManager.getLockInfo(nodeId);
+            lockInfo = wspManager.getLockInfo(lockHoldingState.getNodeId());
         }
 
         /**
@@ -518,8 +538,8 @@
          * it from event listening
          */
         private void release() {
-            if (lockMap.containsKey(nodeId)) {
-                lockMap.remove(nodeId);
+            if (lockMap.containsKey(lockHoldingState)) {
+                lockMap.remove(lockHoldingState);
             }
             wspManager.removeEventListener(this);
         }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/name/CachingNamespaceResolver.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/name/CachingNamespaceResolver.java?rev=430791&r1=430790&r2=430791&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/name/CachingNamespaceResolver.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/name/CachingNamespaceResolver.java Fri Aug 11 07:00:00 2006
@@ -56,9 +56,8 @@
     /**
      * Creates a new <code>CachingNamespaceResolver</code>.
      *
-     * @param base      a base namespace resolver with support for listener
-     *                  registration.
-     * @param cacheSize number of mappings this resolver may cache.
+     * @param base A base namespace resolver with support for listener registration.
+     * @param cacheSize Number of mappings this nsResolver may cache.
      */
     CachingNamespaceResolver(AbstractNamespaceResolver base, int cacheSize) {
         this.base = base;
@@ -111,7 +110,6 @@
             throws NoPrefixDeclaredException {
         String jcrName = (String) qnameToJCRName.get(qName);
         if (jcrName == null) {
-            // DIFF JR: moved method from QName to NameFormat
             jcrName = NameFormat.format(qName, this);
             qnameToJCRName.put(qName, jcrName);
         }