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 [4/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...

Propchange: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

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?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- 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 Tue Feb 13 01:31:36 2007
@@ -19,18 +19,22 @@
 import org.apache.jackrabbit.jcr2spi.ItemManager;
 import org.apache.jackrabbit.jcr2spi.SessionListener;
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
-import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
 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.Status;
-import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.spi.Event;
+import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
+import org.apache.jackrabbit.jcr2spi.state.ItemStateLifeCycleListener;
+import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.state.PropertyState;
 import org.apache.jackrabbit.spi.LockInfo;
-import org.apache.jackrabbit.spi.EventBundle;
-import org.apache.jackrabbit.spi.EventFilter;
+import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.name.QName;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -40,13 +44,10 @@
 import javax.jcr.Node;
 import javax.jcr.Item;
 import javax.jcr.Session;
-import javax.jcr.UnsupportedRepositoryOperationException;
 
 import java.util.Iterator;
 import java.util.Map;
 import java.util.HashMap;
-import java.util.Collection;
-import java.util.Collections;
 
 /**
  * <code>LockManagerImpl</code>...
@@ -62,6 +63,7 @@
      */
     private final WorkspaceManager wspManager;
     private final ItemManager itemManager;
+    private final CacheBehaviour cacheBehaviour;
 
     /**
      * Map holding all locks that where created by this <code>Session</code> upon
@@ -72,9 +74,11 @@
      */
     private final Map lockMap;
 
-    public LockManagerImpl(WorkspaceManager wspManager, ItemManager itemManager) {
+    public LockManagerImpl(WorkspaceManager wspManager, ItemManager itemManager,
+                           CacheBehaviour cacheBehaviour) {
         this.wspManager = wspManager;
         this.itemManager = itemManager;
+        this.cacheBehaviour = cacheBehaviour;
         // use hard references in order to make sure, that entries refering
         // to locks created by the current session are not removed.
         lockMap = new HashMap();
@@ -84,15 +88,12 @@
      * @see LockManager#lock(NodeState,boolean,boolean)
      */
     public Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
-        // TODO: TOBEFIXED
-        if (nodeState.isWorkspaceState()) {
-            throw new RepositoryException("Internal error: Cannot create Lock for 'workspace' state.");
-        }
+        nodeState.checkIsSessionState();
         // retrieve node first
         Node lhNode;
         // NOTE: Node must be retrieved from the given NodeState and not from
-        // the overlayed workspace nodestate. See below.
-        Item item = itemManager.getItem(nodeState);
+        // the overlayed workspace nodestate.
+        Item item = itemManager.getItem(nodeState.getHierarchyEntry());
         if (item.isNode()) {
             lhNode = (Node) item;
         } else {
@@ -100,11 +101,10 @@
         }
 
         // execute the operation
-        NodeState wspNodeState = getWorkspaceState(nodeState);
-        LockOperation op = LockOperation.create(wspNodeState, isDeep, isSessionScoped);
+        LockOperation op = LockOperation.create(nodeState, isDeep, isSessionScoped);
         wspManager.execute(op);
 
-        Lock lock = new LockImpl(new LockState(wspNodeState, op.getLockInfo()), lhNode);
+        Lock lock = new LockImpl(new LockState(nodeState, op.getLockInfo()), lhNode);
         return lock;
     }
 
@@ -113,18 +113,17 @@
      * @param nodeState
      */
     public void unlock(NodeState nodeState) throws LockException, RepositoryException {
-        NodeState wspNodeState = getWorkspaceState(nodeState);
         // 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 and reliable information.
-        Operation op = LockRelease.create(wspNodeState);
+        Operation op = LockRelease.create(nodeState);
         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(wspNodeState)) {
-            LockImpl l = (LockImpl) lockMap.remove(wspNodeState);
+        if (lockMap.containsKey(nodeState)) {
+            LockImpl l = (LockImpl) lockMap.remove(nodeState);
             l.lockState.unlocked();
         }
     }
@@ -140,7 +139,7 @@
      * @param nodeState
      */
     public Lock getLock(NodeState nodeState) throws LockException, RepositoryException {
-        LockImpl l = getLockImpl(nodeState);
+        LockImpl l = getLockImpl(nodeState, false);
         // no-lock found or lock doesn't apply to this state -> throw
         if (l == null) {
             throw new LockException("Node with id '" + nodeState.getNodeId() + "' is not locked.");
@@ -156,13 +155,10 @@
      * @param nodeState
      */
     public boolean isLocked(NodeState nodeState) throws RepositoryException {
-        if (nodeState.isWorkspaceState()) {
-            LockState lSt = getLockState(nodeState);
-            return lSt != null;
-        } else {
-            LockImpl l = getLockImpl(nodeState);
-            return l != null;
-        }
+        nodeState.checkIsSessionState();
+
+        LockImpl l = getLockImpl(nodeState, false);
+        return l != null;
     }
 
     /**
@@ -170,25 +166,19 @@
      * @param nodeState
      */
     public void checkLock(NodeState nodeState) throws LockException, RepositoryException {
+        nodeState.checkIsSessionState();
+
         // shortcut: new status indicates that a new state was already added
         // thus, the parent state is not locked by foreign lock.
         if (nodeState.getStatus() == Status.NEW) {
             return;
         }
 
-        if (nodeState.isWorkspaceState()) {
-            LockState lSt = getLockState(nodeState);
-            if (lSt != null && lSt.lockInfo.getLockToken() == null) {
-                // lock is present and token is null -> session is not lock-holder.
-                throw new LockException("Node with id '" + nodeState + "' is locked.");
-            } // else: state is not locked at all || session is lock-holder
-        } else {
-            LockImpl l = getLockImpl(nodeState);
-            if (l != null && l.getLockToken() == null) {
-                // lock is present and token is null -> session is not lock-holder.
-                throw new LockException("Node with id '" + nodeState + "' is locked.");
-            } // else: state is not locked at all || session is lock-holder
-        }
+        LockImpl l = getLockImpl(nodeState, true);
+        if (l != null && l.getLockToken() == null) {
+            // lock is present and token is null -> session is not lock-holder.
+            throw new LockException("Node with id '" + nodeState + "' is locked.");
+        } // else: state is not locked at all || session is lock-holder
     }
 
     /**
@@ -292,28 +282,15 @@
     }
 
     //------------------------------------------------------------< private >---
-    /**
-     * The workspace state of the given node is returned. If the state is a new
-     * state (no overlayed state and not being workspace state itself), an
-     * <code>IllegalArgumentException</code> is thrown.
-     *
-     * @param nodeState
-     * @return The overlayed state or the given state, if this one does not have
-     * an overlayed state.
-     */
-    private NodeState getWorkspaceState(NodeState nodeState) {
-        NodeState wspState = (NodeState) nodeState.getWorkspaceState();
-        if (wspState == null) {
-            throw new IllegalArgumentException("NodeState " + nodeState + " has no overlayed state.");
-        }
-        return wspState;
-    }
 
     /**
      * Search nearest ancestor that is locked. Returns <code>null</code> if neither
      * the given state nor any of its ancestors is locked.
      * Note, that this methods does NOT check if the given node state would
      * be affected by the lock present on an ancestor state.
+     * Note, that in certain cases it might not be possible to detect a lock
+     * being present due to the fact that the hierarchy might be imcomplete or
+     * not even readable completely.
      *
      * @param nodeState <code>NodeState</code> from which searching starts.
      * Note, that the given state must not have an overlayed state.
@@ -326,45 +303,59 @@
          * 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) {
+        NodeEntry entry = nodeState.getNodeEntry();
+        while (!entry.hasPropertyEntry(QName.JCR_LOCKISDEEP)) {
+            NodeEntry parent = entry.getParent();
+            if (parent == null) {
                 // reached root state without finding a locked node
                 return null;
             }
-            nodeState = parentState;
+            entry = parent;
+        }
+        try {
+            return entry.getNodeState();
+        } catch (ItemStateException e) {
+            // may occur if the nodeState is not accessible
+            // for this case, assume that no lock exists and delegate final
+            // validation to the spi-implementation.
+            log.warn("Error while accessing lock holding NodeState", e);
+            return null;
         }
-        return nodeState;
     }
 
-    private LockState getLockState(NodeState wspState) throws LockException, RepositoryException {
-        wspState.checkIsWorkspaceState();
-
-        if (lockMap.containsKey(wspState)) {
-            LockImpl lock = (LockImpl) lockMap.get(wspState);
-            return lock.lockState;
+    private LockState buildLockState(NodeState nodeState) throws RepositoryException {
+        NodeState lockHoldingState = null;
+        LockInfo lockInfo;
+        try {
+            lockInfo = wspManager.getLockInfo(nodeState.getNodeId());
+        } catch (LockException e) {
+            // no lock present
+            return null;
         }
 
-        // try to retrieve a state (ev. a parent state) that holds a lock.
-        NodeState lockHoldingWspState = getLockHoldingState(wspState);
-        if (lockHoldingWspState == null) {
-            // no lock
-            return null;
+        NodeId lockNodeId = lockInfo.getNodeId();
+        if (lockNodeId.equals(nodeState.getId())) {
+            lockHoldingState = nodeState;
         } else {
-            if (lockMap.containsKey(lockHoldingWspState)) {
-                LockImpl lock = (LockImpl) lockMap.get(lockHoldingWspState);
-                return lock.lockState;
-            }
-
-            LockState st = new LockState(lockHoldingWspState);
-            if (st.appliesToNodeState(wspState)) {
-                return st;
+            HierarchyEntry lockedEntry = wspManager.getHierarchyManager().getHierarchyEntry(lockNodeId);
+            if (lockedEntry.denotesNode()) {
+                try {
+                    lockHoldingState = ((NodeEntry) lockedEntry).getNodeState();
+                } catch (ItemStateException e) {
+                    log.warn("Cannot build LockState");
+                    throw new RepositoryException("Cannot build LockState", e);
+                }
             } else {
-                // lock exists but does not apply to the workspace node state
-                // passed to this method.
-                return null;
+                // should never occur
+                throw new RepositoryException("Internal error.");
             }
         }
+
+        if (lockHoldingState == null) {
+            return null;
+        } else {
+            return new LockState(lockHoldingState, lockInfo);
+        }
     }
 
     /**
@@ -373,48 +364,50 @@
      * locked at all.
      *
      * @param nodeState
+     * @param lazyLockDiscovery If true, no extra check with the server is made in order to
+     * determine, whether there is really no lock present. Otherwise, the server
+     * is asked if a lock is present.
      * @return LockImpl that applies to the given state or <code>null</code>.
      * @throws RepositoryException
      */
-    private LockImpl getLockImpl(NodeState nodeState) throws RepositoryException {
+    private LockImpl getLockImpl(NodeState nodeState, boolean lazyLockDiscovery) throws RepositoryException {
+        nodeState.checkIsSessionState();
+
         // shortcut: check if a given state holds a lock, which has been
         // accessed before (thus is known to the manager) irrespective if the
         // current session is the lock holder or not.
-        NodeState wspSt = (NodeState) nodeState.getWorkspaceState();
-        if (wspSt != null && lockMap.containsKey(nodeState)) {
+        if (lockMap.containsKey(nodeState)) {
             return (LockImpl) lockMap.get(nodeState);
         }
 
-        // try to retrieve a state (ev. a parent state) that holds a lock.
-        NodeState lockHoldingState = getLockHoldingState(nodeState);
-        if (lockHoldingState == null) {
-            // no lock
-            return null;
-        } else {
-            NodeState lockHoldingWspState = getWorkspaceState(lockHoldingState);
-            // check lockMap again with the lockholding state
-            if (lockMap.containsKey(lockHoldingWspState)) {
-                return (LockImpl) lockMap.get(lockHoldingWspState);
-            }
-
-            if (lockHoldingWspState == lockHoldingState) {
-                // TODO: TOBEFIXED the Lock cannot be builded from a wsp-state since the Node cannot be retrieved.
-                throw new RepositoryException("Internal error: Cannot retrieve Lock for 'workspace' state " + nodeState);
-            }
-            LockState lstate = new LockState(lockHoldingWspState);
-            // Lock has never been access -> build the lock object
-            // 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);
-            LockImpl l = new LockImpl(lstate, (Node)lockHoldingNode);
-
-            if (l.lockState.appliesToNodeState(nodeState)) {
-                return l;
-            } else {
-                // lock exists but does not apply to the workspace node state
-                // passed to this method.
+        LockState lState;
+        if (lazyLockDiscovery) {
+            // try to retrieve a state (ev. a parent state) that holds a lock.
+            NodeState lockHoldingState = getLockHoldingState(nodeState);
+            if (lockHoldingState == null) {
+                // no lock
                 return null;
+            } else {
+                // check lockMap again with the lockholding state
+                if (lockMap.containsKey(lockHoldingState)) {
+                    return (LockImpl) lockMap.get(lockHoldingState);
+                }
+                lState = buildLockState(lockHoldingState);
             }
+        } else {
+            lState = buildLockState(nodeState);
+        }
+
+        // Lock has never been access -> build the lock object
+        // retrieve lock holding node. note that this may fail if the session
+        // does not have permission to see this node.
+        if (lState != null && lState.appliesToNodeState(nodeState)) {
+            Item lockHoldingNode = itemManager.getItem(lState.lockHoldingState.getHierarchyEntry());
+            return new LockImpl(lState, (Node)lockHoldingNode);
+        } else {
+            // lock exists but does not apply to the given node state
+            // passed to this method.
+            return null;
         }
     }
 
@@ -451,41 +444,18 @@
     }
 
     //--------------------------------------------------------------------------
-    private class LockState implements InternalEventListener{
+    private class LockState implements ItemStateLifeCycleListener {
 
         private final NodeState lockHoldingState;
 
         private LockInfo lockInfo;
         private boolean isLive = true;
-        private EventFilter eventFilter;
 
-        private LockState(NodeState lockHoldingState, LockInfo lockInfo)
-            throws LockException, RepositoryException{
-            lockHoldingState.checkIsWorkspaceState();
+        private LockState(NodeState lockHoldingState, LockInfo lockInfo) {
+            lockHoldingState.checkIsSessionState();
 
             this.lockHoldingState = lockHoldingState;
-            if (lockInfo == null) {
-                // 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(lockHoldingState.getNodeId());
-            } else {
-                this.lockInfo = lockInfo;
-            }
-
-            try {
-                // register as internal listener to the wsp manager in order to get
-                // informed if this lock ends his life.
-                eventFilter = wspManager.createEventFilter(Event.PROPERTY_REMOVED,
-                    lockHoldingState.getQPath(), false, null, null, true);
-                wspManager.addEventListener(this);
-            } catch (UnsupportedRepositoryOperationException e) {
-                eventFilter = null;
-            }
-        }
-
-        private LockState(NodeState lockHoldingState) throws LockException, RepositoryException {
-            this(lockHoldingState, null);
+            this.lockInfo = lockInfo;
         }
 
         private void refresh() throws RepositoryException {
@@ -508,8 +478,7 @@
             if (nodeState.getStatus() == Status.NEW) {
                 return lockInfo.isDeep();
             } else {
-                NodeState wspState = getWorkspaceState(nodeState);
-                if (lockHoldingState == wspState) {
+                if (lockHoldingState == nodeState) {
                     return true;
                 } else {
                     return lockInfo.isDeep();
@@ -535,7 +504,7 @@
             if (lockMap.containsKey(lockHoldingState)) {
                 lockMap.remove(lockHoldingState);
             }
-            wspManager.removeEventListener(this);
+            stopListening();
         }
 
         /**
@@ -550,19 +519,30 @@
             }
         }
 
-        //------------------------------------------< InternalEventListener >---
+        private void startListening() {
+            if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
+                try {
+                    PropertyState ps = lockHoldingState.getPropertyState(QName.JCR_LOCKISDEEP);
+                    ps.addListener(this);
+                } catch (ItemStateException e) {
+                    log.warn("Internal error", e);
+                }
+            }
+        }
 
-        /**
-         * @see InternalEventListener#getEventFilters()
-         */
-        public Collection getEventFilters() {
-            return (eventFilter == null) ?  Collections.EMPTY_LIST : Collections.singletonList(eventFilter);
+        private void stopListening() {
+            if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
+                try {
+                    PropertyState ps = lockHoldingState.getPropertyState(QName.JCR_LOCKISDEEP);
+                    ps.removeListener(this);
+                } catch (ItemStateException e) {
+                    log.warn("Internal error", e);
+                }
+            }
         }
 
-        /**
-         * @see InternalEventListener#onEvent(EventBundle)
-         */
-        public void onEvent(EventBundle eventBundle) {
+        //-------------------------------------< ItemStateLifeCycleListener >---
+        public void statusChanged(ItemState state, int previousStatus) {
             if (!isLive) {
                 // since we only monitor the removal of the lock (by means
                 // of deletion of the jcr:lockIsDeep property, we are not interested
@@ -570,10 +550,15 @@
                 return;
             }
 
-            // this lock has been release by someone else (and not by
-            // a call to LockManager#unlock -> clean up and set isLive
-            // flag to false.
-            unlocked();
+            switch (state.getStatus()) {
+                case Status.REMOVED:
+                    // this lock has been release by someone else (and not by
+                    // a call to LockManager#unlock -> clean up and set isLive
+                    // flag to false.
+                    unlocked();
+               default:
+                   // not interested (Todo correct?)
+            }
         }
     }
 
@@ -597,8 +582,12 @@
             this.lockState = lockState;
             this.node = lockHoldingNode;
 
-            // if observation is supported -> store lock in the map
-            if (lockState.eventFilter != null) {
+            // if observation is supported OR if this is a session-scoped lock
+            // holded by this session -> store lock in the map
+            if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
+                lockMap.put(lockState.lockHoldingState, this);
+                lockState.startListening();
+            } else if (isSessionScoped() && isHoldBySession()) {
                 lockMap.put(lockState.lockHoldingState, this);
             }
         }
@@ -697,9 +686,13 @@
             }
         }
 
+        //--------------------------------------------------------< private >---
         private LockInfo getLockInfo() {
             return lockState.lockInfo;
         }
+        private boolean isHoldBySession() {
+            return lockState.lockInfo.getLockToken() != null;
+        }
     }
 
     //--------------------------------------------------< LockTokenListener >---
@@ -724,4 +717,4 @@
          */
         void lockTokenRemoved(String lockToken) throws LockException, RepositoryException;
     }
-}
\ No newline at end of file
+}

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractCopy.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractCopy.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractCopy.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractCopy.java Tue Feb 13 01:31:36 2007
@@ -19,6 +19,7 @@
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.ManagerProvider;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.jcr2spi.util.LogUtil;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.QName;
@@ -77,10 +78,13 @@
     /**
      * Invalidate the destination parent <code>NodeState</code>.
      * 
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        destParentState.invalidate(false);
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            destParentState.getHierarchyEntry().invalidate(false);
+        }
     }
 
     //----------------------------------------< Access Operation Parameters >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java Tue Feb 13 01:31:36 2007
@@ -18,10 +18,10 @@
 
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.NamespaceResolver;
-import org.apache.jackrabbit.jcr2spi.HierarchyManager;
-import org.apache.jackrabbit.jcr2spi.util.LogUtil;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.util.LogUtil;
 
 import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java Tue Feb 13 01:31:36 2007
@@ -21,8 +21,8 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 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.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -73,18 +73,14 @@
      * version history. If '<code>moveLabel</code>' is true, all decendant states
      * (property states) are invalidated as well.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        ChildNodeEntry lnEntry = versionHistoryState.getChildNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
-        if (lnEntry.isAvailable()) {
-            try {
-                NodeState labelNodeState = lnEntry.getNodeState();
-                // if an existing label must be moved -> invalidate recursively
-                labelNodeState.invalidate(moveLabel);
-            } catch (ItemStateException e) {
-                // ignore
-            }
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            NodeEntry vhEntry = (NodeEntry) versionHistoryState.getHierarchyEntry();
+            NodeEntry lnEntry = vhEntry.getNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
+            lnEntry.invalidate(moveLabel);
         }
     }
     //----------------------------------------< Access Operation Parameters >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.name.QName;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
@@ -63,9 +64,10 @@
     /**
      * Throws UnsupportedOperationException
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
+    public void persisted(CacheBehaviour cacheBehaviour) {
         throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
     }
     //----------------------------------------< Access Operation Parameters >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddProperty.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddProperty.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddProperty.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddProperty.java Tue Feb 13 01:31:36 2007
@@ -20,6 +20,7 @@
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.ItemExistsException;
@@ -64,9 +65,10 @@
     /**
      * Throws UnsupportedOperationException
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
+    public void persisted(CacheBehaviour cacheBehaviour) {
         throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
     }
     //----------------------------------------< Access Operation Parameters >---
@@ -88,6 +90,10 @@
 
     public boolean isMultiValued() {
         return definition.isMultiple();
+    }
+
+    public QPropertyDefinition getDefinition() {
+        return definition;
     }
 
     //------------------------------------------------------------< Factory >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkin.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkin.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkin.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkin.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,12 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.version.VersionManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -25,16 +31,21 @@
 import javax.jcr.version.VersionException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
+import java.util.Iterator;
 
 /**
  * <code>Checkin</code>...
  */
 public class Checkin extends AbstractOperation {
 
+    private static Logger log = LoggerFactory.getLogger(Checkin.class);
+
     private final NodeState nodeState;
+    private final VersionManager mgr;
 
-    private Checkin(NodeState nodeState) {
+    private Checkin(NodeState nodeState, VersionManager mgr) {
         this.nodeState = nodeState;
+        this.mgr = mgr;
         // NOTE: affected-states only needed for transient modifications
     }
 
@@ -50,11 +61,23 @@
     /**
      * Invalidate the target <code>NodeState</code>.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        nodeState.invalidate(false);
-        // TODO: invalidate the corresponding part of the version storage
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            try {
+                mgr.getVersionHistoryNodeState(nodeState).invalidate(true);
+            } catch (RepositoryException e) {
+                log.warn("Internal error", e);
+            }
+            Iterator entries = ((NodeEntry) nodeState.getHierarchyEntry()).getPropertyEntries();
+            while (entries.hasNext()) {
+                PropertyEntry pe = (PropertyEntry) entries.next();
+                pe.invalidate(false);
+            }
+            nodeState.getHierarchyEntry().invalidate(false);
+        }
     }
     //----------------------------------------< Access Operation Parameters >---
     /**
@@ -69,9 +92,10 @@
     /**
      *
      * @param nodeState
+     * @param mgr
      * @return
      */
-    public static Operation create(NodeState nodeState) {
-        return new Checkin(nodeState);
+    public static Operation create(NodeState nodeState, VersionManager mgr) {
+        return new Checkin(nodeState, mgr);
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkout.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkout.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkout.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkout.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,12 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.version.VersionManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -25,16 +31,21 @@
 import javax.jcr.version.VersionException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
+import java.util.Iterator;
 
 /**
  * <code>Checkout</code>...
  */
 public class Checkout extends AbstractOperation {
 
+    private static Logger log = LoggerFactory.getLogger(Checkout.class);
+
     private final NodeState nodeState;
+    private final VersionManager mgr;
 
-    private Checkout(NodeState nodeState) {
+    private Checkout(NodeState nodeState, VersionManager mgr) {
         this.nodeState = nodeState;
+        this.mgr = mgr;
         // NOTE: affected-states only needed for transient modifications
     }
 
@@ -46,11 +57,25 @@
     /**
      * Invalidate the target <code>NodeState</code>.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        nodeState.invalidate(false);
-        // TODO: invalidate the corresponding part of the version storage
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            try {
+                mgr.getVersionHistoryNodeState(nodeState).invalidate(true);
+            } catch (RepositoryException e) {
+                log.warn("Internal error", e);
+            }
+            // non-recursive invalidation (but including all properties)
+            NodeEntry nodeEntry = (NodeEntry) nodeState.getHierarchyEntry();
+            Iterator entries = nodeEntry.getPropertyEntries();
+            while (entries.hasNext()) {
+                PropertyEntry pe = (PropertyEntry) entries.next();
+                pe.invalidate(false);
+            }
+            nodeEntry.invalidate(false);
+        }
     }
 
     //----------------------------------------< Access Operation Parameters >---
@@ -61,9 +86,9 @@
     public NodeState getNodeState() {
         return nodeState;
     }
-    
+
     //------------------------------------------------------------< Factory >---
-    public static Operation create(NodeState nodeState) {
-        return new Checkout(nodeState);
+    public static Operation create(NodeState nodeState, VersionManager mgr) {
+        return new Checkout(nodeState, mgr);
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java Tue Feb 13 01:31:36 2007
@@ -17,8 +17,8 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.ManagerProvider;
-import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
 import org.apache.jackrabbit.name.Path;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -64,21 +64,21 @@
     }
 
     /**
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        if (removeExisting) {
-            // invalidate the complete tree
-            try {
-                NodeState rootState = destMgrProvider.getItemStateManager().getRootState();
-                rootState.invalidate(true);
-            } catch (ItemStateException e) {
-                log.error("Cannot invalidate root state.", e.getMessage());
-                // fallback
-                super.persisted();
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            if (removeExisting) {
+                // invalidate the complete tree -> find root-hierarchy-entry
+                HierarchyEntry he = getDestinationParentState().getHierarchyEntry();
+                while (he.getParent() != null) {
+                    he = he.getParent();
+                }
+                he.invalidate(true);
+            } else {
+                super.persisted(cacheBehaviour);
             }
-        } else {
-            super.persisted();
         }
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.spi.LockInfo;
 
 import javax.jcr.RepositoryException;
@@ -57,10 +58,14 @@
     /**
      * Invalidates the <code>NodeState</code> that has been locked.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        nodeState.invalidate(false);
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            // non-recursive invalidation
+            nodeState.getHierarchyEntry().invalidate(false);
+        }
     }
 
     //----------------------------------------< Access Operation Parameters >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRefresh.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRefresh.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRefresh.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRefresh.java Tue Feb 13 01:31:36 2007
@@ -21,6 +21,7 @@
 import javax.jcr.ItemExistsException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.version.VersionException;
 import javax.jcr.nodetype.ConstraintViolationException;
@@ -48,9 +49,10 @@
     }
 
     /**
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
+    public void persisted(CacheBehaviour cacheBehaviour) {
         // nothing to do.
     }
     

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRelease.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRelease.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRelease.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRelease.java Tue Feb 13 01:31:36 2007
@@ -17,9 +17,9 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.PropertyState;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
-import org.apache.jackrabbit.jcr2spi.state.entry.ChildPropertyEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -28,7 +28,6 @@
 import javax.jcr.version.VersionException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
-import java.util.Collection;
 import java.util.Iterator;
 
 /**
@@ -56,22 +55,20 @@
      * Invalidates the <code>NodeState</code> that has been unlocked and all its
      * child properties.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        Collection propEntries = nodeState.getPropertyEntries();
-        for (Iterator it = propEntries.iterator(); it.hasNext();) {
-            ChildPropertyEntry pe = (ChildPropertyEntry) it.next();
-            if (pe.isAvailable()) {
-                try {
-                    PropertyState st = pe.getPropertyState();
-                    st.invalidate(false);
-                } catch (ItemStateException e) {
-                    // ignore
-                }
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            // non-recursive invalidation but including all properties
+            NodeEntry nodeEntry = nodeState.getNodeEntry();
+            Iterator entries = nodeEntry.getPropertyEntries();
+            while (entries.hasNext()) {
+                PropertyEntry pe = (PropertyEntry) entries.next();
+                pe.invalidate(false);
             }
+            nodeEntry.invalidate(false);
         }
-        nodeState.invalidate(false);
     }
 
     //----------------------------------------< Access Operation Parameters >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Merge.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Merge.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Merge.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Merge.java Tue Feb 13 01:31:36 2007
@@ -17,7 +17,11 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.version.VersionManager;
 import org.apache.jackrabbit.spi.IdIterator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -32,16 +36,20 @@
  */
 public class Merge extends AbstractOperation {
 
+    private static Logger log = LoggerFactory.getLogger(Merge.class);
+
     private final NodeState nodeState;
     private final String srcWorkspaceName;
     private final boolean bestEffort;
+    private final VersionManager mgr;
 
     private IdIterator failedIds = null;
 
-    private Merge(NodeState nodeState, String srcWorkspaceName, boolean bestEffort) {
+    private Merge(NodeState nodeState, String srcWorkspaceName, boolean bestEffort, VersionManager mgr) {
         this.nodeState = nodeState;
         this.srcWorkspaceName = srcWorkspaceName;
         this.bestEffort = bestEffort;
+        this.mgr = mgr;
 
         // NOTE: affected-states only needed for transient modifications
     }
@@ -57,11 +65,18 @@
     /**
      * Invalidates the target nodestate and all descendants.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        nodeState.invalidate(true);
-        // TODO: invalidate the corresponding part of the version storage
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            try {
+                mgr.getVersionHistoryNodeState(nodeState).invalidate(true);
+            } catch (RepositoryException e) {
+                log.warn("Internal error", e);
+            }
+            nodeState.getHierarchyEntry().invalidate(true);
+        }
     }
 
     //----------------------------------------< Access Operation Parameters >---
@@ -100,7 +115,7 @@
      * @param srcWorkspaceName
      * @return
      */
-    public static Merge create(NodeState nodeState, String srcWorkspaceName, boolean bestEffort) {
-        return new Merge(nodeState, srcWorkspaceName, bestEffort);
+    public static Merge create(NodeState nodeState, String srcWorkspaceName, boolean bestEffort, VersionManager mgr) {
+        return new Merge(nodeState, srcWorkspaceName, bestEffort, mgr);
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java Tue Feb 13 01:31:36 2007
@@ -17,10 +17,11 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.util.LogUtil;
-import org.apache.jackrabbit.jcr2spi.HierarchyManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 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.config.CacheBehaviour;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.MalformedPathException;
@@ -77,15 +78,19 @@
      * modification. Otherwise, the moved state as well as both parent states
      * are invalidated.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        if (srcState.isWorkspaceState()) {
-            srcParentState.invalidate(false);
-            destParentState.invalidate(false);
-            srcState.invalidate(false);
-        } else {
-            throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            if (srcState.isWorkspaceState()) {
+                // non-recursive invalidation
+                srcParentState.getHierarchyEntry().invalidate(false);
+                destParentState.getHierarchyEntry().invalidate(false);
+                srcState.getHierarchyEntry().invalidate(false);
+            } else {
+                throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
+            }
         }
     }
     //----------------------------------------< Access Operation Parameters >---
@@ -146,10 +151,11 @@
         NodeState destParentState = getNodeState(destPath.getAncestor(1), hierMgr, nsResolver);
         QName destName = destElement.getName();
 
-        if (destParentState.hasPropertyName(destName)) {
+        NodeEntry destEntry = (NodeEntry) destParentState.getHierarchyEntry();
+        if (destEntry.hasPropertyEntry(destName)) {
             throw new ItemExistsException("Move destination already exists (Property).");
-        } else if (destParentState.hasChildNodeEntry(destName)) {
-            ChildNodeEntry existing = destParentState.getChildNodeEntry(destName, Path.INDEX_DEFAULT);
+        } else if (destEntry.hasNodeEntry(destName)) {
+            NodeEntry existing = destEntry.getNodeEntry(destName, Path.INDEX_DEFAULT);
             try {
                 if (!existing.getNodeState().getDefinition().allowsSameNameSiblings()) {
                     throw new ItemExistsException("Node existing at move destination does not allow same name siblings.");

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Operation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Operation.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Operation.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Operation.java Tue Feb 13 01:31:36 2007
@@ -60,6 +60,8 @@
      * the result of the operation will not be pushed by observation events.
      * Instead the workspace operations must make sure, that the affected
      * item states are properly refreshed or invalidated.
+     *
+     * @param cacheBehaviour
      */
-    public void persisted();
+    public void persisted(CacheBehaviour cacheBehaviour);
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java Tue Feb 13 01:31:36 2007
@@ -18,6 +18,8 @@
 
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.AccessDeniedException;
 import javax.jcr.RepositoryException;
@@ -30,12 +32,14 @@
 public class Remove extends AbstractOperation {
 
     protected ItemState removeState;
+    protected NodeState parent;
 
-    protected Remove(ItemState removeState) {
+    protected Remove(ItemState removeState, NodeState parent) {
         this.removeState = removeState;
+        this.parent = parent;
 
         addAffectedItemState(removeState);
-        addAffectedItemState(removeState.getParent());
+        addAffectedItemState(parent);
     }
 
     //----------------------------------------------------------< Operation >---
@@ -49,9 +53,10 @@
     /**
      * Throws UnsupportedOperationException
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
+    public void persisted(CacheBehaviour cacheBehaviour) {
         throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
     }
 
@@ -62,12 +67,21 @@
     }
 
     public NodeState getParentState() {
-        return removeState.getParent();
+        return parent;
     }
 
     //------------------------------------------------------------< Factory >---
-    public static Operation create(ItemState state) {
-        Remove rm = new Remove(state);
+    public static Operation create(ItemState state) throws RepositoryException {
+        try {
+            Remove rm = new Remove(state, state.getParent());
+            return rm;
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    public static Operation create(ItemState state, NodeState parent) {
+        Remove rm = new Remove(state, parent);
         return rm;
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java Tue Feb 13 01:31:36 2007
@@ -21,8 +21,8 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 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.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -70,17 +70,14 @@
      * Invalidates the jcr:versionlabel nodestate present with the given
      * version history and all decendant states (property states).
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        ChildNodeEntry lnEntry = versionHistoryState.getChildNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
-        if (lnEntry.isAvailable()) {
-            try {
-                NodeState labelNodeState = lnEntry.getNodeState();
-                labelNodeState.invalidate(true);
-            } catch (ItemStateException e) {
-                // ignore
-            }
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            NodeEntry vhEntry = (NodeEntry) versionHistoryState.getHierarchyEntry();
+            NodeEntry lnEntry = vhEntry.getNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
+            lnEntry.invalidate(true);
         }
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java Tue Feb 13 01:31:36 2007
@@ -15,19 +15,35 @@
 
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.version.VersionManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.jcr.AccessDeniedException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.RepositoryException;
 import javax.jcr.version.VersionException;
+import java.util.Iterator;
 
 /**
  * <code>RemoveVersion</code>...
  */
 public class RemoveVersion extends Remove {
 
-    protected RemoveVersion(ItemState removeState) {
-        super(removeState);
+    private static Logger log = LoggerFactory.getLogger(RemoveVersion.class);
+
+    private NodeEntry versionableEntry = null;
+
+    protected RemoveVersion(ItemState removeState, NodeState parent, VersionManager mgr) {
+        super(removeState, parent);
+        try {
+            versionableEntry = mgr.getVersionableNodeState((NodeState) removeState);
+        } catch (RepositoryException e) {
+            log.warn("Internal error", e);
+        }
     }
 
     //----------------------------------------------------------< Operation >---
@@ -42,17 +58,30 @@
      * Invalidates the <code>NodeState</code> that has been updated and all
      * its decendants. Second, the parent state gets invalidated.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        NodeState parent = removeState.getParent();
-        removeState.invalidate(true);
-        parent.invalidate(false);
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            // invaliate the versionable node as well (version related properties)
+            if (versionableEntry != null) {
+                Iterator propEntries = versionableEntry.getPropertyEntries();
+                while (propEntries.hasNext()) {
+                    PropertyEntry pe = (PropertyEntry) propEntries.next();
+                    pe.invalidate(false);
+                }
+                versionableEntry.invalidate(false);
+            }
+
+            // invalidate the versionhistory entry and all its children
+            // in order to the the v-graph recalculated
+            removeState.getHierarchyEntry().getParent().invalidate(true);
+        }
     }
 
     //------------------------------------------------------------< Factory >---
-    public static Operation create(NodeState versionState) {
-        RemoveVersion rm = new RemoveVersion(versionState);
+    public static Operation create(NodeState versionState, NodeState vhState, VersionManager mgr) {
+        RemoveVersion rm = new RemoveVersion(versionState, vhState, mgr);
         return rm;
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java Tue Feb 13 01:31:36 2007
@@ -19,6 +19,7 @@
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.NoSuchItemStateException;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.name.Path;
 
 import javax.jcr.nodetype.ConstraintViolationException;
@@ -55,9 +56,10 @@
     /**
      * Throws UnsupportedOperationException
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
+    public void persisted(CacheBehaviour cacheBehaviour) {
         throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
     }
     //----------------------------------------< Access Operation Parameters >---
@@ -77,8 +79,8 @@
 
     public static Operation create(NodeState parentState, Path.PathElement srcName,
                                    Path.PathElement beforeName) throws NoSuchItemStateException, ItemStateException {
-        NodeState insert = parentState.getChildNodeEntry(srcName.getName(), srcName.getNormalizedIndex()).getNodeState();
-        NodeState before = (beforeName == null) ? null : parentState.getChildNodeEntry(beforeName.getName(), beforeName.getNormalizedIndex()).getNodeState();
+        NodeState insert = parentState.getChildNodeState(srcName.getName(), srcName.getNormalizedIndex());
+        NodeState before = (beforeName == null) ? null : parentState.getChildNodeState(beforeName.getName(), beforeName.getNormalizedIndex());
         Operation op = new ReorderNodes(parentState, insert, before);
         return op;
     }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ResolveMergeConflict.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ResolveMergeConflict.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ResolveMergeConflict.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ResolveMergeConflict.java Tue Feb 13 01:31:36 2007
@@ -17,9 +17,9 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.PropertyState;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
-import org.apache.jackrabbit.jcr2spi.state.entry.ChildPropertyEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -28,7 +28,6 @@
 import javax.jcr.version.VersionException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
-import java.util.Collection;
 import java.util.Iterator;
 
 /**
@@ -60,22 +59,19 @@
      * Invalidates the <code>NodeState</code> that had a merge conflict pending
      * and all its child properties.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        Collection propEntries = nodeState.getPropertyEntries();
-        for (Iterator it = propEntries.iterator(); it.hasNext();) {
-            ChildPropertyEntry pe = (ChildPropertyEntry) it.next();
-            if (pe.isAvailable()) {
-                try {
-                    PropertyState st = pe.getPropertyState();
-                    st.invalidate(false);
-                } catch (ItemStateException e) {
-                    // ignore
-                }
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            // non-recursive invalidation BUT including all properties
+            Iterator propEntries = ((NodeEntry) nodeState.getHierarchyEntry()).getPropertyEntries();
+            while (propEntries.hasNext()) {
+                PropertyEntry pe = (PropertyEntry) propEntries.next();
+                pe.invalidate(false);
             }
+            nodeState.getHierarchyEntry().invalidate(false);
         }
-        nodeState.invalidate(false);
     }
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,8 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.apache.jackrabbit.name.Path;
 
 import javax.jcr.RepositoryException;
@@ -61,14 +63,21 @@
      * invalidated, otherwise the given <code>NodeState</code> that has been
      * updated and all its decendants.
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        if (nodeState == null || removeExisting) {
-            // invalidate the complete tree
-            // TODO
-        } else {
-            nodeState.invalidate(true);
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            if (nodeState == null || removeExisting) {
+                // invalidate the complete tree
+                NodeEntry root = nodeState.getNodeEntry();
+                while (root.getParent() != null) {
+                    root = root.getParent();
+                }
+                root.invalidate(true);
+            } else {
+                nodeState.getHierarchyEntry().invalidate(true);
+            }
         }
     }
     //----------------------------------------< Access Operation Parameters >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java Tue Feb 13 01:31:36 2007
@@ -19,6 +19,9 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -42,9 +45,10 @@
         addAffectedItemState(nodeState);
         // add the jcr:mixinTypes property state as affected if it already exists
         // and therefore gets modified by this operation.
-        if (nodeState.hasPropertyName(QName.JCR_MIXINTYPES)) {
+        PropertyEntry pe = ((NodeEntry) nodeState.getHierarchyEntry()).getPropertyEntry(QName.JCR_MIXINTYPES);
+        if (pe != null) {
             try {
-                addAffectedItemState(nodeState.getPropertyState(QName.JCR_MIXINTYPES));
+                addAffectedItemState(pe.getPropertyState());
             } catch (ItemStateException e) {
                 // should never occur
             }
@@ -64,9 +68,10 @@
     /**
      * Throws UnsupportedOperationException
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
+    public void persisted(CacheBehaviour cacheBehaviour) {
         throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetPropertyValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetPropertyValue.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetPropertyValue.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetPropertyValue.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.PropertyState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.spi.QValue;
 
 import javax.jcr.RepositoryException;
@@ -60,9 +61,10 @@
     /**
      * Throws UnsupportedOperationException
      *
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
+    public void persisted(CacheBehaviour cacheBehaviour) {
         throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Update.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Update.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Update.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Update.java Tue Feb 13 01:31:36 2007
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.jcr2spi.operation;
 
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.AccessDeniedException;
@@ -53,10 +54,13 @@
      * Invalidates the <code>NodeState</code> that has been updated and all
      * its decendants.
      * 
-     * @see Operation#persisted()
+     * @see Operation#persisted(CacheBehaviour)
+     * @param cacheBehaviour
      */
-    public void persisted() {
-        nodeState.invalidate(true);
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        if (cacheBehaviour == CacheBehaviour.INVALIDATE) {
+            nodeState.getHierarchyEntry().invalidate(true);
+        }
     }
 
     //----------------------------------------< Access Operation Parameters >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/NodeIteratorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/NodeIteratorImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/NodeIteratorImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/NodeIteratorImpl.java Tue Feb 13 01:31:36 2007
@@ -23,7 +23,7 @@
 import javax.jcr.Node;
 
 import org.apache.jackrabbit.jcr2spi.ItemManager;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.QueryInfo;
 import org.apache.jackrabbit.spi.QueryResultRow;
@@ -43,8 +43,8 @@
     /** ItemManager to turn Ids into Node instances */
     private final ItemManager itemMgr;
 
-    /** ItemManager to turn Ids into Node instances */
-    private final ItemStateManager itemStateMgr;
+    /**  */
+    private final HierarchyManager hierarchyMgr;
 
     /** The QueryResultRows */
     private final QueryResultRowIterator rows;
@@ -68,14 +68,14 @@
      * Creates a new <code>NodeIteratorImpl</code> instance.
      *
      * @param itemMgr The <code>ItemManager</code> to build <code>Node</code> instances.
-     * @param itemStateMgr The <code>ItemStateManager</code> used to build
-     * <code>ItemState</code>s from the ids returned by the query.
+     * @param hierarchyMgr The <code>HierarchyManager</code> used to retrieve the
+     * HierarchyEntry objects from the ids returned by the query.
      * @param queryInfo the query result.
      */
-    public NodeIteratorImpl(ItemManager itemMgr, ItemStateManager itemStateMgr,
+    public NodeIteratorImpl(ItemManager itemMgr, HierarchyManager hierarchyMgr,
                             QueryInfo queryInfo) {
         this.itemMgr = itemMgr;
-        this.itemStateMgr = itemStateMgr;
+        this.hierarchyMgr = hierarchyMgr;
         this.rows = queryInfo.getRows();
         
         fetchNext();
@@ -214,7 +214,7 @@
             try {
                 QueryResultRow row = rows.nextQueryResultRow();
                 nextId = row.getNodeId();
-                Item tmp = itemMgr.getItem(itemStateMgr.getItemState(nextId));
+                Item tmp = itemMgr.getItem(hierarchyMgr.getHierarchyEntry(nextId));
 
                 if (tmp.isNode()) {
                     next = (Node) tmp;

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java Tue Feb 13 01:31:36 2007
@@ -18,8 +18,8 @@
 
 import org.apache.jackrabbit.jcr2spi.ItemManager;
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
 import org.apache.jackrabbit.jcr2spi.name.LocalNamespaceMappings;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
 import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.name.Path;
@@ -63,9 +63,9 @@
     private final ItemManager itemManager;
 
     /**
-     * The item state manager of the session that executes this query.
+     * The hierarchy manager of the session that executes this query.
      */
-    private final ItemStateManager itemStateManager;
+    private final HierarchyManager hierarchyManager;
 
     /**
      * The query statement
@@ -94,7 +94,7 @@
      * @param session          the session that created this query.
      * @param nsResolver       the namespace resolver to be used.
      * @param itemMgr          the item manager of that session.
-     * @param itemStateManager the item state manager of that session.
+     * @param hierarchyMgr     the HierarchyManager of that session.
      * @param wspManager       the workspace manager that belongs to the
      *                         session.
      * @param statement        the query statement.
@@ -102,14 +102,14 @@
      * @throws InvalidQueryException if the query is invalid.
      */
     public QueryImpl(Session session, LocalNamespaceMappings nsResolver,
-                     ItemManager itemMgr, ItemStateManager itemStateManager,
+                     ItemManager itemMgr, HierarchyManager hierarchyManager,
                      WorkspaceManager wspManager,
                      String statement, String language)
             throws InvalidQueryException, RepositoryException {
         this.session = session;
         this.nsResolver = nsResolver;
         this.itemManager = itemMgr;
-        this.itemStateManager = itemStateManager;
+        this.hierarchyManager = hierarchyManager;
         this.statement = statement;
         this.language = language;
         this.wspManager = wspManager;
@@ -122,6 +122,7 @@
      * @param session    the session that created this query.
      * @param nsResolver the namespace resolver to be used.
      * @param itemMgr    the item manager of that session.
+     * @param hierarchyManager
      * @param wspManager the workspace manager that belongs to the session.
      * @param node       the node from where to read the query.
      * @throws InvalidQueryException if the query is invalid.
@@ -129,14 +130,14 @@
      *                               the node.
      */
     public QueryImpl(Session session, LocalNamespaceMappings nsResolver,
-                     ItemManager itemMgr, ItemStateManager itemStateManager,
+                     ItemManager itemMgr, HierarchyManager hierarchyManager,
                      WorkspaceManager wspManager, Node node)
         throws InvalidQueryException, RepositoryException {
 
         this.session = session;
         this.nsResolver = nsResolver;
         this.itemManager = itemMgr;
-        this.itemStateManager = itemStateManager;
+        this.hierarchyManager = hierarchyManager;
         this.node = node;
         this.wspManager = wspManager;
 
@@ -159,7 +160,7 @@
     public QueryResult execute() throws RepositoryException {
         QueryInfo qI = wspManager.executeQuery(statement, language,
                 nsResolver.getLocalNamespaceMappings());
-        return new QueryResultImpl(itemManager, itemStateManager, qI, nsResolver);
+        return new QueryResultImpl(itemManager, hierarchyManager, qI, nsResolver);
     }
 
     /**

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java Tue Feb 13 01:31:36 2007
@@ -18,8 +18,8 @@
 
 import org.apache.jackrabbit.jcr2spi.ItemManager;
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
 import org.apache.jackrabbit.jcr2spi.name.LocalNamespaceMappings;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
@@ -49,9 +49,9 @@
     private final ItemManager itemMgr;
 
     /**
-     * The <code>ItemStateManager</code> of for item retrieval in search results
+     * The <code>HierarchyManager</code> of for item retrieval in search results
      */
-    private final ItemStateManager itemStateManager;
+    private final HierarchyManager hierarchyManager;
 
     /**
      * The <code>WorkspaceManager</code> where queries are executed.
@@ -65,18 +65,18 @@
      * @param session
      * @param nsResolver
      * @param itemMgr
-     * @param itemStateManager
+     * @param hierarchyManager
      * @param wspManager
      */
     public QueryManagerImpl(Session session,
                             LocalNamespaceMappings nsResolver,
                             ItemManager itemMgr,
-                            ItemStateManager itemStateManager,
+                            HierarchyManager hierarchyManager,
                             WorkspaceManager wspManager) {
         this.session = session;
         this.nsResolver = nsResolver;
         this.itemMgr = itemMgr;
-        this.itemStateManager = itemStateManager;
+        this.hierarchyManager = hierarchyManager;
         this.wspManager = wspManager;
     }
 
@@ -86,7 +86,7 @@
     public Query createQuery(String statement, String language)
             throws InvalidQueryException, RepositoryException {
         checkIsAlive();
-        QueryImpl query = new QueryImpl(session, nsResolver, itemMgr, itemStateManager, wspManager, statement, language);
+        QueryImpl query = new QueryImpl(session, nsResolver, itemMgr, hierarchyManager, wspManager, statement, language);
         return query;
     }
 
@@ -96,7 +96,7 @@
     public Query getQuery(Node node)
             throws InvalidQueryException, RepositoryException {
         checkIsAlive();
-        QueryImpl query = new QueryImpl(session, nsResolver, itemMgr, itemStateManager, wspManager, node);
+        QueryImpl query = new QueryImpl(session, nsResolver, itemMgr, hierarchyManager, wspManager, node);
         return query;
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java Tue Feb 13 01:31:36 2007
@@ -17,7 +17,7 @@
 package org.apache.jackrabbit.jcr2spi.query;
 
 import org.apache.jackrabbit.jcr2spi.ItemManager;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.name.QName;
@@ -47,9 +47,9 @@
     private final ItemManager itemMgr;
 
     /**
-     * The item state manager of the session executing the query
+     * The HierarchyManager of the session executing the query
      */
-    private final ItemStateManager itemStateMgr;
+    private final HierarchyManager hierarchyMgr;
 
     /**
      * The spi query result.
@@ -65,14 +65,14 @@
      * Creates a new query result.
      *
      * @param itemMgr     the item manager of the session executing the query.
-     * @param itemStateMgr the item state manager of the session executing the query.
+     * @param hierarchyMgr the HierarchyManager of the session executing the query.
      * @param queryInfo   the spi query result.
      * @param nsResolver    the namespace nsResolver of the session executing the query.
      */
-    QueryResultImpl(ItemManager itemMgr, ItemStateManager itemStateMgr,
+    QueryResultImpl(ItemManager itemMgr, HierarchyManager hierarchyMgr,
                     QueryInfo queryInfo, NamespaceResolver nsResolver) {
         this.itemMgr = itemMgr;
-        this.itemStateMgr = itemStateMgr;
+        this.hierarchyMgr = hierarchyMgr;
         this.queryInfo = queryInfo;
         this.nsResolver = nsResolver;
     }
@@ -114,7 +114,7 @@
      * Creates a node iterator over the result nodes.
      * @return a node iterator over the result nodes.
      */
-    private ScoreNodeIterator getNodeIterator() throws RepositoryException {
-        return new NodeIteratorImpl(itemMgr, itemStateMgr, queryInfo);
+    private ScoreNodeIterator getNodeIterator() {
+        return new NodeIteratorImpl(itemMgr, hierarchyMgr, queryInfo);
     }
 }