jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r521356 - in /jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: ./ hierarchy/ state/
Date Thu, 22 Mar 2007 17:22:31 GMT
Author: angela
Date: Thu Mar 22 10:22:29 2007
New Revision: 521356

URL: http://svn.apache.org/viewvc?view=rev&rev=521356
Log:
- remove cachebehaviour flag from ChangeLog.persisted
- minor improvement

Modified:
    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/hierarchy/HierarchyEntry.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/PropertyEntryImpl.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/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

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=521356&r1=521355&r2=521356
==============================================================================
--- 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
Thu Mar 22 10:22:29 2007
@@ -444,7 +444,6 @@
     }
 
     //------------------------------------------< UpdatableItemStateManager >---
-    // TODO: review
     /**
      * Creates a new batch from the single workspace operation and executes it.
      *
@@ -483,8 +482,7 @@
         }
         try {
             new OperationVisitorImpl(sessionInfo).execute(changes);
-            // TODO: remove parameter CacheBehaviour
-            changes.persisted(CacheBehaviour.INVALIDATE);
+            changes.persisted();
         } finally {
             updateSync.release();
         }
@@ -493,23 +491,26 @@
     /**
      * Dispose this <code>WorkspaceManager</code>
      */
-    public void dispose() {
-        if (changeFeed != null) {
-            changeFeed.interrupt();
-        }
-        hierarchyManager.dispose();
+    public synchronized void dispose() {
         try {
+            updateSync.acquire();
+            if (changeFeed != null) {
+                changeFeed.interrupt();
+            }
+            hierarchyManager.dispose();
             service.dispose(sessionInfo);
-        } catch (RepositoryException e) {
-            log.warn("Exception while disposing session info: " + e);
+        } catch (Exception e) {
+            log.warn("Exception while disposing WorkspaceManager: " + e);
+        } finally {
+            updateSync.release();
         }
     }
     //------------------------------------------------------< AccessManager >---
     /**
      * @see AccessManager#isGranted(NodeState, Path, String[])
      */
-    public boolean isGranted(NodeState parentState, Path relPath, String[] actions) throws
ItemNotFoundException, RepositoryException {
-        // TODO: correct?
+    public boolean isGranted(NodeState parentState, Path relPath, String[] actions)
+            throws ItemNotFoundException, RepositoryException {
         if (parentState.getStatus() == Status.NEW) {
             return true;
         }
@@ -607,7 +608,6 @@
     }
 
     //--------------------------------------------------------------------------
-
     /**
      * Called when local or external events occured. This method is called after
      * changes have been applied to the repository.
@@ -620,7 +620,7 @@
             log.debug("received {} event bundles.", new Integer(eventBundles.length));
             for (int i = 0; i < eventBundles.length; i++) {
                 log.debug("BundleId: {}", eventBundles[i].getBundleId());
-                log.debug("IsLocal:  {}", new Boolean(eventBundles[i].isLocal()));
+                log.debug("IsLocal:  {}", Boolean.valueOf(eventBundles[i].isLocal()));
                 for (EventIterator it = eventBundles[i].getEvents(); it.hasNext(); ) {
                     Event e = it.nextEvent();
                     String type;

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java
Thu Mar 22 10:22:29 2007
@@ -141,10 +141,12 @@
      * if the item has been transiently added before. In the latter case, the
      * corresponding HierarchyEntries can be removed as well from their parent.
      *
+     * @throws InvalidItemStateException if this entry has been removed in the
+     * mean time.
      * @throws RepositoryException if an error occurs while removing any of the item
      * states e.g. an item state is not valid anymore.
      */
-    public void transientRemove() throws RepositoryException;
+    public void transientRemove() throws InvalidItemStateException, RepositoryException;
 
     /**
      * Removes this <code>HierarchyEntry</code> from its parent and sets the

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java
Thu Mar 22 10:22:29 2007
@@ -161,6 +161,16 @@
         }
     }
 
+    static void removeEntry(HierarchyEntryImpl entry) {
+        ItemState state = entry.internalGetItemState();
+        if (state != null) {
+            if (state.getStatus() == Status.NEW) {
+                state.setStatus(Status.REMOVED);
+            } else {
+                state.getWorkspaceState().setStatus(Status.REMOVED);
+            }
+        }
+    }
     //-----------------------------------------------------< HierarchyEntry >---
     /**
      * @inheritDoc
@@ -321,7 +331,7 @@
      * {@inheritDoc}
      * @see HierarchyEntry#transientRemove()
      */
-    public void transientRemove() throws RepositoryException {
+    public void transientRemove() throws InvalidItemStateException, RepositoryException {
         ItemState state = internalGetItemState();
         if (state == null) {
             // nothing to do -> correct status must be set upon resolution.
@@ -350,6 +360,9 @@
                 // removed propertyEntry is automatically moved to the 'attic'
                 // if a conflict with a new entry occurs.
                 break;
+            case Status.REMOVED:
+            case Status.STALE_DESTROYED:
+                throw new InvalidItemStateException("Item has already been removed by someone
else. Status = " + Status.getName(state.getStatus()));
             default:
                 throw new RepositoryException("Cannot transiently remove an ItemState with
status " + Status.getName(state.getStatus()));
         }
@@ -371,13 +384,14 @@
             log.debug(msg);
             throw new InvalidItemStateException(msg);
         }
-        // only interested in transient modifications or stale-modified states
+        // only interested in transient modifications or stale states
         switch (state.getStatus()) {
             case Status.NEW:
                 changeLog.added(state);
                 break;
             case Status.EXISTING_MODIFIED:
             case Status.STALE_MODIFIED:
+            case Status.STALE_DESTROYED:
                 changeLog.modified(state);
                 break;
             case Status.EXISTING_REMOVED:

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java
Thu Mar 22 10:22:29 2007
@@ -227,15 +227,8 @@
      * @see HierarchyEntry#remove()
      */
     public void remove() {
-        ItemState state = internalGetItemState();
-        if (state != null) {
-            if (state.getStatus() == Status.NEW) {
-                state.setStatus(Status.REMOVED);
-            } else {
-                state.getWorkspaceState().setStatus(Status.REMOVED);
-            }
-        }
-        if (parent.childNodeEntries != null) {
+        removeEntry(this);
+        if (getStatus() != Status.STALE_DESTROYED && parent.childNodeEntries != null)
{
             NodeEntry removed = parent.childNodeEntries.remove(this);
             if (removed == null) {
                 // try attic
@@ -248,14 +241,7 @@
         // since this (i.e. the parent is removed as well).
         for (Iterator it = getAllChildEntries(true, true); it.hasNext();) {
             HierarchyEntryImpl ce = (HierarchyEntryImpl) it.next();
-            state = ce.internalGetItemState();
-            if (state != null) {
-                if (state.getStatus() == Status.NEW) {
-                    state.setStatus(Status.REMOVED);
-                } else {
-                    state.getWorkspaceState().setStatus(Status.REMOVED);
-                }
-            }
+            removeEntry(ce);
         }
     }
 
@@ -268,7 +254,7 @@
      * @inheritDoc
      * @see HierarchyEntry#collectStates(ChangeLog, boolean)
      */
-    public void collectStates(ChangeLog changeLog, boolean throwOnStale) throws InvalidItemStateException
{
+    public synchronized void collectStates(ChangeLog changeLog, boolean throwOnStale) throws
InvalidItemStateException {
         super.collectStates(changeLog, throwOnStale);
 
         // collect transient child states including properties in attic.
@@ -654,8 +640,7 @@
      */
     public synchronized Iterator getPropertyEntries() {
         Collection props;
-        ItemState state = internalGetItemState();
-        if (state != null && state.getStatus() == Status.EXISTING_MODIFIED) {
+        if (getStatus() == Status.EXISTING_MODIFIED) {
             // filter out removed properties
             props = new ArrayList();
             // use array since upon validation the entry might be removed.
@@ -678,7 +663,18 @@
      * @see NodeEntry#addPropertyEntry(QName)
      */
     public PropertyEntry addPropertyEntry(QName propName) throws ItemExistsException {
-        // TODO: check if correct, that check for existing prop can be omitted.
+        // TODO: check for existing prop.
+        return internalAddPropertyEntry(propName);
+    }
+
+    /**
+     * Internal method that adds a PropertyEntry without checking of that entry
+     * exists.
+     *
+     * @param propName
+     * @return
+     */
+    private PropertyEntry internalAddPropertyEntry(QName propName) {
         PropertyEntry entry = PropertyEntryImpl.create(this, propName, factory);
         properties.put(propName, entry);
 
@@ -715,7 +711,9 @@
             for (Iterator it = diff.iterator(); it.hasNext();) {
                 QName propName = (QName) it.next();
                 PropertyEntry pEntry = (PropertyEntry) properties.get(propName);
-                pEntry.remove();
+                if (pEntry != null) {
+                    pEntry.remove();
+                }
             }
         }
     }
@@ -837,8 +835,7 @@
      * @param childEvent
      * @see NodeEntry#refresh(Event)
      */
-    public synchronized void refresh(Event childEvent) {
-        boolean modified = false; // TODO: see todo below
+    public void refresh(Event childEvent) {
         QName eventName = childEvent.getQPath().getNameElement().getName();
         switch (childEvent.getType()) {
             case Event.NODE_ADDED:
@@ -856,38 +853,30 @@
                     cne = childNodeEntries().get(eventName, index);
                 }
                 if (cne == null) {
-                    cne = internalAddNodeEntry(eventName, uniqueChildID, index, childNodeEntries());
-                    modified = true;
+                    internalAddNodeEntry(eventName, uniqueChildID, index, childNodeEntries());
                 } else {
                     // child already exists -> deal with NEW entries, that were
                     // added by some other session.
                     // TODO: TOBEFIXED
-
                 }
                 break;
 
             case Event.PROPERTY_ADDED:
                 // create a new property reference if it has not been
                 // added by some earlier 'add' event
-                if (!hasPropertyEntry(eventName)) {
-                    try {
-                        addPropertyEntry(eventName);
-                        modified = true;
-                    } catch (ItemExistsException e) {
-                        log.warn("Internal error", e);
-                        // TODO
-                    }
+                HierarchyEntry child = lookupEntry(childEvent.getItemId(), childEvent.getQPath());
+                if (child == null) {
+                    internalAddPropertyEntry(eventName);
                 } else {
-                    // TODO: TOBEFIXED deal with NEW entries
+                    child.reload(false, true);
                 }
                 break;
 
             case Event.NODE_REMOVED:
             case Event.PROPERTY_REMOVED:
-                HierarchyEntry child = lookupEntry(childEvent.getItemId(), childEvent.getQPath());
+                child = lookupEntry(childEvent.getItemId(), childEvent.getQPath());
                 if (child != null) {
                     child.remove();
-                    modified = true;
                 } // else: child-Entry has not been loaded yet -> ignore
                 break;
 
@@ -902,25 +891,16 @@
                     // (i.e. this NodeEntry) since both props are protected
                     if (StateUtility.isUuidOrMixin(eventName)) {
                         notifyUUIDorMIXINModified((PropertyEntry) child);
-                        modified = true;
                     }
                 } else {
                     // prop-Entry has not been loaded yet -> add propEntry
-                    try {
-                        addPropertyEntry(eventName);
-                        modified = true;
-                    } catch (ItemExistsException e) {
-                        log.warn("Internal error", e);
-                        // TODO
-                    }
+                    internalAddPropertyEntry(eventName);
                 }
                 break;
             default:
                 // ILLEGAL
                 throw new IllegalArgumentException("Illegal event type " + childEvent.getType()
+ " for NodeState.");
         }
-
-        // TODO: check if status of THIS_state must be marked modified...
     }
 
     //-------------------------------------------------< HierarchyEntryImpl >---
@@ -960,7 +940,7 @@
      * @param builder builder currently being used
      * @param hEntry HierarchyEntry of the state the path should be built for.
      */
-    private static void buildPath(Path.PathBuilder builder, NodeEntryImpl nEntry, boolean
wspPath) {
+    private static void buildPath(Path.PathBuilder builder, NodeEntryImpl nEntry, boolean
wspPath) throws RepositoryException {
         NodeEntryImpl parentEntry = (wspPath && nEntry.revertInfo != null) ? nEntry.revertInfo.oldParent
: nEntry.parent;
         // shortcut for root state
         if (parentEntry == null) {
@@ -974,6 +954,11 @@
         int index = (wspPath) ? nEntry.getWorkspaceIndex() : nEntry.getIndex();
         QName name = (wspPath) ? nEntry.getWorkspaceQName() : nEntry.getQName();
         // add to path
+        if (index == Path.INDEX_UNDEFINED) {
+            throw new RepositoryException("Invalid index " + index + " with nodeEntry " +
nEntry);
+        }
+
+        // TODO: check again. special treatment for index 0 for consistency with PathFormat.parse
         if (index == Path.INDEX_DEFAULT) {
             builder.addLast(name);
         } else {
@@ -1117,8 +1102,10 @@
                     state.setMixinTypeNames(StateUtility.getMixinNames(ps));
                 } // nodestate not yet loaded -> ignore change
             }
+        } catch (ItemNotFoundException e) {
+            log.debug("Property with name " + child.getQName() + " does not exist (anymore)");
         } catch (RepositoryException e) {
-            log.error("Internal Error", e);
+            log.debug("Unable to access child property " + child.getQName(), e.getMessage());
         }
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/PropertyEntryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/PropertyEntryImpl.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/PropertyEntryImpl.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/PropertyEntryImpl.java
Thu Mar 22 10:22:29 2007
@@ -122,14 +122,9 @@
      * @see HierarchyEntry#remove()
      */
     public void remove() {
-        ItemState state = internalGetItemState();
-        if (state != null) {
-            if (state.getStatus() == Status.NEW) {
-                state.setStatus(Status.REMOVED);
-            } else {
-                state.getWorkspaceState().setStatus(Status.REMOVED);
-            }
+        removeEntry(this);
+        if (getStatus() != Status.STALE_DESTROYED) {
+            parent.internalRemovePropertyEntry(getQName());
         }
-        parent.internalRemovePropertyEntry(getQName());
     }
 }

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=521356&r1=521355&r2=521356
==============================================================================
--- 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
Thu Mar 22 10:22:29 2007
@@ -20,10 +20,11 @@
 import org.apache.jackrabbit.jcr2spi.operation.AddNode;
 import org.apache.jackrabbit.jcr2spi.operation.AddProperty;
 import org.apache.jackrabbit.jcr2spi.operation.SetMixin;
-import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.apache.jackrabbit.name.QName;
 import org.apache.commons.collections.iterators.IteratorChain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.RepositoryException;
@@ -39,6 +40,15 @@
  */
 public class ChangeLog {
 
+    /**
+     * Logger instance for this class.
+     */
+    private static final Logger log = LoggerFactory.getLogger(ChangeLog.class);
+
+    /**
+     * The changelog target: Root item of the tree whose changes are contained
+     * in this changelog.
+     */
     private final ItemState target;
     /**
      * Added states
@@ -118,12 +128,11 @@
 
     /**
      * Call this method when this change log has been sucessfully persisted.
-     * This implementation will call {@link ItemState#persisted(ChangeLog, CacheBehaviour)
+     * This implementation will call {@link ItemState#persisted(ChangeLog)
      * ItemState.refresh(this)} on the target item of this change log.
-     * TODO: remove parameter CacheBehaviour
      */
-    public void persisted(CacheBehaviour cacheBehaviour) {
-        target.persisted(this, cacheBehaviour);
+    public void persisted() {
+        target.persisted(this);
     }
 
     /**
@@ -217,12 +226,14 @@
     }
 
     /**
+     * Adjust this ChangeLog according to the status change with the given
+     * ItemState:
      * Remove all entries and operation related to the given ItemState, that
      * are not used any more (respecting the status change).
      *
      * @param state
      */
-    public void removeAffected(ItemState state, int previousStatus) {
+    public void statusChanged(ItemState state, int previousStatus) {
         switch (state.getStatus()) {
             case (Status.EXISTING):
                 switch (previousStatus) {
@@ -248,68 +259,73 @@
             case Status.EXISTING_MODIFIED:
                 modified(state);
                 break;
-            case (Status.REMOVED):
-                if (previousStatus == Status.NEW) {
-                    // was new and now removed again
-                    addedStates.remove(state);
-                    deletedStates.remove(state);
-                    // remove operations performed on the removed state
-                    removeAffectedOperations(state);
-                    /* remove the add-operation as well:
-                       since the affected state of an 'ADD' operation is the parent
-                       instead of the added-state, the set of operations
-                       need to be searched for the parent state && the proper
-                       operation type.
-                       SET_MIXIN can be is a special case of adding a property */
-                    NodeEntry parentEntry = state.getHierarchyEntry().getParent();
-                    if (parentEntry != null && parentEntry.isAvailable()) {
-                        try {
-                            NodeState parent = parentEntry.getNodeState();
-                            if (parent.getStatus() != Status.REMOVED) {
-                                for (Iterator it = operations.iterator(); it.hasNext();)
{
-                                    Operation op = (Operation) it.next();
-                                    if (op instanceof AddNode) {
-                                        AddNode operation = (AddNode) op;
-                                        if (operation.getParentState() == parent
-                                                && operation.getNodeName().equals(state.getQName()))
{
-                                            // TODO: this will not work for name name siblings!
-                                            it.remove();
-                                            break;
-                                        }
-                                    } else if (op instanceof AddProperty) {
-                                        AddProperty operation = (AddProperty) op;
-                                        if (operation.getParentState() == parent
-                                                && operation.getPropertyName().equals(state.getQName()))
{
-                                            it.remove();
-                                            break;
-                                        }
-                                    } else if (op instanceof SetMixin &&
-                                        QName.JCR_MIXINTYPES.equals(state.getQName()) &&
-                                        ((SetMixin)op).getNodeState() == parent) {
-                                        it.remove();
-                                        break;
-                                    }
-                                }
-                            }
-                        } catch (RepositoryException e) {
-                            // should never occur -> ignore
-                        }
-                    }
-                } else if (previousStatus == Status.EXISTING_REMOVED) {
-                    // was removed and is now saved
-                    deletedStates.remove(state);
-                    removeAffectedOperations(state);
-                }
-                break;
             case (Status.EXISTING_REMOVED):
                 deleted(state);
-                removeAffectedOperations(state);
+                // removeAffectedOperations(state);
+                break;
+            case (Status.REMOVED):
+                switch (previousStatus) {
+                    case Status.EXISTING_REMOVED:
+                        // was removed and is now saved
+                        deletedStates.remove(state);
+                        removeAffectedOperations(state);
+                        break;
+                    case Status.NEW:
+                        newStateRemoved(state);
+                        break;
+                }
                 break;
-            case Status.STALE_DESTROYED:
-                // state is now stale. remove from modified
-                modifiedStates.remove(state);
-                removeAffectedOperations(state);
+        }
+    }
+
+    private void newStateRemoved(ItemState state) {
+        NodeEntry parentEntry = state.getHierarchyEntry().getParent();
+        if (!parentEntry.isAvailable() || Status.isTerminal(parentEntry.getStatus())) {
+            return; // TODO: check if correct
+        }
+        // was new and now removed again
+        addedStates.remove(state);
+
+        // remove any operations performed on the removed state
+        removeAffectedOperations(state);
+
+        /* remove the add-operation as well:
+           since the affected state of an 'ADD' operation is the parent instead
+           of the added-state, the set of operations need to be searched for the
+           parent state && the proper operation type.
+           SET_MIXIN is considered as a special case of adding a property
+         */
+        NodeState parent;
+        try {
+            parent = parentEntry.getNodeState();
+        } catch (RepositoryException e) {
+            // should never occur
+            log.error("Internal error:", e);
+            return;
+        }
+        for (Iterator it = operations.iterator(); it.hasNext();) {
+            Operation op = (Operation) it.next();
+            if (op instanceof AddNode) {
+                AddNode operation = (AddNode) op;
+                if (operation.getParentState() == parent
+                        && operation.getNodeName().equals(state.getQName())) {
+                    // TODO: this will not work for name name siblings!
+                    it.remove();
+                    break;
+                }
+            } else if (op instanceof AddProperty) {
+                AddProperty operation = (AddProperty) op;
+                if (operation.getParentState() == parent
+                        && operation.getPropertyName().equals(state.getQName()))
{
+                    it.remove();
+                    break;
+                }
+            } else if (op instanceof SetMixin &&
+                    QName.JCR_MIXINTYPES.equals(state.getQName()) &&
+                    ((SetMixin)op).getNodeState() == parent) {
+                it.remove();
                 break;
+            }
         }
     }
 

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=521356&r1=521355&r2=521356
==============================================================================
--- 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
Thu Mar 22 10:22:29 2007
@@ -22,7 +22,6 @@
 import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
-import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
 import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
@@ -396,7 +395,7 @@
      * @param changeLog
      * @throws IllegalStateException if this state is a 'workspace' state.
      */
-    abstract void persisted(ChangeLog changeLog, CacheBehaviour cacheBehaviour) throws IllegalStateException;
+    abstract void persisted(ChangeLog changeLog) throws IllegalStateException;
 
     /**
      * Connect this state to some underlying overlayed state.

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
Thu Mar 22 10:22:29 2007
@@ -17,13 +17,13 @@
 package org.apache.jackrabbit.jcr2spi.state;
 
 import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
 import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
 import org.apache.jackrabbit.jcr2spi.util.StateUtility;
 import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.spi.QNodeDefinition;
@@ -127,7 +127,7 @@
     public ItemId getId() {
         return getNodeId();
     }
-    
+
     /**
      * @see ItemState#merge(ItemState, boolean)
      */
@@ -325,20 +325,19 @@
      * @see PropertyEntry#getPropertyState()
      */
     public PropertyState getPropertyState(QName propertyName) throws ItemNotFoundException,
RepositoryException {
-        PropertyEntry child = getNodeEntry().getPropertyEntry(propertyName);
-        if (child != null) {
-            return child.getPropertyState();
+        HierarchyEntry child = getNodeEntry().getDeepEntry(Path.create(propertyName, Path.INDEX_UNDEFINED));
+        if (child != null && !child.denotesNode()) {
+            return ((PropertyEntry) child).getPropertyState();
         } else {
-            // TODO; correct?
             throw new ItemNotFoundException("Child Property with name " + propertyName +
" does not exist.");
         }
     }
 
     /**
      * {@inheritDoc}
-     * @see ItemState#persisted(ChangeLog, CacheBehaviour)
+     * @see ItemState#persisted(ChangeLog)
      */
-    void persisted(ChangeLog changeLog, CacheBehaviour cacheBehaviour) throws IllegalStateException
{
+    void persisted(ChangeLog changeLog) throws IllegalStateException {
         checkIsSessionState();
 
         // remember parent states that have need to adjust their uniqueID/mixintypes
@@ -348,8 +347,10 @@
         // process deleted states from the changelog
         for (Iterator it = changeLog.deletedStates(); it.hasNext();) {
             ItemState delState = (ItemState) it.next();
-
-            // delState.overlayedState.getHierarchyEntry().remove();
+            if (Status.isTerminal(delState.getStatus())) {
+                log.debug("Removal of State " + delState + " has already been completed.");
+                continue;
+            }
             delState.getHierarchyEntry().remove();
 
             // adjust parent states unless the parent is removed as well
@@ -373,16 +374,18 @@
             ItemState addedState = (ItemState) it.next();
             try {
                 NodeState parent = addedState.getParent();
-                // connect the new state to its overlayed state (including update
-                // via merging in order to be aware of autocreated values,
-                // changed definition etc.
-                addedState.reconnect(false);
-
                 // if parent is modified -> remember for final status reset
                 if (parent.getStatus() == Status.EXISTING_MODIFIED) {
                     modifiedParent(parent, addedState, modParents);
                 }
-                it.remove();
+                if (addedState.getStatus() == Status.EXISTING) {
+                    log.debug("Adding new state " + addedState + " has already been completed.");
+                } else {
+                    // connect the new state to its overlayed state (including update
+                    // via merging in order to be aware of autocreated values,
+                    // changed definition etc.
+                    addedState.reconnect(false);
+                }
             } catch (RepositoryException e) {
                 // should never occur
                 log.error("Internal error:", e.getMessage());
@@ -391,6 +394,10 @@
 
         for (Iterator it = changeLog.modifiedStates(); it.hasNext();) {
             ItemState modState = (ItemState) it.next();
+            if (modState.getStatus() == Status.EXISTING) {
+                log.debug("Modified state has already been processed");
+                continue;
+            }
             if (modState.isNode()) {
                 if (StateUtility.isMovedState((NodeState) modState)) {
                     // set definition of overlayed according to session-state
@@ -399,7 +406,6 @@
 
                     // and mark the moved state existing
                     modState.setStatus(Status.EXISTING);
-                    it.remove();
                 } else {
                     // remember state as modified only for later processing
                     if (!modParents.containsKey(modState)) {
@@ -422,7 +428,6 @@
                         log.warn("Internal error:", e.getMessage());
                     }
                 }
-                it.remove();
             }
         }
 
@@ -432,7 +437,7 @@
         for (Iterator it = modParents.keySet().iterator(); it.hasNext();) {
             NodeState parent = (NodeState) it.next();
             List l = (List) modParents.get(parent);
-            adjustNodeState(parent, (PropertyState[]) l.toArray(new PropertyState[l.size()]),
cacheBehaviour);
+            adjustNodeState(parent, (PropertyState[]) l.toArray(new PropertyState[l.size()]));
         }
 
         /* finally check if all entries in the changelog have been processed
@@ -468,7 +473,7 @@
 
         NodeEntry before = (beforeNode == null) ? null : beforeNode.getNodeEntry();
         insertNode.getNodeEntry().orderBefore(before);
-        
+
         // mark this state as modified
         markModified();
     }
@@ -522,8 +527,7 @@
      * @param parent
      * @param props
      */
-    private static void adjustNodeState(NodeState parent, PropertyState[] props,
-                                        CacheBehaviour cacheBehaviour) {
+    private static void adjustNodeState(NodeState parent, PropertyState[] props) {
         NodeState overlayed = (NodeState) parent.overlayedState;
         if (overlayed != null) {
             for (int i = 0; i < props.length; i++) {
@@ -549,14 +553,11 @@
 
             // set parent status to 'existing'
             parent.setStatus(Status.EXISTING);
-            if (cacheBehaviour != CacheBehaviour.OBSERVATION) {
-                // TODO: really necessary???
-                try {
-                    parent.reconnect(false);
-                } catch (RepositoryException e) {
-                    // TODO: handle properly
-                    log.error("Internal error", e);
-                }
+            try {
+                parent.reconnect(false);
+            } catch (RepositoryException e) {
+                // TODO: handle properly
+                log.error("Internal error", e);
             }
         } else {
             // should never occur.

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
Thu Mar 22 10:22:29 2007
@@ -27,7 +27,6 @@
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.jcr2spi.nodetype.ValueConstraint;
 import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider;
-import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
 import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
 import org.slf4j.Logger;
@@ -257,9 +256,9 @@
 
     /**
      * {@inheritDoc}
-     * @see ItemState#persisted(ChangeLog, CacheBehaviour)
+     * @see ItemState#persisted(ChangeLog)
      */
-    void persisted(ChangeLog changeLog, CacheBehaviour cacheBehaviour)
+    void persisted(ChangeLog changeLog)
         throws IllegalStateException {
         checkIsSessionState();
         for (Iterator it = changeLog.modifiedStates(); it.hasNext();) {

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
Thu Mar 22 10:22:29 2007
@@ -663,8 +663,6 @@
         try {
             itemState.getHierarchyEntry().transientRemove();
             success = true;
-        } catch (RepositoryException e) {
-            throw new RepositoryException("Cannot remove item: " + e.getMessage(), e);
         } finally {
             if (!success) {
                 // TODO: TOBEFIXED undo state modifications

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java?view=diff&rev=521356&r1=521355&r2=521356
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
Thu Mar 22 10:22:29 2007
@@ -170,9 +170,9 @@
             case Status.EXISTING_MODIFIED:
             case Status.EXISTING_REMOVED:
             case Status.REMOVED:
-            case Status.STALE_DESTROYED:
-                changeLog.removeAffected(state, previousStatus);
+                changeLog.statusChanged(state, previousStatus);
                 break;
+            case Status.STALE_DESTROYED:
             case Status.STALE_MODIFIED:
                 // state is now stale. keep in modified. wait until refreshed
             case Status.MODIFIED:



Mime
View raw message