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/11/20 09:06:20 UTC

svn commit: r477095 [1/2] - in /jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: ./ lock/ operation/ state/ state/entry/ version/

Author: angela
Date: Mon Nov 20 00:06:18 2006
New Revision: 477095

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

- removeVersion missing
- LockManager/VersionManager: should not rely on observation (todo added)
- Add Operation.persisted() (Impl. still missing) in analogy to ChangeLog.persisted.
- ItemImpl.refresh behaves according to CacheBehaviour flag.
- NodeState: fix classcastexception when accessing state from propertiesInAttic
- ItemState: rename 'refresh()' to 'reload()
- ItemState: move code common to PropertyState and NodeState to ItemState
- ItemState: rename 'reset' to 'merge'
- add common interface ChildItemEntry
- SessionItemStateManager: avoid traversing twice during 'undo'

Added:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java   (with props)
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/entry/ChildItemEntry.java   (with props)
Modified:
    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/WorkspaceManager.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/operation/AddLabel.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddProperty.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkin.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkout.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Copy.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRefresh.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRelease.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Merge.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Operation.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/OperationVisitor.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/operation/RemoveLabel.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ResolveMergeConflict.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetPropertyValue.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Update.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.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/NodeState.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.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/state/TransientItemStateManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/entry/ChildItemReference.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/entry/ChildNodeEntry.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/entry/ChildNodeReference.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/entry/ChildPropertyEntry.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/entry/PropertyReference.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java

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?view=diff&rev=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -26,6 +26,7 @@
 import org.apache.jackrabbit.jcr2spi.operation.Remove;
 import org.apache.jackrabbit.jcr2spi.operation.Operation;
 import org.apache.jackrabbit.jcr2spi.util.LogUtil;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.QName;
@@ -243,22 +244,33 @@
     public void refresh(boolean keepChanges) throws InvalidItemStateException, RepositoryException {
         // check session status
         session.checkIsAlive();
-        // check if item has been removed
+        // check if item has been removed by this or another session
         if (Status.isTerminal(state.getStatus())) {
             throw new InvalidItemStateException("Item '" + this + "' doesn't exist anymore");
         }
 
+        /* If 'keepChanges' is true, items that do not have changes pending have
+           their state refreshed to reflect the current saved state */
         if (keepChanges) {
-            state.refresh();
+            if (state.getStatus() != Status.NEW  &&
+                session.getCacheBehaviour() != CacheBehaviour.OBSERVATION) {
+                // merge current transient modifications with latest changes
+                // from the 'server'.
+                // Note, that with Observation-CacheBehaviour no manuel refresh
+                // is required. changes get pushed automatically.
+                state.reload(true);
+            }
         } else {
-            // check status of this item's state
+            // check status of item state
             if (state.getStatus() == Status.NEW) {
                 String msg = "Cannot refresh a new item (" + safeGetJCRPath() + ").";
                 log.debug(msg);
                 throw new RepositoryException(msg);
             }
 
-            // reset all transient modifications from this item and its decendants.
+            /*
+            Reset all transient modifications from this item and its decendants.
+            */
             try {
                 session.getSessionItemStateManager().undo(state);
             } catch (ItemStateException e) {
@@ -266,8 +278,12 @@
                 log.debug(msg);
                 throw new RepositoryException(msg, e);
             }
-            // now refresh to persistent state as present on the server
-            state.refresh();
+            /* Unless the session is in 'observation' mode, mark all states
+               within this tree 'invalidated' in order to have them refreshed
+               from the server upon the next access.*/
+            if (session.getCacheBehaviour() != CacheBehaviour.OBSERVATION) {
+                state.invalidate(true);
+            }
         }
     }
 
@@ -407,7 +423,7 @@
         // check status of this item for read operation
         if (state.getStatus() == Status.INVALIDATED) {
             // refresh to get current status from persistent storage
-            state.refresh();
+            state.reload(false);
         }
         // now check if valid
         if (!state.isValid()) {

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java?view=diff&rev=477095&r1=477094&r2=477095
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java Mon Nov 20 00:06:18 2006
@@ -54,6 +54,7 @@
 import org.apache.jackrabbit.jcr2spi.operation.LockRelease;
 import org.apache.jackrabbit.jcr2spi.operation.AddLabel;
 import org.apache.jackrabbit.jcr2spi.operation.RemoveLabel;
+import org.apache.jackrabbit.jcr2spi.operation.RemoveVersion;
 import org.apache.jackrabbit.jcr2spi.security.AccessManager;
 import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
 import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
@@ -92,6 +93,7 @@
 import javax.jcr.InvalidItemStateException;
 import javax.jcr.MergeException;
 import javax.jcr.Session;
+import javax.jcr.ReferentialIntegrityException;
 import javax.jcr.version.VersionException;
 import javax.jcr.lock.LockException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
@@ -431,16 +433,23 @@
      * @see UpdatableItemStateManager#execute(Operation)
      */
     public void execute(Operation operation) throws RepositoryException {
-        Sync eventSignal;
-        synchronized (updateMonitor) {
+        if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
+            Sync eventSignal;
+            synchronized (updateMonitor) {
+                new OperationVisitorImpl(sessionInfo).execute(operation);
+                eventSignal = getEventPollingRequest();
+            }
+            try {
+                eventSignal.acquire();
+            } catch (InterruptedException e) {
+                Thread.interrupted();
+                log.warn("Interrupted while waiting for events from RepositoryService");
+            }
+        } else {
+            // execute operation and delegate invalidation of affected item
+            // states to the operation.
             new OperationVisitorImpl(sessionInfo).execute(operation);
-            eventSignal = getEventPollingRequest();
-        }
-        try {
-            eventSignal.acquire();
-        } catch (InterruptedException e) {
-            Thread.interrupted();
-            log.warn("Interrupted while waiting for events from RepositoryService");
+            operation.persisted();
         }
     }
 
@@ -451,20 +460,30 @@
      * @throws RepositoryException
      */
     public void execute(ChangeLog changes) throws RepositoryException {
-        Sync eventSignal;
-        synchronized (updateMonitor) {
+        if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
+            // TODO: TOBEFIXED. processing events after changelog may lead to consistency problems (duplicate processing) (e.g. removal of SNSs).
+            // TODO: filtering of events required according to information present in the changelog.
+            Sync eventSignal;
+            synchronized (updateMonitor) {
+                new OperationVisitorImpl(sessionInfo).execute(changes);
+                changes.persisted();
+                eventSignal = getEventPollingRequest();
+            }
+            try {
+                eventSignal.acquire();
+            } catch (InterruptedException e) {
+                Thread.interrupted();
+                log.warn("Interrupted while waiting for events from RepositoryService");
+            }
+        } else {
             new OperationVisitorImpl(sessionInfo).execute(changes);
             changes.persisted();
-            eventSignal = getEventPollingRequest();
-        }
-        try {
-            eventSignal.acquire();
-        } catch (InterruptedException e) {
-            Thread.interrupted();
-            log.warn("Interrupted while waiting for events from RepositoryService");
         }
     }
 
+    /**
+     * Dispose this <code>WorkspaceManager</code>
+     */
     public void dispose() {
         if (externalChangeFeed != null) {
             externalChangeFeed.interrupt();
@@ -614,15 +633,15 @@
      * Called when local or external events occured. This method is called after
      * changes have been applied to the repository.
      *
-     * @param events the events generated by the repository service as the
-     *               effect of a change.
+     * @param eventBundles the event bundles generated by the repository service
+     * as the effect of an local or external change.
      */
-    private void onEventReceived(EventBundle[] events) {
+    private void onEventReceived(EventBundle[] eventBundles) {
         // notify listener
         InternalEventListener[] lstnrs = (InternalEventListener[]) listeners.toArray(new InternalEventListener[listeners.size()]);
-        for (int i = 0; i < events.length; i++) {
+        for (int i = 0; i < eventBundles.length; i++) {
             for (int j = 0; j < lstnrs.length; j++) {
-                lstnrs[j].onEvent(events[i]);
+                lstnrs[j].onEvent(eventBundles[i]);
             }
         }
     }
@@ -900,6 +919,12 @@
             NodeId vId = operation.getVersionState().getNodeId();
             service.removeVersionLabel(sessionInfo, vhId, vId, operation.getLabel());
         }
+
+        public void visit(RemoveVersion operation) throws VersionException, AccessDeniedException, ReferentialIntegrityException, RepositoryException {
+            NodeState versionState = (NodeState) operation.getRemoveState();
+            NodeState vhState = operation.getParentState();
+            service.removeVersion(sessionInfo, vhState.getNodeId(), versionState.getNodeId());
+        }
     }
 
     /**
@@ -921,11 +946,9 @@
             signal = new Sync() {
                 public void acquire() {
                 }
-
                 public boolean attempt(long l) {
                     return true;
                 }
-
                 public void release() {
                     throw new UnsupportedOperationException();
                 }
@@ -974,15 +997,16 @@
                             log.debug("Request for immediate event poll");
                         }
 
+                        long timeout = 0;
                         // get filters from listeners
                         List filters = new ArrayList();
                         InternalEventListener[] iel = (InternalEventListener[]) listeners.toArray(new InternalEventListener[0]);
                         for (int i = 0; i < iel.length; i++) {
                             filters.addAll(iel[i].getEventFilters());
                         }
-                        EventBundle[] bundles = service.getEvents(sessionInfo,
-                                0, (EventFilter[]) filters.toArray(
-                                        new EventFilter[filters.size()]));
+                        EventFilter[] filtArr = (EventFilter[]) filters.toArray(new EventFilter[filters.size()]);
+
+                        EventBundle[] bundles = service.getEvents(sessionInfo, timeout, filtArr);
                         if (bundles.length > 0) {
                             onEventReceived(bundles);
                         }

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -466,6 +466,7 @@
             // child properties nor from the original lock request.
             this.lockInfo = wspManager.getLockInfo(lockHoldingState.getNodeId());
 
+            // TODO: TOBEFIXED...repository may not support observation
             // 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,

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -65,6 +65,12 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getVersionHistoryState() {
         return versionHistoryState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -60,6 +60,14 @@
         visitor.visit(this);
     }
 
+    /**
+     * Throws UnsupportedOperationException
+     *
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
+    }
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getParentState() {
         return parentState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -61,6 +61,14 @@
         visitor.visit(this);
     }
 
+    /**
+     * Throws UnsupportedOperationException
+     *
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
+    }
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getParentState() {
         return parentState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -48,6 +48,12 @@
         return nodeState;
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
     //------------------------------------------------------------< Factory >---
     public static Operation create(NodeState nodeState) {
         return new Checkin(nodeState);

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -43,6 +43,12 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {
         return nodeState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -52,6 +52,13 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+
     //----------------------------------------< Access Operation Parameters >---
     public boolean isRemoveExisting() {
         return removeExisting;

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Copy.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Copy.java?view=diff&rev=477095&r1=477094&r2=477095
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Copy.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Copy.java Mon Nov 20 00:06:18 2006
@@ -47,6 +47,12 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
     //------------------------------------------------------------< Factory >---
     public static Operation create(Path srcPath, Path destPath,
                                    String srcWorkspaceName,

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -51,6 +51,13 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {
         return nodeState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -47,6 +47,13 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+    
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {
         return nodeState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -47,6 +47,13 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+    
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {
         return nodeState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -54,6 +54,13 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {
         return nodeState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -72,6 +72,18 @@
         visitor.visit(this);
     }
 
+    /**
+     * Throws UnsupportedOperationException
+     *
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        if (srcState.isWorkspaceState()) {
+            // TODO
+        } else {
+            throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
+        }
+    }
     //----------------------------------------< Access Operation Parameters >---
     public NodeId getSourceId() {
         return srcId;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -23,6 +23,7 @@
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.RepositoryException;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.version.VersionException;
 import java.util.Collection;
@@ -53,4 +54,12 @@
      * @return collection of affected <code>ItemState</code>s.
      */
     public Collection getAffectedItemStates();
+
+    /**
+     * In case of {@link CacheBehaviour#MANUAL} or {@link CacheBehaviour#INVALIDATE}
+     * 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.
+     */
+    public void persisted();
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/OperationVisitor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/OperationVisitor.java?view=diff&rev=477095&r1=477094&r2=477095
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/OperationVisitor.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/OperationVisitor.java Mon Nov 20 00:06:18 2006
@@ -26,6 +26,7 @@
 import javax.jcr.InvalidItemStateException;
 import javax.jcr.PathNotFoundException;
 import javax.jcr.MergeException;
+import javax.jcr.ReferentialIntegrityException;
 import javax.jcr.version.VersionException;
 
 /**
@@ -72,4 +73,6 @@
     public void visit(AddLabel operation) throws VersionException, RepositoryException;
 
     public void visit(RemoveLabel operation) throws VersionException, RepositoryException;
+
+    public void visit(RemoveVersion operation) throws VersionException, AccessDeniedException, ReferentialIntegrityException, RepositoryException;
 }

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -31,7 +31,7 @@
 
     private ItemState removeState;
 
-    private Remove(ItemState removeState) {
+    protected Remove(ItemState removeState) {
         this.removeState = removeState;
 
         addAffectedItemState(removeState);
@@ -40,11 +40,19 @@
 
     //----------------------------------------------------------< Operation >---
     /**
-     *
-     * @param visitor
+     * @see Operation#accept(OperationVisitor)
      */
     public void accept(OperationVisitor visitor) throws AccessDeniedException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
         visitor.visit(this);
+    }
+
+    /**
+     * Throws UnsupportedOperationException
+     *
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        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/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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -63,6 +63,13 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getVersionHistoryState() {
         return versionHistoryState;

Added: 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=auto&rev=477095
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java (added)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java Mon Nov 20 00:06:18 2006
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Copyright 1997-2005 Day Management AG
+ * Barfuesserplatz 6, 4001 Basel, Switzerland
+ * All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Day Management AG, ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Day.
+ */
+package org.apache.jackrabbit.jcr2spi.operation;
+
+import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.VersionException;
+
+/**
+ * <code>Remove</code>...
+ */
+public class RemoveVersion extends Remove {
+
+    protected RemoveVersion(ItemState removeState) {
+        super(removeState);
+    }
+
+    //----------------------------------------------------------< Operation >---
+    /**
+     * @see Operation#accept(OperationVisitor)
+     */
+    public void accept(OperationVisitor visitor) throws AccessDeniedException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
+        visitor.visit(this);
+    }
+
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+
+    //------------------------------------------------------------< Factory >---
+    public static Operation create(NodeState versionState) {
+        RemoveVersion rm = new RemoveVersion(versionState);
+        return rm;
+    }
+}

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

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

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -52,6 +52,14 @@
         visitor.visit(this);
     }
 
+    /**
+     * Throws UnsupportedOperationException
+     *
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        throw new UnsupportedOperationException("persisted() not implemented for transient modification.");
+    }
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getParentState() {
         return parentState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -53,6 +53,12 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {
         return nodeState;

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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -58,6 +58,12 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
     //----------------------------------------< 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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -55,9 +55,19 @@
     /**
      *
      * @param visitor
+     * @see Operation#accept(OperationVisitor) 
      */
     public void accept(OperationVisitor visitor) throws AccessDeniedException, NoSuchNodeTypeException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
         visitor.visit(this);
+    }
+
+    /**
+     * Throws UnsupportedOperationException
+     *
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        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/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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -52,9 +52,19 @@
     /**
      *
      * @param visitor
+     * @see Operation#accept(OperationVisitor)
      */
     public void accept(OperationVisitor visitor) throws ValueFormatException, LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
         visitor.visit(this);
+    }
+
+    /**
+     * Throws UnsupportedOperationException
+     *
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        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/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=477095&r1=477094&r2=477095
==============================================================================
--- 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 Mon Nov 20 00:06:18 2006
@@ -49,6 +49,13 @@
         visitor.visit(this);
     }
 
+    /**
+     * @see Operation#persisted()
+     */
+    public void persisted() {
+        // TODO
+    }
+
     //----------------------------------------< Access Operation Parameters >---
     public NodeState getNodeState() {
         return nodeState;

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java?view=diff&rev=477095&r1=477094&r2=477095
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java Mon Nov 20 00:06:18 2006
@@ -48,11 +48,6 @@
     final Set deletedStates = new LinkedHashSet();
 
     /**
-     * Modified references
-     */
-    final Set modifiedRefs = new LinkedHashSet();
-
-    /**
      * Type of operation this changelog is collection state modifications for.
      */
     private Set operations = new LinkedHashSet();
@@ -114,15 +109,6 @@
     }
 
     /**
-     * A references has been modified
-     *
-     * @param refs refs that has been modified
-     */
-    public void modified(NodeReferences refs) {
-        modifiedRefs.add(refs);
-    }
-
-    /**
      * Call this method when this change log has been sucessfully persisted.
      * This implementation will call {@link ItemState#persisted(ChangeLog)
      * ItemState.refresh(this)} on the target item of this change log.
@@ -184,12 +170,18 @@
     }
 
     /**
-     * Return an iterator over all modified references.
+     * Removes the subset of this changelog represented by the given
+     * <code>ChangeLog</code> from this changelog.
      *
-     * @return iterator over all modified references.
+     * @param subChangeLog remove all entries (states, operations) present in
+     * the given changelog from this changelog.
      */
-    public Iterator modifiedRefs() {
-        return modifiedRefs.iterator();
+    public void removeAll(ChangeLog subChangeLog) {
+        addedStates.removeAll(subChangeLog.addedStates);
+        modifiedStates.removeAll(subChangeLog.modifiedStates);
+        deletedStates.removeAll(subChangeLog.deletedStates);
+
+        operations.removeAll(subChangeLog.operations);
     }
 
     /**
@@ -245,7 +237,6 @@
         }
     }
 
-    //-----------------------------< Inform ChangeLog about Success/Failure >---
     /**
      * Reset this change log, removing all members inside the
      * maps we built.
@@ -254,7 +245,6 @@
         addedStates.clear();
         modifiedStates.clear();
         deletedStates.clear();
-        modifiedRefs.clear();
         // also clear all operations
         operations.clear();
     }
@@ -272,19 +262,7 @@
         buf.append("#addedStates=").append(addedStates.size());
         buf.append(", #modifiedStates=").append(modifiedStates.size());
         buf.append(", #deletedStates=").append(deletedStates.size());
-        buf.append(", #modifiedRefs=").append(modifiedRefs.size());
         buf.append("}");
         return buf.toString();
-    }
-
-    //----------------------------------< for derived classes >-----------------
-
-    /**
-     * Removes the <code>operation</code> from the list of operations.
-     * @param operation the Operation to remove.
-     * @return <code>true</code> if the operation was removed.
-     */
-    protected boolean removeOperation(Operation operation) {
-        return operations.remove(operation);
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java?view=diff&rev=477095&r1=477094&r2=477095
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java Mon Nov 20 00:06:18 2006
@@ -29,7 +29,6 @@
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.RepositoryException;
 import java.util.Collection;
-import java.util.Set;
 import java.util.Iterator;
 import java.util.Collections;
 
@@ -283,22 +282,35 @@
             }
         }
         if (status == Status.MODIFIED) {
-            // change back tmp MODIFIED status, that is used only to have a marker
-            // to inform the overlaying state, that it needs to synchronize with
-            // its overlayed state again
+            /*
+            change back tmp MODIFIED status, that is used as marker only to
+            force the overlaying state to synchronize as well as to inform
+            other listeners about changes.
+            */
             // TODO: improve...
             status = Status.EXISTING;
         }
     }
 
     /**
-     * Refreshes this item state recursively according to {@link
-     * javax.jcr.Item#refresh(boolean) Item.refresh(true)}. That is, changes
-     * are kept and updated to reflect the current persistent state of this
-     * item.
+     * Reloads this item state recursively. If '<code>keepChanges</code>' is
+     * true, states with transient changes are left untouched. Otherwise this
+     * state gets its data reloaded from the persistent state.
      * todo throw exception in case of error?
      */
-    public abstract void refresh();
+    public abstract void reload(boolean keepChanges);
+
+    /**
+     * Merge all data from the given state into this state. If
+     * '<code>keepChanges</code>' is true, transient modifications present on
+     * this state are not touched. Otherwise this state is completely reset
+     * according to the given other state.
+     *
+     * @param another
+     * @param keepChanges
+     * @return true if this state has been modified
+     */
+    abstract boolean merge(ItemState another, boolean keepChanges);
 
     /**
      * Invalidates this item state recursively. In contrast to {@link #refresh}
@@ -306,7 +318,7 @@
      * Status#INVALIDATED} and does not acutally update it with the persistent
      * state in the repository.
      */
-    public abstract void invalidate();
+    public abstract void invalidate(boolean recursive);
 
     /**
      * Add an <code>ItemStateLifeCycleListener</code>
@@ -356,12 +368,14 @@
                     // underlying state has been modified by external changes
                     if (status == Status.EXISTING || status == Status.INVALIDATED) {
                         synchronized (this) {
-                            reset();
+                            if (merge(state, false) || status == Status.INVALIDATED) {
+                                // temporarily set the state to MODIFIED in order
+                                // to inform listeners.
+                                setStatus(Status.MODIFIED);
+                            }
                         }
-                        // temporarily set the state to MODIFIED in order to
-                        // inform listeners.
-                        setStatus(Status.MODIFIED);
                     } else if (status == Status.EXISTING_MODIFIED) {
+                        // TODO: try to merge changes
                         setStatus(Status.STALE_MODIFIED);
                     }
                     // else: this status is EXISTING_REMOVED => ignore.
@@ -375,8 +389,10 @@
                     }
                     break;
                 case Status.INVALIDATED:
-                    // invalidate session state as well
-                    setStatus(Status.INVALIDATED);
+                    // invalidate this session state if it is EXISTING.
+                    if (status == Status.EXISTING) {
+                        setStatus(Status.INVALIDATED);
+                    }
                     break;
                 default:
                     // Should never occur, since 'setStatus(int)' already validates
@@ -476,11 +492,6 @@
     abstract void persisted(ChangeLog changeLog) throws IllegalStateException;
 
     /**
-     * Copy all state information from overlayed state to this state
-     */
-    abstract void reset();
-
-    /**
      * Connect this state to some underlying overlayed state.
      */
     void connect(ItemState overlayedState) {
@@ -500,31 +511,95 @@
      * Status#REMOVED} depending on the current status.
      *
      * @throws ItemStateException if an error occurs while removing this item
-     *                            state. e.g. this item state is not valid
-     *                            anymore.
+     * state. e.g. this item state is not valid anymore.
      */
-    abstract void remove() throws ItemStateException;
+    void remove() throws ItemStateException {
+        checkIsSessionState();
+        if (!isValid()) {
+            throw new ItemStateException("Cannot remove an invalid ItemState");
+        }
+        int oldStatus = getStatus();
+        if (oldStatus == Status.NEW) {
+            setStatus(Status.REMOVED);
+        } else {
+            setStatus(Status.EXISTING_REMOVED);
+        }
+        // now inform parent
+        getParent().childStatusChanged(this, oldStatus);
+    }
 
     /**
      * Reverts this item state to its initial status (i.e. removing any transient
-     * modifications and adds itself to the Set of <code>affectedItemStates</code>
-     * if it is reverted itself.
-     *
-     * @param affectedItemStates the set of affected item states that reverted
-     * themselfes.
+     * modifications.
      */
-    abstract void revert(Set affectedItemStates);
+    void revert() throws ItemStateException {
+        checkIsSessionState();
+
+        switch (getStatus()) {
+            case Status.EXISTING_MODIFIED:
+            case Status.STALE_MODIFIED:
+                // revert state from overlayed
+                merge(overlayedState, false);
+                setStatus(Status.EXISTING);
+                break;
+            case Status.EXISTING_REMOVED:
+                // revert state from overlayed
+                merge(overlayedState, false);
+                setStatus(Status.EXISTING);
+                parent.childStatusChanged(this, Status.EXISTING_REMOVED);
+                break;
+            case Status.NEW:
+                remove();
+                break;
+            case Status.STALE_DESTROYED:
+                // overlayed does not exist any more
+                // cannot call 'remove' on invalid state -> manuall remove
+                setStatus(Status.REMOVED);
+                parent.childStatusChanged(this, Status.STALE_DESTROYED);
+                break;
+            default:
+                // Cannot revert EXISTING, REMOVED, INVALIDATED, MODIFIED states.
+                // State was implicitely reverted
+                log.debug("State with status " + getStatus() + " cannot be reverted.");
+        }
+    }
 
     /**
-     * Checks if this <code>ItemState</code> is transiently modified or new and
-     * adds itself to the <code>Set</code> of <code>transientStates</code> if
-     * that is the case. It this <code>ItemState</code> has children it will
-     * call the method {@link #collectTransientStates(Collection)} on those
-     * <code>ItemState</code>s.
+     * Checks if this <code>ItemState</code> is transiently modified, new or stale
+     * modified. and adds itself to the <code>ChangeLog</code>.
+     * If this <code>ItemState</code> has children it will call
+     * {@link #collectStates(ChangeLog, boolean)} recursively.
      *
-     * @param transientStates the <code>Set</code> of transient <code>ItemState</code>,
+     * @param changeLog the <code>ChangeLog</code> collecting the transient
+     * item states present in a given tree.
+     * @param throwOnStale If the given flag is true, this methods throws
+     * StaleItemStateException if this state is stale.
+     * @throws StaleItemStateException if <code>throwOnStale</code> is true and
+     * this state is stale.
      */
-    abstract void collectTransientStates(Collection transientStates);
+    void collectStates(ChangeLog changeLog, boolean throwOnStale) throws StaleItemStateException {
+        checkIsSessionState();
+        if (throwOnStale && Status.isStale(getStatus())) {
+            String msg = "Cannot save changes: " + getId() + " has been modified externally.";
+            log.debug(msg);
+            throw new StaleItemStateException(msg);
+        }
+        // only interested in transient modifications or stale-modified states
+        switch (getStatus()) {
+            case Status.NEW:
+                changeLog.added(this);
+                break;
+            case Status.EXISTING_MODIFIED:
+            case Status.STALE_MODIFIED:
+                changeLog.modified(this);
+                break;
+            case Status.EXISTING_REMOVED:
+                changeLog.deleted(this);
+                break;
+            default:
+                log.debug("Collecting states: Ignored ItemState with status " + getStatus());
+        }
+    }
 
     /**
      * Marks this item state as modified.

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java?view=diff&rev=477095&r1=477094&r2=477095
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java Mon Nov 20 00:06:18 2006
@@ -320,8 +320,7 @@
      * @throws RepositoryException
      */
     public void checkIsWritable(NodeState parentState, int options) throws VersionException,
-        LockException, ItemNotFoundException,
-        ItemExistsException, PathNotFoundException, RepositoryException {
+        LockException, ItemNotFoundException, ItemExistsException, PathNotFoundException, RepositoryException {
 
         if ((options & CHECK_ACCESS) == CHECK_ACCESS) {
             // make sure current session is granted read access on parent node
@@ -329,17 +328,14 @@
                 throw new ItemNotFoundException(safeGetJCRPath(parentState));
             }
         }
-
         // make sure there's no foreign lock on parent node
         if ((options & CHECK_LOCK) == CHECK_LOCK) {
             checkLock(parentState);
         }
-
         // make sure parent node is checked-out
         if ((options & CHECK_VERSIONING) == CHECK_VERSIONING) {
             checkIsCheckedOut(parentState);
         }
-
         // constraints
         if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
             // make sure parent node is not protected
@@ -451,13 +447,11 @@
                 throw new AccessDeniedException(safeGetJCRPath(parentState) + ": not allowed to create property with name " + propertyName);
             }
         }
-
         // constraints on property
         if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
             // if definition is available check if prop-def is not protected either.
             checkProtection(definition);
         }
-
         // collisions
         if ((options & CHECK_COLLISION) == CHECK_COLLISION) {
             checkCollision(parentState, propertyName);
@@ -512,14 +506,12 @@
                 throw new AccessDeniedException(safeGetJCRPath(parentState) + ": not allowed to add child node '" + nodeName +"'");
             }
         }
-
         // node type constraints
         if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
             // make sure there's an applicable definition for new child node
             EffectiveNodeType entParent = getEffectiveNodeType(parentState);
             entParent.checkAddNodeConstraints(nodeName, nodeTypeName);
         }
-
         // collisions
         if ((options & CHECK_COLLISION) == CHECK_COLLISION) {
             checkCollision(parentState, nodeName, nodeTypeName);
@@ -589,7 +581,6 @@
             // check if target not protected and not mandatory
             checkRemoveConstraints(targetState);
         }
-
         // check referential integrity of state to be deleted
         if ((options & CHECK_REFERENCES) == CHECK_REFERENCES) {
             checkReferences(targetState);