You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2007/08/13 18:25:56 UTC

svn commit: r565399 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: NodeImpl.java xml/SessionImporter.java xml/WorkspaceImporter.java

Author: stefan
Date: Mon Aug 13 09:25:54 2007
New Revision: 565399

URL: http://svn.apache.org/viewvc?view=rev&rev=565399
Log:
JCR-1055: Incorrect node position after import

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?view=diff&rev=565399&r1=565398&r2=565399
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Mon Aug 13 09:25:54 2007
@@ -1858,6 +1858,79 @@
         thisState.setChildNodeEntries(list);
     }
 
+    /**
+     * Replaces the child node with the specified <code>id</code>
+     * by a new child node with the same id and specified <code>nodeName</code>,
+     * <code>nodeTypeName</code> and <code>mixinNames</code>.
+     *
+     * @param id           id of the child node to be replaced
+     * @param nodeName     name of the new node
+     * @param nodeTypeName name of the new node's node type
+     * @param mixinNames   name of the new node's mixin types
+     *
+     * @return the new child node replacing the existing child
+     * @throws ItemNotFoundException
+     * @throws NoSuchNodeTypeException
+     * @throws VersionException
+     * @throws ConstraintViolationException
+     * @throws LockException
+     * @throws RepositoryException
+     */
+    public synchronized NodeImpl replaceChildNode(NodeId id, QName nodeName,
+                                                  QName nodeTypeName,
+                                                  QName[] mixinNames)
+            throws ItemNotFoundException, NoSuchNodeTypeException, VersionException,
+            ConstraintViolationException, LockException, RepositoryException {
+        // check state of this instance
+        sanityCheck();
+
+        Node existing = (Node) itemMgr.getItem(id);
+
+        // 'replace' is actually a 'remove existing/add new' operation;
+        // this unfortunately changes the order of this node's
+        // child node entries (JCR-1055);
+        // => backup list of child node entries beforehand in order
+        // to restore it afterwards
+        NodeState.ChildNodeEntry cneExisting = ((NodeState) state).getChildNodeEntry(id);
+        if (cneExisting == null) {
+            throw new ItemNotFoundException(safeGetJCRPath()
+                    + ": no child node entry with id " + id);
+        }
+        List cneList = new ArrayList(((NodeState) state).getChildNodeEntries());
+
+        // remove existing
+        existing.remove();
+
+        // create new child node
+        NodeImpl node = addNode(nodeName, nodeTypeName, id.getUUID());
+        if (mixinNames != null) {
+            for (int i = 0; i < mixinNames.length; i++) {
+                node.addMixin(mixinNames[i]);
+            }
+        }
+
+        // restore list of child node entries (JCR-1055)
+        if (cneExisting.getName().equals(nodeName)) {
+            // restore original child node list
+            ((NodeState) state).setChildNodeEntries(cneList);
+        } else {
+            // replace child node entry with different name
+            // but preserving original position
+            ((NodeState) state).removeAllChildNodeEntries();
+            for (Iterator iter = cneList.iterator(); iter.hasNext();) {
+                NodeState.ChildNodeEntry cne = (NodeState.ChildNodeEntry) iter.next();
+                if (cne.getId().equals(id)) {
+                    // replace entry with different name
+                    ((NodeState) state).addChildNodeEntry(nodeName, id);
+                } else {
+                    ((NodeState) state).addChildNodeEntry(cne.getName(), cne.getId());
+                }
+            }
+        }
+
+        return node;
+    }
+
     //-----------------------------------------------------------------< Item >
     /**
      * {@inheritDoc}

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java?view=diff&rev=565399&r1=565398&r2=565399
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java Mon Aug 13 09:25:54 2007
@@ -166,12 +166,10 @@
             }
             // 'replace' current parent with parent of conflicting
             parent = (NodeImpl) conflicting.getParent();
-            // remove conflicting
-            conflicting.remove();
-            // create new with given uuid at same location as conflicting
-            node = createNode(parent, nodeInfo.getName(),
-                    nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(),
-                    nodeInfo.getId());
+
+            // replace child node
+            node = parent.replaceChildNode(nodeInfo.getId(), nodeInfo.getName(),
+                    nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames());
         } else {
             String msg = "unknown uuidBehavior: " + uuidBehavior;
             log.debug(msg);

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java?view=diff&rev=565399&r1=565398&r2=565399
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java Mon Aug 13 09:25:54 2007
@@ -53,6 +53,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Stack;
+import java.util.ArrayList;
 
 /**
  * <code>WorkspaceImporter</code> ...
@@ -226,6 +227,14 @@
                     | BatchedItemOperations.CHECK_LOCK
                     | BatchedItemOperations.CHECK_VERSIONING
                     | BatchedItemOperations.CHECK_CONSTRAINTS);
+
+            // 'replace' is actually a 'remove existing/add new' operation;
+            // this unfortunately changes the order of the parent's
+            // child node entries (JCR-1055);
+            // => backup list of child node entries beforehand in order
+            // to restore it afterwards
+            NodeState.ChildNodeEntry cneConflicting = parent.getChildNodeEntry(nodeInfo.getId());
+            List cneList = new ArrayList(parent.getChildNodeEntries());
             // do remove conflicting (recursive)
             itemOps.removeNodeState(conflicting);
             // create new with given uuid at same location as conflicting:
@@ -241,6 +250,24 @@
             node = itemOps.createNodeState(parent, nodeInfo.getName(),
                     nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(),
                     nodeInfo.getId());
+            // restore list of child node entries (JCR-1055)
+            if (cneConflicting.getName().equals(nodeInfo.getName())) {
+                // restore original child node list
+                parent.setChildNodeEntries(cneList);
+            } else {
+                // replace child node entry with different name
+                // but preserving original position
+                parent.removeAllChildNodeEntries();
+                for (Iterator iter = cneList.iterator(); iter.hasNext();) {
+                    NodeState.ChildNodeEntry cne = (NodeState.ChildNodeEntry) iter.next();
+                    if (cne.getId().equals(nodeInfo.getId())) {
+                        // replace entry with different name
+                        parent.addChildNodeEntry(nodeInfo.getName(), nodeInfo.getId());
+                    } else {
+                        parent.addChildNodeEntry(cne.getName(), cne.getId());
+                    }
+                }
+            }
         } else {
             String msg = "unknown uuidBehavior: " + uuidBehavior;
             log.debug(msg);
@@ -493,7 +520,7 @@
      * being imported already exists; if this property has been imported
      * as well (e.g. through document view import where an element can have
      * the same name as one of the attributes of its parent element) we have
-     * to rename the onflicting property.
+     * to rename the conflicting property.
      *
      * @see http://issues.apache.org/jira/browse/JCR-61
      * @param parent parent node