jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject svn commit: r191499 [2/3] - in /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: ./ jndi/ lock/ nodetype/ observation/ query/lucene/ state/ state/obj/ state/xml/ version/ virtual/ xml/
Date Mon, 20 Jun 2005 15:58:58 GMT
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java Mon Jun 20 08:58:57 2005
@@ -543,23 +543,8 @@
         return node;
     }
 
-    protected NodeImpl createChildNodeLink(QName nodeName, String targetUUID)
-            throws RepositoryException {
-        // modify the state of 'this', i.e. the parent node
-        NodeState thisState = (NodeState) getOrCreateTransientItemState();
-
-        NodeId targetId = new NodeId(targetUUID);
-        NodeImpl targetNode = (NodeImpl) itemMgr.getItem(targetId);
-        // notify target of link
-        targetNode.onLink(thisState);
-
-        thisState.addChildNodeEntry(nodeName, targetUUID);
-
-        return (NodeImpl) itemMgr.getItem(targetId);
-    }
-
-    protected void renameChildNodeLink(QName oldName, int index, String uuid,
-                                       QName newName)
+    protected void renameChildNode(QName oldName, int index, String uuid,
+                                   QName newName)
             throws RepositoryException {
         // modify the state of 'this', i.e. the parent node
         NodeState thisState = (NodeState) getOrCreateTransientItemState();
@@ -613,18 +598,18 @@
             throw new RepositoryException(msg);
         }
 
-        NodeId childId = new NodeId(entry.getUUID());
-        NodeImpl childNode = (NodeImpl) itemMgr.getItem(childId);
-        // notify target of removal/unlink
-        childNode.onUnlink(thisState);
-
-        // remove child entry
+        // remove the child node entry
         if (!thisState.removeChildNodeEntry(nodeName, index)) {
             String msg = "failed to remove child " + nodeName + " of "
                     + safeGetJCRPath();
             log.debug(msg);
             throw new RepositoryException(msg);
         }
+
+        // notify target of removal
+        NodeId childId = new NodeId(entry.getUUID());
+        NodeImpl childNode = (NodeImpl) itemMgr.getItem(childId);
+        childNode.onRemove();
     }
 
     protected void onRedefine(NodeDefId defId) throws RepositoryException {
@@ -637,51 +622,41 @@
         definition = newDef;
     }
 
-    protected void onLink(NodeState parentState) throws RepositoryException {
+    protected void onRemove() throws RepositoryException {
         // modify the state of 'this', i.e. the target node
         NodeState thisState = (NodeState) getOrCreateTransientItemState();
-        // add uuid of this node to target's parent list
-        thisState.addParentUUID(parentState.getUUID());
-    }
-
-    protected void onUnlink(NodeState parentState) throws RepositoryException {
-        // modify the state of 'this', i.e. the target node
-        NodeState thisState = (NodeState) getOrCreateTransientItemState();
-
-        // check if this node would be orphaned after unlinking it from parent
-        ArrayList parentUUIDs = new ArrayList(thisState.getParentUUIDs());
-        parentUUIDs.remove(parentState.getUUID());
-        boolean orphaned = parentUUIDs.isEmpty();
-
-        if (orphaned) {
-            // remove child nodes (recursive)
-            // use temp array to avoid ConcurrentModificationException
-            ArrayList tmp = new ArrayList(thisState.getChildNodeEntries());
-            // remove from tail to avoid problems with same-name siblings
-            for (int i = tmp.size() - 1; i >= 0; i--) {
-                NodeState.ChildNodeEntry entry =
-                        (NodeState.ChildNodeEntry) tmp.get(i);
-                removeChildNode(entry.getName(), entry.getIndex());
-            }
 
-            // remove properties
-            // use temp array to avoid ConcurrentModificationException
-            tmp = new ArrayList(thisState.getPropertyEntries());
-            for (int i = 0; i < tmp.size(); i++) {
-                NodeState.PropertyEntry entry =
-                        (NodeState.PropertyEntry) tmp.get(i);
-                removeChildProperty(entry.getName());
-            }
+        // remove child nodes
+        // use temp array to avoid ConcurrentModificationException
+        ArrayList tmp = new ArrayList(thisState.getChildNodeEntries());
+        // remove from tail to avoid problems with same-name siblings
+        for (int i = tmp.size() - 1; i >= 0; i--) {
+            NodeState.ChildNodeEntry entry =
+                    (NodeState.ChildNodeEntry) tmp.get(i);
+            // remove the child node entry
+            thisState.removeChildNodeEntry(entry.getName(), entry.getIndex());
+            // recursively remove child node
+            NodeId childId = new NodeId(entry.getUUID());
+            NodeImpl childNode = (NodeImpl) itemMgr.getItem(childId);
+            childNode.onRemove();
         }
 
-        // now actually do unlink this node from specified parent node
-        // (i.e. remove uuid of parent node from this node's parent list)
-        thisState.removeParentUUID(parentState.getUUID());
-
-        if (orphaned) {
-            // remove this node
-            itemMgr.getItem(id).setRemoved();
+        // remove properties
+        // use temp array to avoid ConcurrentModificationException
+        tmp = new ArrayList(thisState.getPropertyEntries());
+        for (int i = 0; i < tmp.size(); i++) {
+            NodeState.PropertyEntry entry =
+                    (NodeState.PropertyEntry) tmp.get(i);
+            // remove the property entry
+            thisState.removePropertyEntry(entry.getName());
+            // remove property
+            PropertyId propId = new PropertyId(thisState.getUUID(), entry.getName());
+            itemMgr.getItem(propId).setRemoved();
         }
+
+        // finally remove this node
+        thisState.setParentUUID(null);
+        itemMgr.getItem(id).setRemoved();
     }
 
     protected NodeImpl internalAddNode(String relPath, NodeTypeImpl nodeType)
@@ -918,7 +893,6 @@
         // copy state from transient state:
         // parent uuid's
         persistentState.setParentUUID(transientState.getParentUUID());
-        persistentState.setParentUUIDs(transientState.getParentUUIDs());
         // mixin types
         persistentState.setMixinTypeNames(transientState.getMixinTypeNames());
         // id of definition
@@ -1222,7 +1196,7 @@
         try {
             EffectiveNodeType ent = ntReg.getEffectiveNodeType((QName[]) mixinNames.toArray(new QName[mixinNames.size()]));
             return ent.includesNodeType(ntName);
-        } catch (NodeTypeConflictException ntce) {
+        } catch  (NodeTypeConflictException ntce) {
             String msg = "internal error: invalid mixin node type(s)";
             log.debug(msg);
             throw new RepositoryException(msg, ntce);
@@ -3712,7 +3686,7 @@
     /**
      * {@inheritDoc}
      */
-    public Lock lock(boolean isDeep, boolean isSessionScoped)
+        public Lock lock(boolean isDeep, boolean isSessionScoped)
             throws UnsupportedRepositoryOperationException, LockException,
             AccessDeniedException, InvalidItemStateException,
             RepositoryException {

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java Mon Jun 20 08:58:57 2005
@@ -42,7 +42,7 @@
 import javax.jcr.observation.EventListener;
 import javax.security.auth.Subject;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.config.LoginModuleConfig;
 import org.apache.jackrabbit.core.config.PersistenceManagerConfig;
 import org.apache.jackrabbit.core.config.RepositoryConfig;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java Mon Jun 20 08:58:57 2005
@@ -16,10 +16,9 @@
  */
 package org.apache.jackrabbit.core;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.config.AccessManagerConfig;
 import org.apache.jackrabbit.core.config.WorkspaceConfig;
-import org.apache.jackrabbit.core.nodetype.NodeDefId;
 import org.apache.jackrabbit.core.nodetype.NodeDefinitionImpl;
 import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
 import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
@@ -922,11 +921,21 @@
 
         if (srcParentNode.isSame(destParentNode)) {
             // do rename
-            destParentNode.renameChildNodeLink(srcName.getName(), index, targetUUID, destName.getName());
+            destParentNode.renameChildNode(srcName.getName(), index, targetUUID, destName.getName());
         } else {
-            // do move
-            destParentNode.createChildNodeLink(destName.getName(), targetUUID);
-            srcParentNode.removeChildNode(srcName.getName(), index);
+            // do move:
+            // 1. remove child node entry from old parent
+            NodeState srcParentState =
+                    (NodeState) srcParentNode.getOrCreateTransientItemState();
+            srcParentState.removeChildNodeEntry(srcName.getName(), index);
+            // 2. re-parent target node
+            NodeState targetState =
+                    (NodeState) targetNode.getOrCreateTransientItemState();
+            targetState.setParentUUID(destParentNode.internalGetUUID());
+            // 3. add child node entry to new parent
+            NodeState destParentState =
+                    (NodeState) destParentNode.getOrCreateTransientItemState();
+            destParentState.addChildNodeEntry(destName.getName(), targetUUID);
         }
 
         // change definition of target

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ZombieHierarchyManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ZombieHierarchyManager.java?rev=191499&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ZombieHierarchyManager.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ZombieHierarchyManager.java Mon Jun 20 08:58:57 2005
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core;
+
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.ItemStateManager;
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.log4j.Logger;
+
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
+import java.util.Iterator;
+
+/**
+ * <code>HierarchyManager</code> implementation that is also able to
+ * build/resolve paths of those items that have been moved or removed
+ * (i.e. moved to the attic).
+ *
+ * todo make use of path caching
+ */
+public class ZombieHierarchyManager extends HierarchyManagerImpl {
+
+    private static Logger log = Logger.getLogger(ZombieHierarchyManager.class);
+
+    protected ItemStateManager attic;
+
+    public ZombieHierarchyManager(String rootNodeUUID,
+                                 ItemStateManager provider,
+                                 ItemStateManager attic,
+                                 NamespaceResolver nsResolver) {
+        super(rootNodeUUID, provider, nsResolver);
+        this.attic = attic;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Checks attic first.
+     */
+    protected ItemState getItemState(ItemId id)
+            throws NoSuchItemStateException, ItemStateException {
+        // always check attic first
+        if (attic.hasItemState(id)) {
+            return attic.getItemState(id);
+        }
+        // delegate to base class
+        return super.getItemState(id);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Checks attic first.
+     */
+    protected boolean hasItemState(ItemId id) {
+        // always check attic first
+        if (attic.hasItemState(id)) {
+            return true;
+        }
+        // delegate to base class
+        return super.hasItemState(id);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Also allows for removed/renamed parent-child links.
+     */
+    protected void buildPath(Path.PathBuilder builder, ItemState state)
+            throws ItemStateException, RepositoryException {
+
+        // shortcut
+        if (state.getId().equals(rootNodeId)) {
+            builder.addRoot();
+            return;
+        }
+
+        String parentUUID;
+        if (state.hasOverlayedState()) {
+            // use 'old' parent in case item has been removed
+            parentUUID = state.getOverlayedState().getParentUUID();
+        } else {
+            parentUUID = state.getParentUUID();
+        }
+        if (parentUUID == null) {
+            String msg = "failed to build path of " + state.getId() + ": orphaned item";
+            log.debug(msg);
+            throw new ItemNotFoundException(msg);
+        }
+
+        NodeState parent = (NodeState) getItemState(new NodeId(parentUUID));
+        // recursively build path of parent
+        buildPath(builder, parent);
+
+        if (state.isNode()) {
+            NodeState nodeState = (NodeState) state;
+            String uuid = nodeState.getUUID();
+            NodeState.ChildNodeEntry parentEntry = null;
+            // check removed child node entries first
+            Iterator iter = parent.getRemovedChildNodeEntries().iterator();
+            while (iter.hasNext()) {
+                NodeState.ChildNodeEntry entry =
+                        (NodeState.ChildNodeEntry) iter.next();
+                if (entry.getUUID().equals(uuid)) {
+                    parentEntry = entry;
+                    break;
+                }
+            }
+            if (parentEntry == null) {
+                // no removed child node entry found in parent,
+                // check current child node entries
+                parentEntry = parent.getChildNodeEntry(uuid);
+            }
+            if (parentEntry == null) {
+                String msg = "failed to build path of " + state.getId() + ": "
+                        + parent.getUUID() + " has no child entry for "
+                        + uuid;
+                log.debug(msg);
+                throw new ItemNotFoundException(msg);
+            }
+            // add to path
+            if (parentEntry.getIndex() == 1) {
+                builder.addLast(parentEntry.getName());
+            } else {
+                builder.addLast(parentEntry.getName(), parentEntry.getIndex());
+            }
+        } else {
+            PropertyState propState = (PropertyState) state;
+            QName name = propState.getName();
+            // add to path
+            builder.addLast(name);
+        }
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ZombieHierarchyManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java Mon Jun 20 08:58:57 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.jndi;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 
 import javax.naming.Context;
 import javax.naming.Name;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Mon Jun 20 08:58:57 2005
@@ -28,7 +28,7 @@
 import org.apache.jackrabbit.core.observation.SynchronousEventListener;
 import org.apache.jackrabbit.core.observation.EventImpl;
 import org.apache.log4j.Logger;
-import org.apache.commons.collections.SequencedHashMap;
+import org.apache.commons.collections.map.LinkedMap;
 
 import javax.jcr.lock.Lock;
 import javax.jcr.lock.LockException;
@@ -585,7 +585,7 @@
      * operation.
      */
     private Iterator consolidateEvents(EventIterator events) {
-        SequencedHashMap eventMap = new SequencedHashMap();
+        LinkedMap eventMap = new LinkedMap();
 
         while (events.hasNext()) {
             EventImpl event = (EventImpl) events.nextEvent();

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java Mon Jun 20 08:58:57 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.nodetype;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.IllegalNameException;
 import org.apache.jackrabbit.core.NamespaceResolver;
 import org.apache.jackrabbit.core.QName;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java Mon Jun 20 08:58:57 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.nodetype;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.Constants;
 import org.apache.jackrabbit.core.QName;
 import org.apache.jackrabbit.core.value.InternalValue;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java Mon Jun 20 08:58:57 2005
@@ -20,6 +20,8 @@
 import org.apache.jackrabbit.core.ItemId;
 import org.apache.jackrabbit.core.HierarchyManagerImpl;
 import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.ZombieHierarchyManager;
+import org.apache.jackrabbit.core.Path;
 import org.apache.jackrabbit.core.state.ChangeLog;
 import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.ItemState;
@@ -28,6 +30,8 @@
 import org.apache.jackrabbit.core.state.NodeReferences;
 import org.apache.jackrabbit.core.state.NodeReferencesId;
 
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -42,6 +46,8 @@
  */
 class ChangeLogBasedHierarchyMgr extends HierarchyManagerImpl {
 
+    ZombieHierarchyManager zombieHierMgr;
+
     /**
      * Creates a new <code>ChangeLogBasedHierarchyMgr</code> that overlays
      * <code>manager</code> with <code>changes</code> and uses the deleted
@@ -57,8 +63,24 @@
                                NamespaceResolver resolver) {
         super(rootNodeUUID,
                 new ChangeLogItemStateManager(manager, changes),
-                resolver,
-                new AtticItemStateManager(changes));
+                resolver);
+        zombieHierMgr =
+                new ZombieHierarchyManager(rootNodeUUID, provider,
+                        new AtticItemStateManager(changes), resolver);
+    }
+
+    /**
+     * Same as {@link #getPath(ItemId)}} except that the <i>old</i> path is
+     * returned in case of a moved/removed item.
+     *
+     * @param id
+     * @return
+     * @throws ItemNotFoundException
+     * @throws RepositoryException
+     */
+    public Path getZombiePath(ItemId id)
+            throws ItemNotFoundException, RepositoryException {
+        return zombieHierMgr.getPath(id);
     }
 
     /**
@@ -173,7 +195,7 @@
         }
 
         /**
-         * Returns an {@link ItemState} it is found in the deleted map of the
+         * Returns an {@link ItemState} if it is found in the deleted map of the
          * {@link ChangeLog}.
          * @param id the id of the {@link ItemState}.
          * @return the deleted {@link ItemState}.

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java Mon Jun 20 08:58:57 2005
@@ -16,32 +16,30 @@
  */
 package org.apache.jackrabbit.core.observation;
 
-import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
-import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.HierarchyManager;
-import org.apache.jackrabbit.core.Path;
-import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.ItemId;
 import org.apache.jackrabbit.core.MalformedPathException;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.Path;
 import org.apache.jackrabbit.core.QName;
-import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
 import org.apache.jackrabbit.core.state.ChangeLog;
+import org.apache.jackrabbit.core.state.ItemState;
 import org.apache.jackrabbit.core.state.ItemStateException;
 import org.apache.jackrabbit.core.state.ItemStateManager;
-import org.apache.jackrabbit.core.state.ItemState;
-import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.core.state.NoSuchItemStateException;
+import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.log4j.Logger;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.PathNotFoundException;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeManager;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Arrays;
-import java.util.Collection;
 
 /**
  * The <code>EventStateCollection</code> class implements how {@link EventState}
@@ -84,18 +82,21 @@
     /**
      * Creates {@link EventState} instances from <code>ItemState</code>
      * <code>changes</code>.
+     *
      * @param rootNodeUUID the UUID of the root node.
-     * @param changes the changes on <code>ItemState</code>s.
-     * @param provider an <code>ItemStateProvider</code> to provide <code>ItemState</code>
-     * of items that are not contained in the <code>changes</code> collection.
+     * @param changes      the changes on <code>ItemState</code>s.
+     * @param provider     an <code>ItemStateProvider</code> to provide <code>ItemState</code>
+     *                     of items that are not contained in the <code>changes</code> collection.
      * @throws ItemStateException if an error occurs while creating events
-     * states for the item state changes.
+     *                            states for the item state changes.
      */
     public void createEventStates(String rootNodeUUID, ChangeLog changes, ItemStateManager provider) throws ItemStateException {
         // create a hierarchy manager, that is based on the ChangeLog and
         // the ItemStateProvider
         // todo use CachingHierarchyManager ?
-        HierarchyManager hmgr = new ChangeLogBasedHierarchyMgr(rootNodeUUID, provider, changes, session.getNamespaceResolver());
+        ChangeLogBasedHierarchyMgr hmgr =
+                new ChangeLogBasedHierarchyMgr(rootNodeUUID, provider, changes,
+                        session.getNamespaceResolver());
 
         for (Iterator it = changes.modifiedStates(); it.hasNext();) {
             ItemState state = (ItemState) it.next();
@@ -119,102 +120,104 @@
                 // in case 6) only one node state changes. the state of the
                 // parent node.
                 NodeState n = (NodeState) state;
-                if (n.getAddedParentUUIDs().size() > 0 && n.getRemovedParentUUIDs().size() > 0) {
-                    // node moved
-                    // generate node removed & node added event
-                    String oldParentUUID = (String) n.getRemovedParentUUIDs().get(0);
-                    NodeState oldParent;
-                    try {
-                        oldParent = (NodeState) changes.get(new NodeId(oldParentUUID));
-                    } catch (NoSuchItemStateException e) {
-                        // old parent has been deleted, retrieve from
-                        // shared item state manager
-                        oldParent = (NodeState) provider.getItemState(new NodeId(oldParentUUID));
-                    }
 
-                    NodeTypeImpl oldParentNodeType = getNodeType(oldParent, session);
-                    Path newPath = getPath(n.getId(), hmgr);
-                    Path[] allPaths = getAllPaths(n.getId(), hmgr);
-                    List paths = new ArrayList(Arrays.asList(allPaths));
-                    paths.remove(newPath);
-                    if (paths.size() > 0) {
-                        Path removedPath = (Path) paths.get(0);
-                        events.add(EventState.childNodeRemoved(oldParentUUID,
-                                getParent(removedPath),
-                                n.getUUID(),
-                                removedPath.getNameElement(),
-                                oldParentNodeType,
-                                session));
-
-                        String newParentUUID = (String) n.getAddedParentUUIDs().get(0);
-                        NodeState newParent = (NodeState) changes.get(new NodeId(newParentUUID));
-                        NodeTypeImpl newParentNodeType = getNodeType(newParent, session);
-                        events.add(EventState.childNodeAdded(newParentUUID,
-                                getParent(newPath),
-                                n.getUUID(),
-                                newPath.getNameElement(),
-                                newParentNodeType,
-                                session));
-                    } else {
-                        log.error("Unable to calculate old path of moved node");
-                    }
-                } else {
-                    // a moved node always has a modified parent node
-                    NodeState parent = null;
-                    try {
-                        // root node does not have a parent UUID
-                        if (state.getParentUUID() != null) {
-                            parent = (NodeState) changes.get(new NodeId(state.getParentUUID()));
+                if (n.hasOverlayedState()) {
+                    String oldParentUUID = n.getOverlayedState().getParentUUID();
+                    String newParentUUID = n.getParentUUID();
+                    if (newParentUUID != null &&
+                            !oldParentUUID.equals(newParentUUID)) {
+                        // node moved
+                        // generate node removed & node added event
+                        NodeState oldParent;
+                        try {
+                            oldParent = (NodeState) changes.get(new NodeId(oldParentUUID));
+                        } catch (NoSuchItemStateException e) {
+                            // old parent has been deleted, retrieve from
+                            // shared item state manager
+                            oldParent = (NodeState) provider.getItemState(new NodeId(oldParentUUID));
                         }
-                    } catch (NoSuchItemStateException e) {
-                        // should never happen actually. this would mean
-                        // the parent of this modified node is deleted
-                        String msg = "Parent of node " + state.getId() + " is deleted.";
-                        log.error(msg);
-                        throw new ItemStateException(msg, e);
-                    }
-                    if (parent != null) {
-                        // check if node has been renamed
-                        NodeState.ChildNodeEntry moved = null;
-                        for (Iterator removedNodes = parent.getRemovedChildNodeEntries().iterator(); removedNodes.hasNext();) {
-                            NodeState.ChildNodeEntry child = (NodeState.ChildNodeEntry) removedNodes.next();
-                            if (child.getUUID().equals(n.getUUID())) {
-                                // found node re-added with different name
-                                moved = child;
-                            }
-                        }
-                        if (moved != null) {
-                            NodeTypeImpl nodeType = getNodeType(parent, session);
-                            Path newPath = getPath(state.getId(), hmgr);
-                            Path parentPath = getParent(newPath);
-                            Path oldPath;
-                            try {
-                                if (moved.getIndex() == 0) {
-                                    oldPath = Path.create(parentPath, moved.getName(), false);
-                                } else {
-                                    oldPath = Path.create(parentPath, moved.getName(), moved.getIndex(), false);
-                                }
-                            } catch (MalformedPathException e) {
-                                // should never happen actually
-                                String msg = "Malformed path for item: " + state.getId();
-                                log.error(msg);
-                                throw new ItemStateException(msg, e);
-                            }
-                            events.add(EventState.childNodeRemoved(parent.getUUID(),
-                                    parentPath,
+
+                        NodeTypeImpl oldParentNodeType = getNodeType(oldParent, session);
+                        Path newPath = getPath(n.getId(), hmgr);
+                        Path oldPath = getZombiePath(n.getId(), hmgr);
+                        if (!oldPath.equals(newPath)) {
+                            events.add(EventState.childNodeRemoved(oldParentUUID,
+                                    getParent(oldPath),
                                     n.getUUID(),
                                     oldPath.getNameElement(),
-                                    nodeType,
+                                    oldParentNodeType,
                                     session));
-                            events.add(EventState.childNodeAdded(parent.getUUID(),
-                                    parentPath,
+
+                            NodeState newParent = (NodeState) changes.get(new NodeId(newParentUUID));
+                            NodeTypeImpl newParentNodeType = getNodeType(newParent, session);
+                            events.add(EventState.childNodeAdded(newParentUUID,
+                                    getParent(newPath),
                                     n.getUUID(),
                                     newPath.getNameElement(),
-                                    nodeType,
+                                    newParentNodeType,
                                     session));
+                        } else {
+                            log.error("Unable to calculate old path of moved node");
+                        }
+                    } else {
+                        // a moved node always has a modified parent node
+                        NodeState parent = null;
+                        try {
+                            // root node does not have a parent UUID
+                            if (state.getParentUUID() != null) {
+                                parent = (NodeState) changes.get(new NodeId(state.getParentUUID()));
+                            }
+                        } catch (NoSuchItemStateException e) {
+                            // should never happen actually. this would mean
+                            // the parent of this modified node is deleted
+                            String msg = "Parent of node " + state.getId() + " is deleted.";
+                            log.error(msg);
+                            throw new ItemStateException(msg, e);
+                        }
+                        if (parent != null) {
+                            // check if node has been renamed
+                            NodeState.ChildNodeEntry moved = null;
+                            for (Iterator removedNodes = parent.getRemovedChildNodeEntries().iterator(); removedNodes.hasNext();) {
+                                NodeState.ChildNodeEntry child = (NodeState.ChildNodeEntry) removedNodes.next();
+                                if (child.getUUID().equals(n.getUUID())) {
+                                    // found node re-added with different name
+                                    moved = child;
+                                }
+                            }
+                            if (moved != null) {
+                                NodeTypeImpl nodeType = getNodeType(parent, session);
+                                Path newPath = getPath(state.getId(), hmgr);
+                                Path parentPath = getParent(newPath);
+                                Path oldPath;
+                                try {
+                                    if (moved.getIndex() == 0) {
+                                        oldPath = Path.create(parentPath, moved.getName(), false);
+                                    } else {
+                                        oldPath = Path.create(parentPath, moved.getName(), moved.getIndex(), false);
+                                    }
+                                } catch (MalformedPathException e) {
+                                    // should never happen actually
+                                    String msg = "Malformed path for item: " + state.getId();
+                                    log.error(msg);
+                                    throw new ItemStateException(msg, e);
+                                }
+                                events.add(EventState.childNodeRemoved(parent.getUUID(),
+                                        parentPath,
+                                        n.getUUID(),
+                                        oldPath.getNameElement(),
+                                        nodeType,
+                                        session));
+                                events.add(EventState.childNodeAdded(parent.getUUID(),
+                                        parentPath,
+                                        n.getUUID(),
+                                        newPath.getNameElement(),
+                                        nodeType,
+                                        session));
+                            }
                         }
                     }
                 }
+
                 // check if child nodes of modified node state have been reordered
                 List reordered = n.getReorderedChildNodeEntries();
                 NodeTypeImpl nodeType = getNodeType(n, session);
@@ -229,11 +232,10 @@
                         Path.PathElement addedElem = Path.create(name, index).getNameElement();
                         // get removed index
                         NodeState overlayed = (NodeState) n.getOverlayedState();
-                        List removedChild = overlayed.getChildNodeEntries(child.getUUID());
-                        if (removedChild.size() == 0) {
+                        NodeState.ChildNodeEntry entry = overlayed.getChildNodeEntry(child.getUUID());
+                        if (entry == null) {
                             throw new ItemStateException("Unable to retrieve old child index for item: " + child.getUUID());
                         }
-                        NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) removedChild.get(0);
                         int oldIndex = (entry.getIndex() != 1) ? entry.getIndex() : 0;
                         Path.PathElement removedElem = Path.create(name, oldIndex).getNameElement();
 
@@ -304,15 +306,13 @@
                 NodeState n = (NodeState) state;
                 NodeState parent = (NodeState) provider.getItemState(new NodeId(n.getParentUUID()));
                 NodeTypeImpl nodeType = getNodeType(parent, session);
-                Path[] paths = getAllPaths(state.getId(), hmgr);
-                for (int i = 0; i < paths.length; i++) {
-                    events.add(EventState.childNodeRemoved(n.getParentUUID(),
-                            getParent(paths[i]),
-                            n.getUUID(),
-                            paths[i].getNameElement(),
-                            nodeType,
-                            session));
-                }
+                Path path = getZombiePath(state.getId(), hmgr);
+                events.add(EventState.childNodeRemoved(n.getParentUUID(),
+                        getParent(path),
+                        n.getUUID(),
+                        path.getNameElement(),
+                        nodeType,
+                        session));
             } else {
                 // property removed
                 // only create an event if node still exists
@@ -320,16 +320,14 @@
                     NodeState n = (NodeState) changes.get(new NodeId(state.getParentUUID()));
                     // node state exists -> only property removed
                     NodeTypeImpl nodeType = getNodeType(n, session);
-                    Path[] paths = getAllPaths(state.getId(), hmgr);
-                    for (int i = 0; i < paths.length; i++) {
-                        events.add(EventState.propertyRemoved(state.getParentUUID(),
-                                getParent(paths[i]),
-                                paths[i].getNameElement(),
-                                nodeType,
-                                session));
-                    }
+                    Path path = getZombiePath(state.getId(), hmgr);
+                    events.add(EventState.propertyRemoved(state.getParentUUID(),
+                            getParent(path),
+                            path.getNameElement(),
+                            nodeType,
+                            session));
                 } catch (NoSuchItemStateException e) {
-                    // also node removed -> do not create an event
+                    // node removed as well -> do not create an event
                 }
             }
         }
@@ -337,6 +335,7 @@
 
     /**
      * Adds all event states in the given collection to this collection
+     *
      * @param c
      */
     public void addAll(Collection c) {
@@ -369,7 +368,8 @@
     /**
      * Resolves the node type name in <code>node</code> into a {@link NodeType}
      * object using the {@link NodeTypeManager} of <code>session</code>.
-     * @param node the node.
+     *
+     * @param node    the node.
      * @param session the session.
      * @return the {@link NodeType} of <code>node</code>.
      * @throws ItemStateException if the nodetype cannot be resolved.
@@ -389,10 +389,11 @@
 
     /**
      * Returns the path of the parent node of node at <code>path</code>..
+     *
      * @param p the path.
      * @return the parent path.
      * @throws ItemStateException if <code>p</code> does not have a parent
-     * path. E.g. <code>p</code> designates root.
+     *                            path. E.g. <code>p</code> designates root.
      */
     private Path getParent(Path p) throws ItemStateException {
         try {
@@ -407,6 +408,7 @@
 
     /**
      * Resolves the path of the Item with id <code>itemId</code>.
+     *
      * @param itemId the id of the item.
      * @return the path of the item.
      * @throws ItemStateException if the path cannot be resolved.
@@ -424,19 +426,20 @@
     }
 
     /**
-     * Resolves all paths of the Item with id <code>itemId</code> including
-     * the zombie paths.
+     * Resolves the <i>zombie</i> (i.e. the old) path of the Item with id
+     * <code>itemId</code>.
+     *
      * @param itemId the id of the item.
-     * @return the paths of the item.
-     * @throws ItemStateException if the paths cannot be resolved.
+     * @return the path of the item.
+     * @throws ItemStateException if the path cannot be resolved.
      */
-    private Path[] getAllPaths(ItemId itemId, HierarchyManager hmgr)
+    private Path getZombiePath(ItemId itemId, ChangeLogBasedHierarchyMgr hmgr)
             throws ItemStateException {
         try {
-            return hmgr.getAllPaths(itemId, true);
+            return hmgr.getZombiePath(itemId);
         } catch (RepositoryException e) {
             // should never happen actually
-            String msg = "Unable to resolve paths for item: " + itemId;
+            String msg = "Unable to resolve zombie path for item: " + itemId;
             log.error(msg);
             throw new ItemStateException(msg, e);
         }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java Mon Jun 20 08:58:57 2005
@@ -18,7 +18,7 @@
 
 import org.apache.commons.collections.Buffer;
 import org.apache.commons.collections.BufferUtils;
-import org.apache.commons.collections.UnboundedFifoBuffer;
+import org.apache.commons.collections.buffer.UnboundedFifoBuffer;
 import org.apache.log4j.Logger;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.ItemManager;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java Mon Jun 20 08:58:57 2005
@@ -361,14 +361,15 @@
                                 // specified position
                                 if (position == LocationStepQueryNode.LAST) {
                                     // only select last
-                                    List childNodes = state.getChildNodeEntries(uuid);
-                                    if (childNodes.size() == 0) {
+                                    NodeState.ChildNodeEntry entry =
+                                            state.getChildNodeEntry(uuid);
+                                    if (entry == null) {
                                         // no such child node, probably deleted meanwhile
                                         hits.flip(i);
                                     } else {
                                         // only use the last one
-                                        QName name = ((NodeState.ChildNodeEntry) childNodes.get(0)).getName();
-                                        childNodes = state.getChildNodeEntries(name);
+                                        QName name = entry.getName();
+                                        List childNodes = state.getChildNodeEntries(name);
                                         if (childNodes.size() == 0
                                                 || !((NodeState.ChildNodeEntry) childNodes.get(childNodes.size() - 1))
                                                     .getUUID().equals(uuid)) {
@@ -376,16 +377,14 @@
                                         }
                                     }
                                 } else {
-                                    List childNodes = state.getChildNodeEntries(uuid);
-                                    if (childNodes.size() == 0) {
+                                    NodeState.ChildNodeEntry entry =
+                                            state.getChildNodeEntry(uuid);
+                                    if (entry == null) {
                                         // no such child node, probably has been deleted meanwhile
                                         hits.flip(i);
                                     } else {
-                                        for (int j = 0; j < childNodes.size(); j++) {
-                                            NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) childNodes.get(j);
-                                            if (entry.getIndex() != position) {
-                                                hits.flip(i);
-                                            }
+                                        if (entry.getIndex() != position) {
+                                            hits.flip(i);
                                         }
                                     }
                                 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/FileSystemDirectory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/FileSystemDirectory.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/FileSystemDirectory.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/FileSystemDirectory.java Mon Jun 20 08:58:57 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.query.lucene;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.fs.FileSystem;
 import org.apache.jackrabbit.core.fs.FileSystemException;
 import org.apache.jackrabbit.core.fs.FileSystemResource;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java Mon Jun 20 08:58:57 2005
@@ -138,12 +138,9 @@
             } else {
                 doc.add(new Field(FieldNames.PARENT, node.getParentUUID(), true, true, false));
                 NodeState parent = (NodeState) stateProvider.getItemState(new NodeId(node.getParentUUID()));
-                List entries = parent.getChildNodeEntries(node.getUUID());
-                for (Iterator it = entries.iterator(); it.hasNext();) {
-                    NodeState.ChildNodeEntry child = (NodeState.ChildNodeEntry) it.next();
-                    String name = child.getName().toJCRName(mappings);
-                    doc.add(new Field(FieldNames.LABEL, name, false, true, false));
-                }
+                NodeState.ChildNodeEntry child = parent.getChildNodeEntry(node.getUUID());
+                String name = child.getName().toJCRName(mappings);
+                doc.add(new Field(FieldNames.LABEL, name, false, true, false));
             }
         } catch (NoSuchItemStateException e) {
             throw new RepositoryException("Error while indexing node: " + node.getUUID(), e);

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/VolatileIndex.java Mon Jun 20 08:58:57 2005
@@ -22,7 +22,7 @@
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.IndexReader;
 import org.apache.jackrabbit.core.fs.FileSystemException;
-import org.apache.commons.collections.SequencedHashMap;
+import org.apache.commons.collections.map.LinkedMap;
 
 import java.io.IOException;
 import java.util.Map;
@@ -42,7 +42,7 @@
     private final RedoLog redoLog;
 
     /** Map of pending documents to add to the index */
-    private final Map pending = new SequencedHashMap();
+    private final Map pending = new LinkedMap();
 
     /**
      * Number of documents that are buffered before they are added to the index.

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ChangeLog.java Mon Jun 20 08:58:57 2005
@@ -16,11 +16,11 @@
  */
 package org.apache.jackrabbit.core.state;
 
+import org.apache.commons.collections.map.LinkedMap;
 import org.apache.jackrabbit.core.ItemId;
-import org.apache.commons.collections.SequencedHashMap;
 
-import java.util.Map;
 import java.util.Iterator;
+import java.util.Map;
 
 /**
  * Registers changes made to states and references and consolidates
@@ -31,25 +31,26 @@
     /**
      * Added states
      */
-    private final Map addedStates = new SequencedHashMap();
+    private final Map addedStates = new LinkedMap();
 
     /**
      * Modified states
      */
-    private final Map modifiedStates = new SequencedHashMap();
+    private final Map modifiedStates = new LinkedMap();
 
     /**
      * Deleted states
      */
-    private final Map deletedStates = new SequencedHashMap();
+    private final Map deletedStates = new LinkedMap();
 
     /**
      * Modified references
      */
-    private final Map modifiedRefs = new SequencedHashMap();
+    private final Map modifiedRefs = new LinkedMap();
 
     /**
      * A state has been added
+     *
      * @param state state that has been added
      */
     public void added(ItemState state) {
@@ -61,6 +62,7 @@
      * (not in the collection of added ones), then disconnect
      * the local state from its underlying shared state and add
      * it to the modified states collection.
+     *
      * @param state state that has been modified
      */
     public void modified(ItemState state) {
@@ -76,6 +78,7 @@
      * the local state from its underlying shared state, remove
      * it from the modified states collection and add it to the
      * deleted states collection.
+     *
      * @param state state that has been deleted
      */
     public void deleted(ItemState state) {
@@ -88,6 +91,7 @@
 
     /**
      * A references has been modified
+     *
      * @param refs refs that has been modified
      */
     public void modified(NodeReferences refs) {
@@ -99,6 +103,7 @@
      * if the item state is neither in the added nor in the modified
      * section. Throws a <code>NoSuchItemStateException</code> if
      * the item state is in the deleted section.
+     *
      * @return item state or <code>null</code>
      * @throws NoSuchItemStateException if the item has been deleted
      */
@@ -108,8 +113,7 @@
             state = (ItemState) modifiedStates.get(id);
             if (state == null) {
                 if (deletedStates.containsKey(id)) {
-                    throw new NoSuchItemStateException(
-                            "State has been marked destroyed: " + id);
+                    throw new NoSuchItemStateException("State has been marked destroyed: " + id);
                 }
             }
         }
@@ -118,6 +122,7 @@
 
     /**
      * Return a flag indicating whether a given item state exists.
+     *
      * @return <code>true</code> if item state exists within this
      *         log; <code>false</code> otherwise
      */
@@ -132,6 +137,7 @@
      * Return a node references object given its id. Returns
      * <code>null</code> if the node reference is not in the modified
      * section.
+     *
      * @return node references or <code>null</code>
      */
     public NodeReferences get(NodeReferencesId id) {
@@ -140,6 +146,7 @@
 
     /**
      * Return an iterator over all added states.
+     *
      * @return iterator over all added states.
      */
     public Iterator addedStates() {
@@ -148,6 +155,7 @@
 
     /**
      * Return an iterator over all modified states.
+     *
      * @return iterator over all modified states.
      */
     public Iterator modifiedStates() {
@@ -156,6 +164,7 @@
 
     /**
      * Return an iterator over all deleted states.
+     *
      * @return iterator over all deleted states.
      */
     public Iterator deletedStates() {
@@ -164,6 +173,7 @@
 
     /**
      * Return an iterator over all modified references.
+     *
      * @return iterator over all modified references.
      */
     public Iterator modifiedRefs() {
@@ -172,6 +182,7 @@
 
     /**
      * Merge another change log to this change log
+     *
      * @param other other change log
      */
     public void merge(ChangeLog other) {
@@ -272,6 +283,7 @@
      * Undo changes made to items in the change log. Discards
      * added items, refreshes modified and resurrects deleted
      * items.
+     *
      * @param parent parent manager that will hold current data
      */
     public void undo(ItemStateManager parent) {

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemState.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemState.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemState.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemState.java Mon Jun 20 08:58:57 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.state;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.ItemId;
 import org.apache.log4j.Logger;
 

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateCache.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateCache.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateCache.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/ItemStateCache.java Mon Jun 20 08:58:57 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.state;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.ItemId;
 import org.apache.log4j.Logger;
 
@@ -60,9 +60,9 @@
      *
      * @param keyType   the type of reference to use for keys (i.e. the item paths)
      * @param valueType the type of reference to use for values (i.e. the item-datas)
-     * @see org.apache.commons.collections.ReferenceMap#HARD
-     * @see org.apache.commons.collections.ReferenceMap#SOFT
-     * @see org.apache.commons.collections.ReferenceMap#WEAK
+     * @see ReferenceMap#HARD
+     * @see ReferenceMap#SOFT
+     * @see ReferenceMap#WEAK
      */
     protected ItemStateCache(int keyType, int valueType) {
         cache = new ReferenceMap(keyType, valueType);

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java Mon Jun 20 08:58:57 2005
@@ -40,18 +40,7 @@
  */
 public class NodeState extends ItemState {
 
-    static final long serialVersionUID = -1785389681811057946L;
-
-    /**
-     * List of parent UUIDs: there's <i>one</i> entry for every parent although
-     * a parent might have more than one child entries refering to <i>this</i>
-     * node state.
-     * <p/>
-     * Furthermore:
-     * <p/>
-     * <code>parentUUIDs.contains(super.parentUUID) == true</code>
-     */
-    protected List parentUUIDs = new ArrayList();
+    static final long serialVersionUID = -3210487938753054604L;
 
     protected String uuid;
     protected QName nodeTypeName;
@@ -97,9 +86,6 @@
                      int initialStatus, boolean isTransient) {
         super(parentUUID, new NodeId(uuid), initialStatus, isTransient);
 
-        if (parentUUID != null) {
-            parentUUIDs.add(parentUUID);
-        }
         this.nodeTypeName = nodeTypeName;
         this.uuid = uuid;
     }
@@ -116,8 +102,6 @@
         mixinTypeNames.addAll(nodeState.getMixinTypeNames());
         defId = nodeState.getDefinitionId();
         uuid = nodeState.getUUID();
-        parentUUIDs.clear();
-        parentUUIDs.addAll(nodeState.getParentUUIDs());
         propertyEntries.clear();
         propertyEntries.addAll(nodeState.getPropertyEntries());
         childNodeEntries.removeAll();
@@ -191,77 +175,6 @@
     }
 
     /**
-     * Returns the UUIDs of the parent <code>NodeState</code>s or <code>null</code>
-     * if either this item state represents the root node or this item state is
-     * 'free floating', i.e. not attached to the repository's hierarchy.
-     *
-     * @return the UUIDs of the parent <code>NodeState</code>s
-     * @see #addParentUUID
-     * @see #removeParentUUID
-     */
-    public synchronized List getParentUUIDs() {
-        return Collections.unmodifiableList(parentUUIDs);
-    }
-
-    /**
-     * Adds the specified UUID to the list of parent UUIDs of this node state.
-     *
-     * @param uuid the UUID of the parent node
-     * @see #getParentUUIDs
-     * @see #removeParentUUID
-     */
-    public synchronized void addParentUUID(String uuid) {
-        if (parentUUIDs.isEmpty()) {
-            parentUUID = uuid;
-        }
-        parentUUIDs.add(uuid);
-    }
-
-    /**
-     * Removes the specified UUID from the list of parent UUIDs of this node state.
-     *
-     * @param uuid the UUID of the parent node
-     * @return <code>true</code> if the specified UUID was contained in the set
-     *         of parent UUIDs and could be removed.
-     * @see #getParentUUIDs
-     * @see #addParentUUID
-     */
-    public synchronized boolean removeParentUUID(String uuid) {
-        if (parentUUID.equals(uuid)) {
-            parentUUID = null;
-        }
-        boolean removed = parentUUIDs.remove(uuid);
-        if (parentUUID == null) {
-            // change primary parent
-            if (!parentUUIDs.isEmpty()) {
-                parentUUID = (String) parentUUIDs.iterator().next();
-            }
-        }
-        return removed;
-    }
-
-    /**
-     * Removes all parent UUIDs of this node state.
-     */
-    public synchronized void removeAllParentUUIDs() {
-        parentUUIDs.clear();
-        parentUUID = null;
-    }
-
-    /**
-     * Sets the UUIDs of the parent <code>NodeState</code>s.
-     */
-    public synchronized void setParentUUIDs(List uuids) {
-        parentUUIDs.clear();
-        parentUUIDs.addAll(uuids);
-        if (!parentUUIDs.isEmpty()) {
-            parentUUID = (String) parentUUIDs.iterator().next();
-        } else {
-            parentUUID = null;
-        }
-    }
-
-    /**
      * Determines if there is a <code>ChildNodeEntry</code> with the
      * specified <code>name</code>.
      *
@@ -365,28 +278,29 @@
     }
 
     /**
-     * Returns a list of <code>ChildNodeEntry</code> objects denoting the
-     * child nodes of this node.
+     * Returns the <code>ChildNodeEntry</code> with the specified uuid or
+     * <code>null</code> if there's no such entry.
      *
-     * @return list of <code>ChildNodeEntry</code> objects
+     * @param uuid UUID of a child node state.
+     * @return the <code>ChildNodeEntry</code> with the specified uuid or
+     *         <code>null</code> if there's no such entry.
      * @see #addChildNodeEntry
      * @see #removeChildNodeEntry
      */
-    public synchronized List getChildNodeEntries() {
-        return childNodeEntries.entries();
+    public synchronized ChildNodeEntry getChildNodeEntry(String uuid) {
+        return childNodeEntries.get(uuid);
     }
 
     /**
      * Returns a list of <code>ChildNodeEntry</code> objects denoting the
-     * child nodes of this node that refer to the specified UUID.
+     * child nodes of this node.
      *
-     * @param uuid UUID of a child node state.
      * @return list of <code>ChildNodeEntry</code> objects
      * @see #addChildNodeEntry
      * @see #removeChildNodeEntry
      */
-    public synchronized List getChildNodeEntries(String uuid) {
-        return childNodeEntries.get(uuid);
+    public synchronized List getChildNodeEntries() {
+        return childNodeEntries.entries();
     }
 
     /**
@@ -402,24 +316,25 @@
     }
 
     /**
-     * Adds a new <code>ChildNodeEntry<code>.
+     * Adds a new <code>ChildNodeEntry</code>.
      *
-     * @param nodeName <code>QName<code> object specifying the name of the new entry.
+     * @param nodeName <code>QName</code> object specifying the name of the new entry.
      * @param uuid     UUID the new entry is refering to.
-     * @return the newly added <code>ChildNodeEntry<code>
+     * @return the newly added <code>ChildNodeEntry</code>
      */
-    public synchronized ChildNodeEntry addChildNodeEntry(QName nodeName, String uuid) {
+    public synchronized ChildNodeEntry addChildNodeEntry(QName nodeName,
+                                                         String uuid) {
         ChildNodeEntry entry = childNodeEntries.add(nodeName, uuid);
         notifyNodeAdded(entry);
         return entry;
     }
 
     /**
-     * Renames a new <code>ChildNodeEntry<code>.
+     * Renames a new <code>ChildNodeEntry</code>.
      *
-     * @param oldName <code>QName<code> object specifying the entry's old name
+     * @param oldName <code>QName</code> object specifying the entry's old name
      * @param index 1-based index if there are same-name child node entries
-     * @param newName <code>QName<code> object specifying the entry's new name
+     * @param newName <code>QName</code> object specifying the entry's new name
      * @return <code>true</code> if the entry was sucessfully renamed;
      *         otherwise <code>false</code>
      */
@@ -427,7 +342,8 @@
                                                      QName newName) {
         ChildNodeEntry oldEntry = childNodeEntries.remove(oldName, index);
         if (oldEntry != null) {
-            ChildNodeEntry newEntry = addChildNodeEntry(newName, oldEntry.getUUID());
+            ChildNodeEntry newEntry =
+                    addChildNodeEntry(newName, oldEntry.getUUID());
             notifyNodeAdded(newEntry);
             notifyNodeRemoved(oldEntry);
             return true;
@@ -452,10 +368,29 @@
     }
 
     /**
-     * Removes all <code>ChildNodeEntry<code>s.
+     * Removes a <code>ChildNodeEntry</code>.
+     *
+     * @param uuid UUID of the entry to be removed
+     * @return <code>true</code> if the specified child node entry was found
+     *         in the list of child node entries and could be removed.
+     */
+    public synchronized boolean removeChildNodeEntry(String uuid) {
+        ChildNodeEntry entry = childNodeEntries.remove(uuid);
+        if (entry != null) {
+            notifyNodeRemoved(entry);
+        }
+        return entry != null;
+    }
+
+    /**
+     * Removes all <code>ChildNodeEntry</code>s.
      */
     public synchronized void removeAllChildNodeEntries() {
-        childNodeEntries.removeAll();
+        Iterator iter = childNodeEntries.entries().iterator();
+        while (iter.hasNext()) {
+            ChildNodeEntry entry = (ChildNodeEntry) iter.next();
+            removeChildNodeEntry(entry.getUUID());
+        }
     }
 
     /**
@@ -481,9 +416,9 @@
     }
 
     /**
-     * Adds a <code>PropertyEntry<code>.
+     * Adds a <code>PropertyEntry</code>.
      *
-     * @param propName <code>QName<code> object specifying the property name
+     * @param propName <code>QName</code> object specifying the property name
      */
     public synchronized void addPropertyEntry(QName propName) {
         PropertyEntry entry = new PropertyEntry(propName);
@@ -491,9 +426,9 @@
     }
 
     /**
-     * Removes a <code>PropertyEntry<code>.
+     * Removes a <code>PropertyEntry</code>.
      *
-     * @param propName <code>QName<code> object specifying the property name
+     * @param propName <code>QName</code> object specifying the property name
      * @return <code>true</code> if the specified property entry was found
      *         in the list of property entries and could be removed.
      */
@@ -509,7 +444,7 @@
     }
 
     /**
-     * Removes all <code>PropertyEntry<code>s.
+     * Removes all <code>PropertyEntry</code>s.
      */
     public synchronized void removeAllPropertyEntries() {
         propertyEntries.clear();
@@ -536,23 +471,6 @@
 
     //---------------------------------------------------------< diff methods >
     /**
-     * Returns a list of parent UUID's, that do not exist in the overlayed node
-     * state but have been added to <i>this</i> node state.
-     *
-     * @return list of added parent UUID's
-     */
-    public synchronized List getAddedParentUUIDs() {
-        if (!hasOverlayedState()) {
-            return Collections.EMPTY_LIST;
-        }
-
-        NodeState other = (NodeState) getOverlayedState();
-        ArrayList list = new ArrayList(parentUUIDs);
-        list.removeAll(other.parentUUIDs);
-        return list;
-    }
-
-    /**
      * Returns a list of property entries, that do not exist in the overlayed
      * node state but have been added to <i>this</i> node state.
      *
@@ -585,23 +503,6 @@
     }
 
     /**
-     * Returns a list of parent UUID's, that exist in the overlayed node state
-     * but have been removed from <i>this</i> node state.
-     *
-     * @return list of removed parent UUID's
-     */
-    public synchronized List getRemovedParentUUIDs() {
-        if (!hasOverlayedState()) {
-            return Collections.EMPTY_LIST;
-        }
-
-        NodeState other = (NodeState) getOverlayedState();
-        ArrayList list = new ArrayList(other.parentUUIDs);
-        list.removeAll(parentUUIDs);
-        return list;
-    }
-
-    /**
      * Returns a list of property entries, that exist in the overlayed node state
      * but have been removed from <i>this</i> node state.
      *
@@ -634,7 +535,7 @@
     }
 
     /**
-     * Returns a list of child node entries, that exist both in <i>this</i> node
+     * Returns a list of child node entries that exist both in <i>this</i> node
      * state and in the overlayed node state, but have been reordered.
      * <p/>
      * The list may include only the minimal set of nodes that have been
@@ -737,23 +638,7 @@
 
     //--------------------------------------------------< ItemState overrides >
     /**
-     * Sets the UUID of the parent <code>NodeState</code>.
-     *
-     * @param parentUUID the parent <code>NodeState</code>'s UUID or
-     *                   <code>null</code> if either this item state should
-     *                   represent the root node or this item state should
-     *                   be 'free floating', i.e. detached from the repository's
-     *                   hierarchy.
-     */
-    public synchronized void setParentUUID(String parentUUID) {
-        if (parentUUID != null && !parentUUIDs.contains(parentUUID)) {
-            parentUUIDs.add(parentUUID);
-        }
-        this.parentUUID = parentUUID;
-    }
-
-    /**
-     * @see ItemState#addListener
+     * {@inheritDoc}
      *
      * If the listener passed is at the same time a <code>NodeStateListener</code>
      * we add it to our list of specialized listeners.
@@ -770,7 +655,7 @@
     }
 
     /**
-     * @see ItemState#removeListener
+     * {@inheritDoc}
      *
      * If the listener passed is at the same time a <code>NodeStateListener</code>
      * we remove it from our list of specialized listeners.
@@ -784,6 +669,7 @@
         super.removeListener(listener);
     }
 
+    //-------------------------------------------------< misc. helper methods >
     /**
      * Notify the listeners that some child node was added
      */
@@ -891,8 +777,8 @@
             entries.clear();
         }
 
-        public boolean remove(ChildNodeEntry entry) {
-            return remove(entry.getName(), entry.getIndex()) != null;
+        public ChildNodeEntry remove(ChildNodeEntry entry) {
+            return remove(entry.getName(), entry.getIndex());
         }
 
         public ChildNodeEntry remove(QName nodeName, int index) {
@@ -939,35 +825,26 @@
             }
         }
 
-        boolean remove(QName nodeName, String uuid) {
-            List siblings = (List) names.get(nodeName);
-            if (siblings == null || siblings.isEmpty()) {
-                return false;
-            }
-
-            Iterator iter = siblings.iterator();
+        ChildNodeEntry remove(String uuid) {
+            Iterator iter = entries.iterator();
             while (iter.hasNext()) {
                 ChildNodeEntry entry = (ChildNodeEntry) iter.next();
                 if (entry.getUUID().equals(uuid)) {
                     return remove(entry);
                 }
             }
-            return false;
+            return null;
         }
 
-        List get(String uuid) {
-            if (entries.isEmpty()) {
-                return Collections.EMPTY_LIST;
-            }
-            ArrayList list = new ArrayList();
+        ChildNodeEntry get(String uuid) {
             Iterator iter = entries.iterator();
             while (iter.hasNext()) {
                 ChildNodeEntry entry = (ChildNodeEntry) iter.next();
                 if (entry.getUUID().equals(uuid)) {
-                    list.add(entry);
+                    return entry;
                 }
             }
-            return Collections.unmodifiableList(list);
+            return null;
         }
 
         Iterator iterator() {

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java Mon Jun 20 08:58:57 2005
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.core.state;
 
 import org.apache.jackrabbit.core.CachingHierarchyManager;
-import org.apache.jackrabbit.core.Constants;
 import org.apache.jackrabbit.core.HierarchyManager;
 import org.apache.jackrabbit.core.ItemId;
 import org.apache.jackrabbit.core.MalformedPathException;
@@ -25,6 +24,7 @@
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.Path;
 import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.ZombieHierarchyManager;
 import org.apache.log4j.Logger;
 
 import javax.jcr.InvalidItemStateException;
@@ -34,7 +34,6 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
-import java.util.Random;
 import java.util.TreeMap;
 
 /**
@@ -80,18 +79,7 @@
         // create transient item state manager
         transientStateMgr = new TransientItemStateManager();
         // create hierarchy manager that uses both transient and persistent state
-        hierMgr = new CachingHierarchyManager(rootNodeUUID, this,
-                nsResolver, transientStateMgr.getAttic());
-    }
-
-    /**
-     * En-/Disable chaching of path values.
-     * <p/>
-     * Paths are always cached, therefore this method has no implementation.
-     * @param enable <code>true</code> to enable caching;
-     *               <code>false</code> to disable
-     */
-    public void enablePathCaching(boolean enable) {
+        hierMgr = new CachingHierarchyManager(rootNodeUUID, this, nsResolver);
     }
 
     /**
@@ -322,7 +310,6 @@
      */
     public Iterator getDescendantTransientItemStates(NodeId parentId)
             throws InvalidItemStateException, RepositoryException {
-        // @todo need a more efficient way to find descendents in cache (e.g. using hierarchical index)
         if (!transientStateMgr.hasAnyItemStates()) {
             return Collections.EMPTY_LIST.iterator();
         }
@@ -360,9 +347,9 @@
             return descendants.values().iterator();
         }
 
-        Path[] parentPaths;
+        Path parentPath;
         try {
-            parentPaths = hierMgr.getAllPaths(parentId);
+            parentPath = hierMgr.getPath(parentId);
         } catch (ItemNotFoundException infe) {
             String msg = parentId + ": the item has been removed externally.";
             log.debug(msg);
@@ -378,9 +365,9 @@
             while (iter.hasNext()) {
                 ItemState state = (ItemState) iter.next();
                 ItemId id = state.getId();
-                Path[] paths;
+                Path path;
                 try {
-                    paths = hierMgr.getAllPaths(id);
+                    path = hierMgr.getPath(id);
                 } catch (ItemNotFoundException infe) {
                     /**
                      * one of the parents of the specified item has been
@@ -398,94 +385,11 @@
                     log.debug(msg);
                     throw new InvalidItemStateException(msg);
                 }
-                boolean isDescendant = false;
-                /**
-                 * check if any of the paths to the transient state
-                 * is a descendant of any of the specified parentId's paths
-                 */
-                for (int i = 0; i < paths.length; i++) {
-                    Path p0 = paths[i]; // path to transient state
-                    // walk through array of the specified parentId's paths
-                    for (int j = 0; j < parentPaths.length; j++) {
-                        Path p1 = parentPaths[j]; // path to specified parentId
-                        if (p0.isDescendantOf(p1)) {
-                            // this is a descendant, add it to the list and
-                            // continue with next transient state
-                            descendants.put(p0, state);
-                            isDescendant = true;
-                            break;
-                        }
-                    }
-                    if (isDescendant) {
-                        break;
-                    }
-                }
-                if (!isDescendant && id.denotesNode()) {
-                    /**
-                     * finally check if transient state has been unlinked
-                     * from a parent node (but is not orphaned yet, i.e. is
-                     * still linked to at least one other parent node);
-                     * if that's the case, check if that parent is a
-                     * descendant of/identical with any of the specified
-                     * parentId's paths.
-                     */
-                    NodeState nodeState = (NodeState) state;
-                    Iterator iterUUIDs = nodeState.getRemovedParentUUIDs().iterator();
-                    while (iterUUIDs.hasNext()) {
-                        /**
-                         * check if any of the paths to the removed parent
-                         * is a descendant of/identical with any of the
-                         * specified parentId's paths.
-                         */
-                        String uuid = (String) iterUUIDs.next();
-                        Path[] pa;
-                        try {
-                            pa = hierMgr.getAllPaths(new NodeId(uuid));
-                        } catch (ItemNotFoundException infe) {
-                            /**
-                             * one of the parents of the specified item has been
-                             * removed externally; as we don't know its path,
-                             * we can't determine if it is a descendant;
-                             * ItemNotFoundException should only be thrown if
-                             * a descendant is affected;
-                             * => log warning and ignore for now
-                             * todo FIXME
-                             */
-                            log.warn(id + ": inconsistent hierarchy state", infe);
-                            continue;
-                        }
-
-                        for (int k = 0; k < pa.length; k++) {
-                            Path p0 = pa[k];   // path to removed parent
-                            // walk through array of the specified parentId's paths
-                            for (int j = 0; j < parentPaths.length; j++) {
-                                Path p1 = parentPaths[j]; // path to specified parentId
-                                if (p0.equals(p1) || p0.isDescendantOf(p1)) {
-                                    // this is a descendant, add it to the list and
-                                    // continue with next transient state
-
-                                    /**
-                                     * FIXME need to create dummy path by
-                                     * appending a random integer in order to
-                                     * avoid potential conflicts
-                                     */
-                                    QName dummyName = new QName(Constants.NS_DEFAULT_URI, Integer.toString(new Random().nextInt()));
-                                    Path dummy = Path.create(p0, Path.create(dummyName, 0), true);
-                                    descendants.put(dummy, state);
-                                    isDescendant = true;
-                                    break;
-                                }
-                            }
-                            if (isDescendant) {
-                                break;
-                            }
-                        }
-                        if (isDescendant) {
-                            break;
-                        }
-                    }
+
+                if (path.isDescendantOf(parentPath)) {
+                    // this is a descendant, add it to the list
+                    descendants.put(path, state);
                 }
-                // continue with next transient state
             }
         } catch (MalformedPathException mpe) {
             String msg = "inconsistent hierarchy state";
@@ -505,15 +409,22 @@
      * @return an iterator over descendant transient item state instances in the attic
      */
     public Iterator getDescendantTransientItemStatesInAttic(NodeId parentId) {
-        // @todo need a more efficient way to find descendents in attic (e.g. using hierarchical index)
         if (!transientStateMgr.hasAnyItemStatesInAttic()) {
             return Collections.EMPTY_LIST.iterator();
         }
         // collection of descendant transient states in attic:
         // the path serves as key and sort criteria
+
+        // we have to use a special attic-aware hierarchy manager
+        ZombieHierarchyManager zombieHierMgr =
+                new ZombieHierarchyManager(hierMgr.getRootNodeId().getUUID(),
+                        this,
+                        transientStateMgr.getAttic(),
+                        hierMgr.getNamespaceResolver());
+
         TreeMap descendants = new TreeMap(new PathComparator());
         try {
-            Path[] parentPaths = hierMgr.getAllPaths(parentId, true);
+            Path parentPath = zombieHierMgr.getPath(parentId);
             /**
              * walk through list of transient states in attic and check if
              * they are descendants of the specified parent
@@ -522,28 +433,10 @@
             while (iter.hasNext()) {
                 ItemState state = (ItemState) iter.next();
                 ItemId id = state.getId();
-                Path[] paths = hierMgr.getAllPaths(id, true);
-                boolean isDescendant = false;
-                /**
-                 * check if any of the paths to the transient state
-                 * is a descendant of any of the specified parentId's paths
-                 */
-                for (int i = 0; i < paths.length; i++) {
-                    Path p0 = paths[i]; // path to transient state in attic
-                    // walk through array of the specified parentId's paths
-                    for (int j = 0; j < parentPaths.length; j++) {
-                        Path p1 = parentPaths[j]; // path to specified parentId
-                        if (p0.isDescendantOf(p1)) {
-                            // this is a descendant, add it to the list and
-                            // continue with next transient state
-                            descendants.put(p0, state);
-                            isDescendant = true;
-                            break;
-                        }
-                    }
-                    if (isDescendant) {
-                        break;
-                    }
+                Path path = zombieHierMgr.getPath(id);
+                if (path.isDescendantOf(parentPath)) {
+                    // this is a descendant, add it to the list
+                    descendants.put(path, state);
                 }
                 // continue with next transient state
             }
@@ -579,8 +472,7 @@
     public NodeState createTransientNodeState(NodeState overlayedState, int initialStatus)
             throws ItemStateException {
 
-        NodeState state = transientStateMgr.createNodeState(
-                overlayedState, initialStatus);
+        NodeState state = transientStateMgr.createNodeState(overlayedState, initialStatus);
         hierMgr.stateOverlaid(state);
         return state;
     }
@@ -606,8 +498,7 @@
     public PropertyState createTransientPropertyState(PropertyState overlayedState, int initialStatus)
             throws ItemStateException {
 
-        PropertyState state = transientStateMgr.createPropertyState(
-                overlayedState, initialStatus);
+        PropertyState state = transientStateMgr.createPropertyState(overlayedState, initialStatus);
         hierMgr.stateOverlaid(state);
         return state;
     }
@@ -615,6 +506,7 @@
     /**
      * Disconnect a transient item state from its underlying persistent state.
      * Notifies the <code>HierarchyManager</code> about the changed identity.
+     *
      * @param state the transient <code>ItemState</code> instance that should
      *              be disconnected
      */

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java?rev=191499&r1=191498&r2=191499&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/TransientItemStateManager.java Mon Jun 20 08:58:57 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.state;
 
-import org.apache.commons.collections.ReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.core.ItemId;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.PropertyId;



Mime
View raw message