jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject svn commit: r125788 - in incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: . state xml
Date Thu, 20 Jan 2005 16:24:15 GMT
Author: stefan
Date: Thu Jan 20 08:24:14 2005
New Revision: 125788

URL: http://svn.apache.org/viewcvs?view=rev&rev=125788
Log:
optimized the following methods:

Node.addNode
Node.getProperty
Node.hasProperty
Node.getNode
Node.hasNode
Node.save

avoid unnecessary throwing & catching of exceptions
avoid unnecessary building & resolving of paths
avoid unnecessary regexp evaluations



Modified:
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/Path.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java

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?view=diff&rev=125788&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java&r1=125787&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java&r2=125788
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java	Thu Jan 20
08:24:14 2005
@@ -69,6 +69,125 @@
         this.definition = definition;
     }
 
+    /**
+     * Returns the id of the property at <code>relPath</code> or <code>null</code>
+     * if no property exists at <code>relPath</code>.
+     * <p/>
+     * Note that access rights are not checked.
+     *
+     * @param relPath relative path of a (possible) property
+     * @return the id of the property at <code>relPath</code> or
+     *         <code>null</code> if no property exists at <code>relPath</code>
+     * @throws RepositoryException if <code>relPath</code> is not a valid
+     *                             relative path
+     */
+    protected PropertyId resolveRelativePropertyPath(String relPath)
+            throws RepositoryException {
+        try {
+            /**
+             * first check if relPath is just a name (in which case we don't
+             * have to build & resolve absolute path)
+             */
+            Path p = Path.create(relPath, session.getNamespaceResolver(), false);
+            if (p.getLength() == 1) {
+                Path.PathElement pe = p.getNameElement();
+                if (pe.denotesName()) {
+                    if (pe.getIndex() > 0) {
+                        // property name can't have subscript
+                        String msg = relPath + " is not a valid property path";
+                        log.error(msg);
+                        throw new RepositoryException(msg);
+                    }
+                    // check if property entry exists
+                    NodeState thisState = (NodeState) state;
+                    if (thisState.hasPropertyEntry(pe.getName())) {
+                        return new PropertyId(thisState.getUUID(), pe.getName());
+                    } else {
+                        // there's no property with that name
+                        return null;
+                    }
+                }
+            }
+            /**
+             * build and resolve absolute path
+             */
+            p = Path.create(getPrimaryPath(), relPath, session.getNamespaceResolver(), true);
+            try {
+                ItemId id = session.getHierarchyManager().resolvePath(p);
+                if (!id.denotesNode()) {
+                    return (PropertyId) id;
+                } else {
+                    // not a property
+                    return null;
+                }
+            } catch (PathNotFoundException pnfe) {
+                return null;
+            }
+        } catch (MalformedPathException e) {
+            String msg = "failed to resolve path " + relPath + " relative to " + safeGetJCRPath();
+            log.error(msg, e);
+            throw new RepositoryException(msg, e);
+        }
+    }
+
+    /**
+     * Returns the id of the node at <code>relPath</code> or <code>null</code>
+     * if no node exists at <code>relPath</code>.
+     * <p/>
+     * Note that access rights are not checked.
+     *
+     * @param relPath relative path of a (possible) node
+     * @return the id of the node at <code>relPath</code> or
+     *         <code>null</code> if no node exists at <code>relPath</code>
+     * @throws RepositoryException if <code>relPath</code> is not a valid
+     *                             relative path
+     */
+    protected NodeId resolveRelativeNodePath(String relPath)
+            throws RepositoryException {
+        try {
+            /**
+             * first check if relPath is just a name (in which case we don't
+             * have to build & resolve absolute path)
+             */
+            Path p = Path.create(relPath, session.getNamespaceResolver(), false);
+            if (p.getLength() == 1) {
+                Path.PathElement pe = p.getNameElement();
+                if (pe.denotesName()) {
+                    // check if node entry exists
+                    NodeState thisState = (NodeState) state;
+                    NodeState.ChildNodeEntry cne =
+                            thisState.getChildNodeEntry(pe.getName(),
+                                    pe.getIndex() == 0 ? 1 : pe.getIndex());
+                    if (cne != null) {
+                        return new NodeId(cne.getUUID());
+                    } else {
+                        // there's no child node with that name
+                        return null;
+                    }
+                }
+            }
+            /**
+             * build and resolve absolute path
+             */
+            p = Path.create(getPrimaryPath(), relPath, session.getNamespaceResolver(), true);
+            try {
+                ItemId id = session.getHierarchyManager().resolvePath(p);
+                if (id.denotesNode()) {
+                    return (NodeId) id;
+                } else {
+                    // not a node
+                    return null;
+                }
+            } catch (PathNotFoundException pnfe) {
+                return null;
+            }
+        } catch (MalformedPathException e) {
+            String msg = "failed to resolve path " + relPath + " relative to " + safeGetJCRPath();
+            log.error(msg, e);
+            throw new RepositoryException(msg, e);
+        }
+    }
+
     protected synchronized ItemState getOrCreateTransientItemState()
             throws RepositoryException {
         if (!isTransient()) {
@@ -507,6 +626,7 @@
         }
 
         // check for name collisions
+/*
         try {
             Item item = itemMgr.getItem(nodePath);
             if (!item.isNode()) {
@@ -523,6 +643,25 @@
         } catch (PathNotFoundException pnfe) {
             // no name collision
         }
+*/
+        NodeState thisState = (NodeState) state;
+        if (thisState.hasPropertyEntry(nodeName)) {
+            // there's already a property with that name
+            throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
+        }
+        NodeState.ChildNodeEntry cne = thisState.getChildNodeEntry(nodeName, 1);
+        if (cne != null) {
+            // there's already a child node entry with that name;
+            // check same-name sibling setting of new node
+            if (!def.allowSameNameSibs()) {
+                throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
+            }
+            // check same-name sibling setting of existing node
+            NodeId newId = new NodeId(cne.getUUID());
+            if (!((NodeImpl) itemMgr.getItem(newId)).getDefinition().allowSameNameSibs())
{
+                throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
+            }
+        }
 
         // check if versioning allows write (only cheep call)
         if (!isCheckedOut(false)) {
@@ -791,30 +930,19 @@
      *                               specified name.
      * @throws RepositoryException   If another error occurs.
      */
-    public NodeImpl getNode(QName name, int index) throws ItemNotFoundException, RepositoryException
{
+    public NodeImpl getNode(QName name, int index)
+            throws ItemNotFoundException, RepositoryException {
         // check state of this instance
         sanityCheck();
 
-        Path nodePath;
-        try {
-            nodePath = Path.create(getPrimaryPath(), name, index, true);
-        } catch (MalformedPathException e) {
-            // should never happen
-            String msg = "internal error: invalid path " + safeGetJCRPath();
-            log.error(msg, e);
-            throw new RepositoryException(msg, e);
+        NodeState thisState = (NodeState) state;
+        NodeState.ChildNodeEntry cne = thisState.getChildNodeEntry(name, index);
+        if (cne == null) {
+            throw new ItemNotFoundException();
         }
-
+        NodeId nodeId = new NodeId(cne.getUUID());
         try {
-            Item item = itemMgr.getItem(nodePath);
-            if (item.isNode()) {
-                return (NodeImpl) item;
-            } else {
-                // there's a property with that name, no child node though
-                throw new ItemNotFoundException();
-            }
-        } catch (PathNotFoundException pnfe) {
-            throw new ItemNotFoundException();
+            return (NodeImpl) itemMgr.getItem(nodeId);
         } catch (AccessDeniedException ade) {
             throw new ItemNotFoundException();
         }
@@ -830,12 +958,7 @@
      * @throws RepositoryException If an unspecified error occurs.
      */
     public boolean hasNode(QName name) throws RepositoryException {
-        try {
-            getNode(name, 1);
-            return true;
-        } catch (ItemNotFoundException pnfe) {
-            return false;
-        }
+        return hasNode(name, 1);
     }
 
     /**
@@ -849,12 +972,17 @@
      * @throws RepositoryException If an unspecified error occurs.
      */
     public boolean hasNode(QName name, int index) throws RepositoryException {
-        try {
-            getNode(name, index);
-            return true;
-        } catch (ItemNotFoundException pnfe) {
+        // check state of this instance
+        sanityCheck();
+
+        NodeState thisState = (NodeState) state;
+        NodeState.ChildNodeEntry cne = thisState.getChildNodeEntry(name, index);
+        if (cne == null) {
             return false;
         }
+        NodeId nodeId = new NodeId(cne.getUUID());
+
+        return itemMgr.itemExists(nodeId);
     }
 
     /**
@@ -872,7 +1000,8 @@
         // check state of this instance
         sanityCheck();
 
-        PropertyId propId = new PropertyId(((NodeState) state).getUUID(), name);
+        NodeState thisState = (NodeState) state;
+        PropertyId propId = new PropertyId(thisState.getUUID(), name);
         try {
             return (PropertyImpl) itemMgr.getItem(propId);
         } catch (AccessDeniedException ade) {
@@ -890,12 +1019,16 @@
      * @throws RepositoryException If an unspecified error occurs.
      */
     public boolean hasProperty(QName name) throws RepositoryException {
-        try {
-            getProperty(name);
-            return true;
-        } catch (ItemNotFoundException pnfe) {
+        // check state of this instance
+        sanityCheck();
+
+        NodeState thisState = (NodeState) state;
+        if (!thisState.hasPropertyEntry(name)) {
             return false;
         }
+        PropertyId propId = new PropertyId(thisState.getUUID(), name);
+
+        return itemMgr.itemExists(propId);
     }
 
     /**
@@ -1517,7 +1650,7 @@
             throws PathNotFoundException, RepositoryException {
         // check state of this instance
         sanityCheck();
-
+/*
         Path nodePath;
         try {
             nodePath = Path.create(getPrimaryPath(), relPath, session.getNamespaceResolver(),
true);
@@ -1538,6 +1671,16 @@
         } catch (AccessDeniedException ade) {
             throw new PathNotFoundException(relPath);
         }
+*/
+        NodeId id = resolveRelativeNodePath(relPath);
+        if (id == null) {
+            throw new PathNotFoundException(relPath);
+        }
+        try {
+            return (Node) itemMgr.getItem(id);
+        } catch (AccessDeniedException ade) {
+            throw new PathNotFoundException(relPath);
+        }
     }
 
     /**
@@ -1601,7 +1744,7 @@
             throws PathNotFoundException, RepositoryException {
         // check state of this instance
         sanityCheck();
-
+/*
         Path propPath;
         try {
             propPath = Path.create(getPrimaryPath(), relPath, session.getNamespaceResolver(),
true);
@@ -1622,17 +1765,35 @@
         } catch (AccessDeniedException ade) {
             throw new PathNotFoundException(relPath);
         }
+*/
+        PropertyId id = resolveRelativePropertyPath(relPath);
+        if (id == null) {
+            throw new PathNotFoundException(relPath);
+        }
+        try {
+            return (Property) itemMgr.getItem(id);
+        } catch (AccessDeniedException ade) {
+            throw new PathNotFoundException(relPath);
+        }
     }
 
     /**
      * @see Node#hasNode(String)
      */
     public boolean hasNode(String relPath) throws RepositoryException {
+/*
         try {
-            return getNode(relPath) != null;
+            getNode(relPath);
+            return true;
         } catch (PathNotFoundException pnfe) {
             return false;
         }
+*/
+        // check state of this instance
+        sanityCheck();
+
+        NodeId id = resolveRelativeNodePath(relPath);
+        return (id != null) ? itemMgr.itemExists(id) : false;
     }
 
     /**
@@ -2029,11 +2190,19 @@
      * @see Node#hasProperty(String)
      */
     public boolean hasProperty(String relPath) throws RepositoryException {
+/*
         try {
-            return getProperty(relPath) != null;
+            getProperty(relPath);
+            return true;
         } catch (PathNotFoundException pnfe) {
             return false;
         }
+*/
+        // check state of this instance
+        sanityCheck();
+
+        PropertyId id = resolveRelativePropertyPath(relPath);
+        return (id != null) ? itemMgr.itemExists(id) : false;
     }
 
     /**
@@ -2504,7 +2673,6 @@
      * state of its parent.
      *
      * @param inherit
-     *
      * @see Node#isCheckedOut()
      */
     public boolean isCheckedOut(boolean inherit) throws RepositoryException {

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/Path.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/Path.java?view=diff&rev=125788&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/Path.java&r1=125787&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/Path.java&r2=125788
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/Path.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/Path.java	Thu Jan 20 08:24:14
2005
@@ -662,61 +662,65 @@
     }
 
     //--------------------------------------------------------< inner classes >
-    public static final class PathBuilder implements Cloneable {
+    /**
+     * package private inner class used to build a path from path elements;
+     * this class does not validate the format of the path elements!
+     */
+    static final class PathBuilder implements Cloneable {
         private final LinkedList queue;
 
-        public PathBuilder() {
+        PathBuilder() {
             queue = new LinkedList();
         }
 
-        public PathBuilder(PathElement[] elements) {
+        PathBuilder(PathElement[] elements) {
             this();
             addAll(elements);
         }
 
-        public void addRoot() {
+        void addRoot() {
             queue.addFirst(ROOT_ELEMENT);
         }
 
-        public void addAll(PathElement[] elements) {
+        void addAll(PathElement[] elements) {
             for (int i = 0; i < elements.length; i++) {
                 queue.add(elements[i]);
             }
         }
 
-        public void addFirst(String nameSpaceURI, String localName) {
+        void addFirst(String nameSpaceURI, String localName) {
             queue.addFirst(new PathElement(nameSpaceURI, localName));
         }
 
-        public void addFirst(String nameSpaceURI, String localName, int index) {
+        void addFirst(String nameSpaceURI, String localName, int index) {
             queue.addFirst(new PathElement(nameSpaceURI, localName, index));
         }
 
-        public void addFirst(QName name) {
+        void addFirst(QName name) {
             queue.addFirst(new PathElement(name));
         }
 
-        public void addFirst(QName name, int index) {
+        void addFirst(QName name, int index) {
             queue.addFirst(new PathElement(name, index));
         }
 
-        public void addLast(String nameSpaceURI, String localName) {
+        void addLast(String nameSpaceURI, String localName) {
             queue.addLast(new PathElement(nameSpaceURI, localName));
         }
 
-        public void addLast(String nameSpaceURI, String localName, int index) {
+        void addLast(String nameSpaceURI, String localName, int index) {
             queue.addLast(new PathElement(nameSpaceURI, localName, index));
         }
 
-        public void addLast(QName name) {
+        void addLast(QName name) {
             queue.addLast(new PathElement(name));
         }
 
-        public void addLast(QName name, int index) {
+        void addLast(QName name, int index) {
             queue.addLast(new PathElement(name, index));
         }
 
-        public Path getPath() throws MalformedPathException {
+        Path getPath() throws MalformedPathException {
             PathElement[] elements = (PathElement[]) queue.toArray(new PathElement[queue.size()]);
             // validate path
             if (elements.length == 0) {
@@ -726,12 +730,6 @@
                 if (elements[i].denotesRoot()) {
                     throw new MalformedPathException("path contains invalid root element(s)");
                 }
-                String localName = elements[i].getName().getLocalName();
-                Matcher matcher = PATH_ELEMENT_PATTERN.matcher(localName);
-                if (!matcher.matches()) {
-                    // illegal syntax for path element
-                    throw new MalformedPathException(localName + "' is not a legal path element");
-                }
             }
             return new Path(elements);
         }
@@ -757,6 +755,21 @@
         }
 
         // PathElement override
+        public boolean denotesCurrent() {
+            return false;
+        }
+
+        // PathElement override
+        public boolean denotesParent() {
+            return false;
+        }
+
+        // PathElement override
+        public boolean denotesName() {
+            return false;
+        }
+
+        // PathElement override
         public String toJCRName(NamespaceResolver resolver) throws NoPrefixDeclaredException
{
             return "";
         }
@@ -775,6 +788,26 @@
         }
 
         // PathElement override
+        public boolean denotesRoot() {
+            return false;
+        }
+
+        // PathElement override
+        public boolean denotesCurrent() {
+            return true;
+        }
+
+        // PathElement override
+        public boolean denotesParent() {
+            return false;
+        }
+
+        // PathElement override
+        public boolean denotesName() {
+            return false;
+        }
+
+        // PathElement override
         public String toJCRName(NamespaceResolver resolver) throws NoPrefixDeclaredException
{
             return LITERAL;
         }
@@ -793,6 +826,26 @@
         }
 
         // PathElement override
+        public boolean denotesRoot() {
+            return false;
+        }
+
+        // PathElement override
+        public boolean denotesCurrent() {
+            return false;
+        }
+
+        // PathElement override
+        public boolean denotesParent() {
+            return true;
+        }
+
+        // PathElement override
+        public boolean denotesName() {
+            return false;
+        }
+
+        // PathElement override
         public String toJCRName(NamespaceResolver resolver) throws NoPrefixDeclaredException
{
             return LITERAL;
         }
@@ -859,8 +912,48 @@
             return index;
         }
 
+        /**
+         * Returns <code>true</code> if this element denotes the <i>root</i>
element,
+         * otherwise returns <code>false</code>.
+         *
+         * @return <code>true</code> if this element denotes the <i>root</i>
+         *         element; otherwise <code>false</code>
+         */
         public boolean denotesRoot() {
-            return false;
+            return equals(ROOT_ELEMENT);
+        }
+
+        /**
+         * Returns <code>true</code> if this element denotes the <i>parent</i>
+         * ('..') element, otherwise returns <code>false</code>.
+         *
+         * @return <code>true</code> if this element denotes the <i>parent</i>
+         *         element; otherwise <code>false</code>
+         */
+        public boolean denotesParent() {
+            return equals(PARENT_ELEMENT);
+        }
+
+        /**
+         * Returns <code>true</code> if this element denotes the <i>current</i>
+         * ('.') element, otherwise returns <code>false</code>.
+         *
+         * @return <code>true</code> if this element denotes the <i>current</i>
+         *         element; otherwise <code>false</code>
+         */
+        public boolean denotesCurrent() {
+            return equals(CURRENT_ELEMENT);
+        }
+
+        /**
+         * Returns <code>true</code> if this element represents a regular name
+         * (i.e. neither root, '.' nor '..'), otherwise returns <code>false</code>.
+         *
+         * @return <code>true</code> if this element represents a regular name;
+         *         otherwise <code>false</code>
+         */
+        public boolean denotesName() {
+            return !denotesRoot() && !denotesParent() && !denotesCurrent();
         }
 
         public String toJCRName(NamespaceResolver resolver) throws NoPrefixDeclaredException
{
@@ -951,7 +1044,8 @@
     }
 
     //-------------------------------------------------------< implementation >
-    private static PathElement[] parse(String jcrPath, PathElement[] master, NamespaceResolver
resolver)
+    private static PathElement[] parse(String jcrPath, PathElement[] master,
+                                       NamespaceResolver resolver)
             throws MalformedPathException {
         // shortcut
         if (jcrPath.equals("/")) {

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?view=diff&rev=125788&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java&r1=125787&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java&r2=125788
==============================================================================
--- 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
Thu Jan 20 08:24:14 2005
@@ -20,6 +20,8 @@
 import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider;
 import org.apache.log4j.Logger;
 
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.RepositoryException;
 import java.io.PrintStream;
 import java.util.*;
@@ -31,6 +33,7 @@
 
     private static Logger log = Logger.getLogger(SessionItemStateManager.class);
 
+    private final NodeId rootNodeId;
     private final PersistentItemStateProvider persistentStateMgr;
     private VirtualItemStateProvider[] virtualProviders = new VirtualItemStateProvider[0];
     private final TransientItemStateManager transientStateMgr;
@@ -44,6 +47,7 @@
      * @param nsResolver
      */
     public SessionItemStateManager(String rootNodeUUID, PersistentItemStateProvider persistentStateMgr,
NamespaceResolver nsResolver) {
+        rootNodeId = new NodeId(rootNodeUUID);
         this.persistentStateMgr = persistentStateMgr;
         // create transient item state manager
         transientStateMgr = new TransientItemStateManager();
@@ -256,20 +260,20 @@
      * @see ItemStateProvider#hasItemState(ItemId)
      */
     public boolean hasItemState(ItemId id) {
-	// first check if the specified item has been transiently removed
-	if (transientStateMgr.hasItemStateInAttic(id)) {
-	    /**
-	     * check if there's new transient state for the specified item
-	     * (e.g. if a property with name 'x' has been removed and a new
-	     * property with same name has been created);
-	     */
-	    return transientStateMgr.hasItemState(id);
-	}
-
-	// check if there's transient state for the specified item
-	if (transientStateMgr.hasItemState(id)) {
-	    return true;
-	}
+        // first check if the specified item has been transiently removed
+        if (transientStateMgr.hasItemStateInAttic(id)) {
+            /**
+             * check if there's new transient state for the specified item
+             * (e.g. if a property with name 'x' has been removed and a new
+             * property with same name has been created);
+             */
+            return transientStateMgr.hasItemState(id);
+        }
+
+        // check if there's transient state for the specified item
+        if (transientStateMgr.hasItemState(id)) {
+            return true;
+        }
 
         // check the virtual root ids (needed for overlay)
         for (int i = 0; i < virtualProviders.length; i++) {
@@ -277,10 +281,10 @@
                 return true;
             }
         }
-	// check if there's persistent state for the specified item
-	if (persistentStateMgr.hasItemState(id)) {
-	    return true;
-	}
+        // check if there's persistent state for the specified item
+        if (persistentStateMgr.hasItemState(id)) {
+            return true;
+        }
 
         // check if there is a virtual state for the specified item
         for (int i = 0; i < virtualProviders.length; i++) {
@@ -289,7 +293,7 @@
             }
         }
 
-	return false;
+        return false;
     }
 
     /**
@@ -337,8 +341,12 @@
      * @param parentId the id of the common parent of the transient item state
      *                 instances to be returned.
      * @return an iterator over descendant transient item state instances
+     * @throws InvalidItemStateException if any descendant item state has been
+     *                                   deleted externally
+     * @throws RepositoryException       if another error occurs
      */
-    public Iterator getDescendantTransientItemStates(ItemId parentId) {
+    public Iterator getDescendantTransientItemStates(ItemId 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();
@@ -346,17 +354,64 @@
         // collection of descendant transient states:
         // the path serves as key and sort criteria
         TreeMap descendants = new TreeMap(new PathComparator());
+
+        // use shortcut if root was specified as parent
+        // (in which case all non-root states are descendents)
+        if (parentId.equals(rootNodeId)) {
+            Iterator iter = transientStateMgr.getEntries();
+            while (iter.hasNext()) {
+                ItemState state = (ItemState) iter.next();
+                ItemId id = state.getId();
+                if (id.equals(rootNodeId)) {
+                    // skip root
+                    continue;
+                }
+                try {
+                    Path p = hierMgr.getPath(id);
+                    descendants.put(p, state);
+                } catch (ItemNotFoundException infe) {
+                    String msg = id + ": the item has been removed externally.";
+                    log.error(msg);
+                    throw new InvalidItemStateException(msg);
+                }
+            }
+            return descendants.values().iterator();
+        }
+
+        Path[] parentPaths = null;
+        try {
+            parentPaths = hierMgr.getAllPaths(parentId);
+        } catch (ItemNotFoundException infe) {
+            String msg = parentId + ": the item has been removed externally.";
+            log.error(msg);
+            throw new InvalidItemStateException(msg);
+        }
+
+        /**
+         * walk through list of transient states and check if
+         * they are descendants of the specified parent
+         */
         try {
-            Path[] parentPaths = hierMgr.getAllPaths(parentId);
-            /**
-             * walk through list of transient states and check if
-             * they are descendants of the specified parent
-             */
             Iterator iter = transientStateMgr.getEntries();
             while (iter.hasNext()) {
                 ItemState state = (ItemState) iter.next();
                 ItemId id = state.getId();
-                Path[] paths = hierMgr.getAllPaths(id);
+                Path[] paths = null;
+                try {
+                    paths = hierMgr.getAllPaths(id);
+                } 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;
+                }
                 boolean isDescendant = false;
                 /**
                  * check if any of the paths to the transient state
@@ -396,7 +451,24 @@
                          * is a descendant of/identical with any of the
                          * specified parentId's paths.
                          */
-                        Path[] pa = hierMgr.getAllPaths(new NodeId((String) iterUUIDs.next()));
+                        String uuid = (String) iterUUIDs.next();
+                        Path[] pa = null;
+                        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
@@ -406,11 +478,15 @@
                                     // this is a descendant, add it to the list and
                                     // continue with next transient state
 
-                                    // FIXME need to create dummy path in order
-                                    // to avoid conflicts
-                                    Path.PathBuilder pb = new Path.PathBuilder(p0.getElements());
-                                    pb.addFirst(NamespaceRegistryImpl.NS_DEFAULT_URI, Integer.toString(new
Random().nextInt()));
-                                    descendants.put(pb.getPath(), state);
+                                    /**
+                                     * FIXME need to create dummy path by
+                                     * appending a random integer in order to
+                                     * avoid potential conflicts
+                                     */
+                                    Path dummy = Path.create(p0,
+                                            Path.create(new QName(NamespaceRegistryImpl.NS_DEFAULT_URI,
Integer.toString(new Random().nextInt())), 0),
+                                            true);
+                                    descendants.put(dummy, state);
                                     isDescendant = true;
                                     break;
                                 }
@@ -427,9 +503,9 @@
                 // continue with next transient state
             }
         } catch (MalformedPathException mpe) {
-            log.warn("inconsistent hierarchy state", mpe);
-        } catch (RepositoryException re) {
-            log.warn("inconsistent hierarchy state", re);
+            String msg = "inconsistent hierarchy state";
+            log.warn(msg, mpe);
+            throw new RepositoryException(msg, mpe);
         }
 
         return descendants.values().iterator();

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java?view=diff&rev=125788&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java&r1=125787&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java&r2=125788
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
Thu Jan 20 08:24:14 2005
@@ -52,7 +52,7 @@
     // jcr:xmltext
     public static final QName NODENAME_XMLTEXT =
             new QName(NamespaceRegistryImpl.NS_JCR_URI, "xmltext");
-    // jcr:xmltext
+    // jcr:xmlcharacters
     public static final QName PROPNAME_XMLCHARACTERS =
             new QName(NamespaceRegistryImpl.NS_JCR_URI, "xmlcharacters");
 
@@ -123,7 +123,7 @@
                 }
             }
         } else {
-            // regalur node
+            // regular node
 
             // element name
             String elemName;

Mime
View raw message