jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r518930 - in /jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: hierarchy/ state/
Date Fri, 16 Mar 2007 10:36:13 GMT
Author: angela
Date: Fri Mar 16 03:36:11 2007
New Revision: 518930

URL: http://svn.apache.org/viewvc?view=rev&rev=518930
Log:
- invalidating a NodeEntry must also invalidate the ChildNodeEntries collection in order to
get informed about reordering of the entries.

- comparing ItemInfo.getPath to HierarchyEntry.getPath must use the 'workspace' path of the
latter and not the current path present in the transient space, which differs in case of a
moved item.

Modified:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.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/NodeState.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java?view=diff&rev=518930&r1=518929&r2=518930
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java
Fri Mar 16 03:36:11 2007
@@ -21,6 +21,7 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
+import org.apache.jackrabbit.spi.ChildInfo;
 import org.apache.commons.collections.list.AbstractLinkedList;
 import org.apache.commons.collections.iterators.UnmodifiableIterator;
 
@@ -47,7 +48,11 @@
 
     private static Logger log = LoggerFactory.getLogger(ChildNodeEntries.class);
 
+    static final int STATUS_OK = 0;
+    static final int STATUS_INVALIDATED = 1;
+
     private final NodeEntryImpl parent;
+    private int status = STATUS_OK;
 
     /**
      * Linked list of {@link NodeEntry} instances.
@@ -71,6 +76,21 @@
     }
 
     /**
+     * Mark <code>ChildNodeEntries</code> in order to force
+     */
+    void setStatus(int status) {
+        if (status == STATUS_INVALIDATED || status == STATUS_OK) {
+            this.status = status;
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    int getStatus() {
+        return status;
+    }
+
+    /**
      * Returns true, if this ChildNodeEntries contains a entry that matches
      * the given name and either index or uniqueID:<br>
      * If <code>uniqueID</code> is not <code>null</code> the given
index is
@@ -211,7 +231,6 @@
         if (index < Path.INDEX_DEFAULT) {
             throw new IllegalArgumentException("index is 1-based");
         }
-
         Object obj = nameMap.get(nodeName);
         if (obj == null) {
             return null;
@@ -219,32 +238,7 @@
         if (obj instanceof List) {
             // map entry is a list of siblings
             List siblings = (List) obj;
-            // shortcut if index can never match
-            if (index > siblings.size()) {
-                return null;
-            }
-            // filter out removed states
-            for (Iterator it = siblings.iterator(); it.hasNext(); ) {
-                NodeEntry cne = ((LinkedEntries.LinkNode) it.next()).getNodeEntry();
-                if (cne.isAvailable()) {
-                    try {
-                        if (cne.getNodeState().isValid()) {
-                            index--;
-                        } else {
-                            // child node removed
-                        }
-                    } catch (ItemStateException e) {
-                        // should never happen, cne.isAvailable() returned true
-                    }
-                } else {
-                    // then this child node entry has never been accessed
-                    // before and is assumed valid // TODO: check if correct.
-                    index--;
-                }
-                if (index == 0) {
-                    return cne;
-                }
-            }
+            return findMatchingEntry(siblings, index, true);
         } else {
             // map entry is a single child node entry
             if (index == Path.INDEX_DEFAULT) {
@@ -276,6 +270,69 @@
     }
 
     /**
+     * Find the matching NodeEntry for the given <code>ChildInfo</code>. Returns
+     * <code>null</code> if no matching entry can be found. NOTE, that no check
+     * for validity of the entries is made.
+     *
+     * @param childInfo
+     * @return
+     */
+    NodeEntry get(ChildInfo childInfo) {
+        String uniqueID = childInfo.getUniqueID();
+        if (uniqueID != null) {
+            return get(childInfo.getName(), uniqueID);
+        } else {
+            int index = childInfo.getIndex();
+            Object obj = nameMap.get(childInfo.getName());
+            if (obj == null) {
+                return null;
+            } else if (obj instanceof List) {
+                // map entry is a list of siblings
+                List siblings = (List) obj;
+                return findMatchingEntry(siblings, index, false);
+            } else if (index == Path.INDEX_DEFAULT) {
+                // map entry is a single child node entry
+                return ((LinkedEntries.LinkNode) obj).getNodeEntry();
+            } // else return 'null'
+        }
+        return null;
+    }
+
+    private static NodeEntry findMatchingEntry(List siblings, int index, boolean checkValidity)
{
+        // shortcut if index can never match
+        if (index > siblings.size()) {
+            return null;
+        }
+        if (!checkValidity) {
+            return ((LinkedEntries.LinkNode) siblings.get(index - 1)).getNodeEntry();
+        } else {
+            // filter out removed states
+            for (Iterator it = siblings.iterator(); it.hasNext(); ) {
+                NodeEntry cne = ((LinkedEntries.LinkNode) it.next()).getNodeEntry();
+                if (cne.isAvailable()) {
+                    try {
+                        if (cne.getNodeState().isValid()) {
+                            index--;
+                        } else {
+                            // child node removed
+                        }
+                    } catch (ItemStateException e) {
+                        // should never happen, cne.isAvailable() returned true
+                    }
+                } else {
+                    // then this child node entry has never been accessed
+                    // before and is assumed valid // TODO: check if correct.
+                    index--;
+                }
+                if (index == 0) {
+                    return cne;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Adds a <code>NodeEntry</code> to the end of the list. Same as
      * {@link #add(NodeEntry, int)}, where the index is {@link Path#INDEX_UNDEFINED}.
      *
@@ -346,6 +403,23 @@
         }
     }
 
+    void add(NodeEntry entry, NodeEntry beforeEntry) {
+        if (beforeEntry != null) {
+            // the link node where the new entry is ordered before
+            LinkedEntries.LinkNode beforeLN = getLinkNode(beforeEntry);
+            if (beforeLN == null) {
+                throw new NoSuchElementException();
+            }
+            add(entry);
+            Object insertObj = nameMap.get(entry.getQName());
+            LinkedEntries.LinkNode insertLN = getLinkNode(entry);
+            reorder(insertObj, insertLN, beforeLN);
+        } else {
+            // 'before' is null -> simply append new entry at the end
+            add(entry);
+        }
+    }
+
     /**
      * Removes the child node entry with the given <code>nodeName</code> and
      * <code>index</code>.
@@ -411,18 +485,15 @@
      * @return the removed entry or <code>null</code> if there is no such entry.
      */
     NodeEntry remove(NodeEntry childEntry) {
-        NodeEntry entry = null;
-        for (Iterator it = get(childEntry.getQName()).iterator(); it.hasNext(); ) {
-            NodeEntry tmp = (NodeEntry) it.next();
+        List l = get(childEntry.getQName());
+        for (int i = 0; i < l.size(); i++) {
+            NodeEntry tmp = (NodeEntry) l.get(i);
             if (tmp == childEntry) {
-                entry = tmp;
-                break;
+                int index = i+1; // index is 1-based
+                return remove(childEntry.getQName(), index);
             }
         }
-        if (entry != null) {
-            return remove(entry.getQName(), entry.getIndex());
-        }
-        return entry;
+        return null;
     }
 
     /**
@@ -453,7 +524,9 @@
         }
 
         NodeEntry previousBefore = insertLN.getNextLinkNode().getNodeEntry();
-        reorder(insertObj, insertLN, beforeLN);
+        if (previousBefore != beforeNode) {
+            reorder(insertObj, insertLN, beforeLN);
+        }
         return previousBefore;
     }
 
@@ -503,9 +576,7 @@
      *
      * @param nodeEntry the <code>NodeEntry</code> that is compared to the
      * resolution of any <code>NodeEntry</code> that matches by name.
-     * @return the matching <code>LinkNode</code>.
-     * @throws NoSuchElementException if none of the <code>LinkNode</code>s
-     * matches.
+     * @return the matching <code>LinkNode</code> or <code>null</code>
      */
     private LinkedEntries.LinkNode getLinkNode(NodeEntry nodeEntry) {
         Object listOrLinkNode = nameMap.get(nodeEntry.getQName());
@@ -519,15 +590,14 @@
             for (Iterator it = ((List) listOrLinkNode).iterator(); it.hasNext();) {
                 LinkedEntries.LinkNode n = (LinkedEntries.LinkNode) it.next();
                 NodeEntry cne = n.getNodeEntry();
-                // only check available child node entries
-                if (cne.isAvailable() && cne == nodeEntry) {
+                if (cne == nodeEntry) {
                     return n;
                 }
             }
         } else {
             // single child node with this name
             NodeEntry cne = ((LinkedEntries.LinkNode) listOrLinkNode).getNodeEntry();
-            if (cne.isAvailable() && cne == nodeEntry) {
+            if (cne == nodeEntry) {
                 return (LinkedEntries.LinkNode) listOrLinkNode;
             }
         }

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=518930&r1=518929&r2=518930
==============================================================================
--- 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
Fri Mar 16 03:36:11 2007
@@ -50,6 +50,13 @@
     public Path getPath() throws RepositoryException;
 
     /**
+     * @return If this entry has not been modified this method returns the same
+     * as {@link #getPath()}. In case of moved items this method return the
+     * original path as it is present on the persistent layer.
+     */
+    public Path getWorkspacePath() throws RepositoryException;
+
+    /**
      * Returns the <code>NodeEntry</code> being parent to this
      * <code>HierarchyEntry</code>.
      *

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=518930&r1=518929&r2=518930
==============================================================================
--- 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
Fri Mar 16 03:36:11 2007
@@ -18,7 +18,6 @@
 
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
-import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.NoSuchItemStateException;
@@ -94,8 +93,13 @@
         ItemState state = internalGetItemState();
         // not yet resolved. retrieve and keep weak reference to state
         if (state == null) {
-            state = doResolve();
-            target = new WeakReference(state);
+            try {
+                state = doResolve();
+                target = new WeakReference(state);
+            } catch (NoSuchItemStateException e) {
+                remove();
+                throw e;
+            }
         } else if (state.getStatus() == Status.INVALIDATED) {
             // completely reload this entry, but don't reload recursively
             reload(false, false);
@@ -115,6 +119,15 @@
     abstract ItemState doResolve() throws NoSuchItemStateException, ItemStateException;
 
     /**
+     * Build the Path of this entry
+     *
+     * @param workspacePath
+     * @return
+     * @throws RepositoryException
+     */
+    abstract Path buildPath(boolean workspacePath) throws RepositoryException;
+
+    /**
      * 
      * @return
      */
@@ -161,53 +174,15 @@
      * @see HierarchyEntry#getPath()
      */
     public Path getPath() throws RepositoryException {
-        // shortcut for root state
-        if (parent == null) {
-            return Path.ROOT;
-        }
-
-        // build path otherwise
-        try {
-            Path.PathBuilder builder = new Path.PathBuilder();
-            buildPath(builder, this);
-            return builder.getPath();
-        } catch (MalformedPathException e) {
-            String msg = "Failed to build path of " + this;
-            throw new RepositoryException(msg, e);
-        }
+        return buildPath(false);
     }
 
     /**
-     * Adds the path element of an item id to the path currently being built.
-     * On exit, <code>builder</code> contains the path of <code>state</code>.
-     *
-     * @param builder builder currently being used
-     * @param hEntry HierarchyEntry of the state the path should be built for.
+     * @inheritDoc
+     * @see HierarchyEntry#getWorkspacePath()
      */
-    private void buildPath(Path.PathBuilder builder, HierarchyEntry hEntry) {
-        NodeEntry parentEntry = hEntry.getParent();
-        // shortcut for root state
-        if (parentEntry == null) {
-            builder.addRoot();
-            return;
-        }
-
-        // recursively build path of parent
-        buildPath(builder, parentEntry);
-
-        QName name = hEntry.getQName();
-        if (hEntry.denotesNode()) {
-            int index = ((NodeEntry) hEntry).getIndex();
-            // add to path
-            if (index == Path.INDEX_DEFAULT) {
-                builder.addLast(name);
-            } else {
-                builder.addLast(name, index);
-            }
-        } else {
-            // property-state: add to path
-            builder.addLast(name);
-        }
+    public Path getWorkspacePath() throws RepositoryException {
+        return buildPath(true);
     }
 
     /**

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=518930&r1=518929&r2=518930
==============================================================================
--- 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
Fri Mar 16 03:36:11 2007
@@ -44,6 +44,7 @@
 import javax.jcr.ItemExistsException;
 import javax.jcr.RepositoryException;
 import javax.jcr.PathNotFoundException;
+import javax.jcr.ItemNotFoundException;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ArrayList;
@@ -153,6 +154,10 @@
                 ce.invalidate(recursive);
             }
         }
+        // invalidate 'childNodeEntries'
+        if (getStatus() != Status.NEW && childNodeEntries != null) {
+            childNodeEntries.setStatus(ChildNodeEntries.STATUS_INVALIDATED);
+        }
         // ... and invalidate the resolved state (if available)
         super.invalidate(recursive);
     }
@@ -232,7 +237,13 @@
                 state.getWorkspaceState().setStatus(Status.REMOVED);
             }
         }
-        parent.childNodeEntries().remove(this);
+        if (parent.childNodeEntries != null) {
+            NodeEntry removed = parent.childNodeEntries.remove(this);
+            if (removed == null) {
+                // try attic
+                parent.childNodeAttic.remove(this);
+            }
+        }
 
         // now traverse all child-entries and mark the attached states removed
         // without removing the child-entries themselves. this is not required
@@ -296,13 +307,9 @@
         if (uniqueID != null || parent == null) {
             // uniqueID and root-node -> internal id is always the same as getId().
             return getId();
-        } else if (revertInfo != null) {
-            NodeId parentId = revertInfo.oldParent.getWorkspaceId();
-            Path path = Path.create(revertInfo.oldName, revertInfo.oldIndex);
-            return idFactory.createNodeId(parentId, path);
         } else {
-            NodeId parentId = parent.getWorkspaceId();
-            return idFactory.createNodeId(parentId, Path.create(getQName(), getIndex()));
+            NodeId parentId = (revertInfo != null) ? revertInfo.oldParent.getWorkspaceId()
: parent.getWorkspaceId();
+            return idFactory.createNodeId(parentId, Path.create(getWorkspaceQName(), getWorkspaceIndex()));
         }
     }
 
@@ -345,7 +352,7 @@
                 return Path.INDEX_DEFAULT;
             }
         } catch (RepositoryException e) {
-            log.error("Error while building Index. ", e);
+            log.error("Error while building Index. ", e.getMessage());
             return Path.INDEX_UNDEFINED;
         }
     }
@@ -919,7 +926,7 @@
 
         // TODO: check if status of THIS_state must be marked modified...
     }
-    
+
     //-------------------------------------------------< HierarchyEntryImpl >---
     /**
      * @inheritDoc
@@ -927,9 +934,55 @@
      * <p/>
      * Returns a <code>NodeState</code>.
      */
-    ItemState doResolve()
-        throws NoSuchItemStateException, ItemStateException {
-        return factory.getItemStateFactory().createNodeState((NodeId) getWorkspaceId(), this);
+    ItemState doResolve() throws NoSuchItemStateException, ItemStateException {
+        return factory.getItemStateFactory().createNodeState(getWorkspaceId(), this);
+    }
+
+    /**
+     * @see HierarchyEntryImpl#buildPath(boolean)
+     */
+    Path buildPath(boolean wspPath) throws RepositoryException {
+        // shortcut for root state
+        if (parent == null) {
+            return Path.ROOT;
+        }
+        // build path otherwise
+        try {
+            Path.PathBuilder builder = new Path.PathBuilder();
+            buildPath(builder, this, wspPath);
+            return builder.getPath();
+        } catch (MalformedPathException e) {
+            String msg = "Failed to build path of " + this;
+            throw new RepositoryException(msg, e);
+        }
+    }
+
+    /**
+     * Adds the path element of an item id to the path currently being built.
+     * On exit, <code>builder</code> contains the path of this entry.
+     *
+     * @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) {
+        NodeEntryImpl parentEntry = (wspPath && nEntry.revertInfo != null) ? nEntry.revertInfo.oldParent
: nEntry.parent;
+        // shortcut for root state
+        if (parentEntry == null) {
+            builder.addRoot();
+            return;
+        }
+
+        // recursively build path of parent
+        buildPath(builder, parentEntry, wspPath);
+
+        int index = (wspPath) ? nEntry.getWorkspaceIndex() : nEntry.getIndex();
+        QName name = (wspPath) ? nEntry.getWorkspaceQName() : nEntry.getQName();
+        // add to path
+        if (index == Path.INDEX_DEFAULT) {
+            builder.addLast(name);
+        } else {
+            builder.addLast(name, index);
+        }
     }
 
     //-----------------------------------------------< private || protected >---
@@ -954,11 +1007,7 @@
      * @return
      */
     boolean matches(QName oldName, int oldIndex) {
-        if (revertInfo != null) {
-            return revertInfo.oldName.equals(oldName) && revertInfo.oldIndex == oldIndex;
-        } else {
-            return getQName().equals(oldName) && getIndex() == oldIndex;
-        }
+        return getWorkspaceQName().equals(oldName) && getWorkspaceIndex() == oldIndex;
     }
 
     /**
@@ -967,10 +1016,23 @@
      * @return
      */
     boolean matches(QName oldName) {
+        return getWorkspaceQName().equals(oldName);
+    }
+
+
+    private QName getWorkspaceQName() {
+        if (revertInfo != null) {
+            return revertInfo.oldName;
+        } else {
+            return getQName();
+        }
+    }
+
+    private int getWorkspaceIndex() {
         if (revertInfo != null) {
-            return revertInfo.oldName.equals(oldName);
+            return revertInfo.oldIndex;
         } else {
-            return getQName().equals(oldName);
+            return getIndex();
         }
     }
 
@@ -1089,26 +1151,90 @@
      */
     private ChildNodeEntries childNodeEntries() {
         if (childNodeEntries == null) {
+            loadChildNodeEntries();
+        } else if (childNodeEntries.getStatus() == ChildNodeEntries.STATUS_INVALIDATED) {
+            reloadChildNodeEntries(childNodeEntries);
+            childNodeEntries.setStatus(ChildNodeEntries.STATUS_OK);
+        }
+        return childNodeEntries;
+    }
+
+    private void loadChildNodeEntries() {
+        try {
             childNodeEntries = new ChildNodeEntries(this);
-            ItemState state = internalGetItemState();
-            if (state == null || state.getStatus() != Status.NEW) {
-                try {
-                    NodeId id = getWorkspaceId();
-                    Iterator it = factory.getItemStateFactory().getChildNodeInfos(id);
-                    while (it.hasNext()) {
-                        ChildInfo ci = (ChildInfo) it.next();
-                        internalAddNodeEntry(ci.getName(), ci.getUniqueID(), ci.getIndex(),
childNodeEntries);
+            if (getStatus() == Status.NEW || Status.isTerminal(getStatus())) {
+                return; // cannot retrieve child-entries from persistent layer
+            }
+
+            NodeId id = getWorkspaceId();
+            Iterator it = factory.getItemStateFactory().getChildNodeInfos(id);
+            // simply add all child entries to the empty collection
+            while (it.hasNext()) {
+                ChildInfo ci = (ChildInfo) it.next();
+                internalAddNodeEntry(ci.getName(), ci.getUniqueID(), ci.getIndex(), childNodeEntries);
+            }
+        } catch (NoSuchItemStateException e) {
+            log.error("Cannot retrieve child node entries.", e);
+            // ignore (TODO correct?)
+        } catch (ItemStateException e) {
+            log.error("Cannot retrieve child node entries.", e);
+            // ignore (TODO correct?)
+        }
+    }
+
+    private void reloadChildNodeEntries(ChildNodeEntries cnEntries) {
+        if (getStatus() == Status.NEW || Status.isTerminal(getStatus())) {
+            // nothing to do
+            return;
+        }
+        try {
+            NodeId id = getWorkspaceId();
+            Iterator it = factory.getItemStateFactory().getChildNodeInfos(id);
+            // create list from all ChildInfos (for multiple loop)
+            List cInfos = new ArrayList();
+            while (it.hasNext()) {
+                cInfos.add((ChildInfo) it.next());
+            }
+            // first make sure the ordering of all existing entries is ok
+            NodeEntry entry = null;
+            for (it = cInfos.iterator(); it.hasNext();) {
+                ChildInfo ci = (ChildInfo) it.next();
+                NodeEntry nextEntry = cnEntries.get(ci);
+                if (nextEntry != null) {
+                    if (entry != null) {
+                        cnEntries.reorder(entry, nextEntry);
                     }
-                } catch (NoSuchItemStateException e) {
-                    log.error("Cannot retrieve child node entries.", e);
-                    // ignore (TODO correct?)
-                } catch (ItemStateException e) {
-                    log.error("Cannot retrieve child node entries.", e);
-                    // ignore (TODO correct?)
+                    entry = nextEntry;
                 }
             }
+            // then insert the 'new' entries
+            List newEntries = new ArrayList();
+            for (it = cInfos.iterator(); it.hasNext();) {
+                ChildInfo ci = (ChildInfo) it.next();
+                NodeEntry beforeEntry = cnEntries.get(ci);
+                if (beforeEntry == null) {
+                    NodeEntry ne = new NodeEntryImpl(this, ci.getName(), ci.getUniqueID(),
factory);
+                    newEntries.add(ne);
+                } else {
+                    // insert all new entries from the list BEFORE the existing
+                    // 'nextEntry'. Then clear the list.
+                    for (int i = 0; i < newEntries.size(); i++) {
+                        cnEntries.add((NodeEntry) newEntries.get(i), beforeEntry);
+                    }
+                    newEntries.clear();
+                }
+            }
+            // deal with new entries at the end
+            for (int i = 0; i < newEntries.size(); i++) {
+                cnEntries.add((NodeEntry) newEntries.get(i));
+            }
+        } catch (NoSuchItemStateException e) {
+            log.error("Cannot retrieve child node entries.", e);
+            // ignore (TODO correct?)
+        } catch (ItemStateException e) {
+            log.error("Cannot retrieve child node entries.", e);
+            // ignore (TODO correct?)
         }
-        return childNodeEntries;
     }
 
     /**
@@ -1148,10 +1274,11 @@
      * Returns the index of the given <code>NodeEntry</code>.
      *
      * @param cne  the <code>NodeEntry</code> instance.
-     * @return the index of the child node entry or <code>Path.INDEX_UNDEFINED</code>
-     * if the given entry isn't a valid child of this <code>NodeEntry</code>.
+     * @return the index of the child node entry.
+     * @throws ItemNotFoundException if the given entry isn't a valid child of
+     * this <code>NodeEntry</code>.
      */
-    private int getChildIndex(NodeEntry cne) {
+    private int getChildIndex(NodeEntry cne) throws ItemNotFoundException {
         List sns = childNodeEntries().get(cne.getQName());
         // index is one based
         int index = Path.INDEX_DEFAULT;
@@ -1167,7 +1294,7 @@
             }
         }
         // not found (should not occur)
-        return Path.INDEX_UNDEFINED;
+        throw new ItemNotFoundException("No valid child entry for NodeEntry " + cne);
     }
 
     /**

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=518930&r1=518929&r2=518930
==============================================================================
--- 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
Fri Mar 16 03:36:11 2007
@@ -17,6 +17,8 @@
 package org.apache.jackrabbit.jcr2spi.hierarchy;
 
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
+import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.jackrabbit.jcr2spi.state.PropertyState;
 import org.apache.jackrabbit.jcr2spi.state.NoSuchItemStateException;
@@ -24,6 +26,8 @@
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.Status;
 
+import javax.jcr.RepositoryException;
+
 /**
  * <code>PropertyEntryImpl</code> implements a reference to a property state.
  */
@@ -62,6 +66,23 @@
      */
     ItemState doResolve() throws NoSuchItemStateException, ItemStateException {
         return factory.getItemStateFactory().createPropertyState(getWorkspaceId(), this);
+    }
+
+    /**
+     * @see HierarchyEntryImpl#buildPath(boolean)
+     */
+    Path buildPath(boolean workspacePath) throws RepositoryException {
+        try {
+            Path.PathBuilder builder = new Path.PathBuilder();
+            builder.addAll(parent.buildPath(workspacePath).getElements());
+            // add property name to parent path
+            builder.addLast(getQName());
+
+            return builder.getPath();
+        } catch (MalformedPathException e) {
+            String msg = "Failed to build path of " + this;
+            throw new RepositoryException(msg, e);
+        }
     }
 
     //------------------------------------------------------< PropertyEntry >---

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=518930&r1=518929&r2=518930
==============================================================================
--- 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
Fri Mar 16 03:36:11 2007
@@ -382,7 +382,7 @@
                 it.remove();
             } catch (ItemStateException e) {
                 // should never occur
-                log.error("Internal error", e);
+                log.error("Internal error:", e.getMessage());
             }
         }
 
@@ -416,7 +416,7 @@
                     } catch (ItemStateException e) {
                         // should never occur. since parent must be available otherwise
                         // the mixin could not been added/removed.
-                        log.error("Internal error", e);
+                        log.error("Internal error:", e.getMessage());
                     }
                 }
                 it.remove();

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java?view=diff&rev=518930&r1=518929&r2=518930
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
Fri Mar 16 03:36:11 2007
@@ -153,11 +153,11 @@
             PropertyInfo info = service.getPropertyInfo(sessionInfo, propertyId);
             return createPropertyState(info, entry);
         } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
+            throw new NoSuchItemStateException(e.getMessage());
         } catch (ItemNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
+            throw new NoSuchItemStateException(e.getMessage());
         } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
+            throw new ItemStateException(e.getMessage());
         }
     }
 
@@ -193,13 +193,13 @@
             }
             return createPropertyState(info, propEntry);
         } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
+            throw new NoSuchItemStateException(e.getMessage());
         } catch (ItemNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
+            throw new NoSuchItemStateException(e.getMessage());
         } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
+            throw new ItemStateException(e.getMessage());
         } catch (MalformedPathException e) {
-            throw new ItemStateException(e.getMessage(), e);
+            throw new ItemStateException(e.getMessage());
         }
     }
 
@@ -213,11 +213,11 @@
         try {
             return service.getChildInfos(sessionInfo, nodeId);
         } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
+            throw new NoSuchItemStateException(e.getMessage());
         } catch (ItemNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
+            throw new NoSuchItemStateException(e.getMessage());
         } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
+            throw new ItemStateException(e.getMessage());
         }
     }
 
@@ -277,7 +277,7 @@
         if (parent == null) {
             // special case for root state
             definition = wspManager.getNodeTypeRegistry().getRootNodeDef();
-        } else if (parent.isAvailable() && parent.getStatus() != Status.INVALIDATED)
{
+        } else if (parent.isAvailable() && parent.getStatus() == Status.EXISTING)
{
             // try to retrieve definition if the parent is available
             try {
                 NodeState parentState = parent.getNodeState();
@@ -285,13 +285,13 @@
                 definition = ent.getApplicableNodeDefinition(info.getQName(), info.getNodetype(),
ntReg);
             } catch (RepositoryException e) {
                 // should not get here
-                log.warn("Internal error", e);
+                log.warn("Internal error", e.getMessage());
             } catch (ItemStateException e) {
                 // should not get here
-                log.warn("Internal error", e);
+                log.warn("Internal error", e.getMessage());
             } catch (NodeTypeConflictException e) {
                 // should not get here
-               log.warn("Internal error", e);
+               log.warn("Internal error", e.getMessage());
             }
         }
 
@@ -337,27 +337,26 @@
 
         QPropertyDefinition definition = null;
         // try to retrieve property definition
-        if (entry.getParent().isAvailable() && entry.getStatus() != Status.INVALIDATED)
{
-            NodeState parentState = null;
+        NodeEntry parent = entry.getParent();
+        if (parent.isAvailable() && parent.getStatus() == Status.EXISTING) {
             try {
-                parentState = entry.getParent().getNodeState();
+                NodeState parentState = parent.getNodeState();
                 EffectiveNodeType ent = wspManager.getNodeTypeRegistry().getEffectiveNodeType(parentState.getNodeTypeNames());
                 QPropertyDefinition defs[] = ent.getApplicablePropertyDefinitions(info.getQName(),
info.getType(), info.isMultiValued());
                 if (defs.length == 1) {
                     definition = defs[0];
-                }
-                else {
+                } else {
                     definition = service.getPropertyDefinition(sessionInfo, entry.getId());
                 }
             } catch (ItemStateException e) {
                 // should not get here
-                log.warn("Internal error", e);
+                log.warn("Internal error", e.getMessage());
             } catch (RepositoryException e) {
                 // should not get here
-                log.warn("Internal error", e);
+                log.warn("Internal error", e.getMessage());
             } catch (NodeTypeConflictException e) {
                 // should not get here
-                log.warn("Internal error", e);
+                log.warn("Internal error", e.getMessage());
             }
         }
 
@@ -378,7 +377,7 @@
      * a uniqueID that may move within the hierarchy upon restore or clone.
      */
     private void assertMatchingPath(ItemInfo info, HierarchyEntry entry) throws NoSuchItemStateException,
RepositoryException {
-        if (!info.getPath().equals(entry.getPath())) {
+        if (!info.getPath().equals(entry.getWorkspacePath())) {
             throw new NoSuchItemStateException("HierarchyEntry does not belong the given
ItemInfo.");
         }
     }
@@ -434,4 +433,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}



Mime
View raw message