jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject svn commit: r158489 - in incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: WorkspaceImpl.java util/ReferenceChangeTracker.java xml/SessionImporter.java
Date Mon, 21 Mar 2005 17:50:37 GMT
Author: stefan
Date: Mon Mar 21 09:50:35 2005
New Revision: 158489

URL: http://svn.apache.org/viewcvs?view=rev&rev=158489
Log:
re-implementing Workspace methods clone, copy, importXML [work in progress...]


Added:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ReferenceChangeTracker.java
  (with props)
Modified:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java?view=diff&r1=158488&r2=158489
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java Mon
Mar 21 09:50:35 2005
@@ -38,6 +38,7 @@
 import org.apache.jackrabbit.core.state.SharedItemStateManager;
 import org.apache.jackrabbit.core.state.TransactionalItemStateManager;
 import org.apache.jackrabbit.core.util.uuid.UUID;
+import org.apache.jackrabbit.core.util.ReferenceChangeTracker;
 import org.apache.jackrabbit.core.version.GenericVersionSelector;
 import org.apache.jackrabbit.core.version.InternalVersion;
 import org.apache.jackrabbit.core.version.VersionImpl;
@@ -833,6 +834,7 @@
      *                     <li><code>CLONE</code></li>
      *                     <li><code>CLONE_REMOVE_EXISTING</code></li>
      *                     </ul>
+     * @param refTracker   tracks uuid mappings and processed reference properties
      * @return a deep copy of the given node state and its children
      * @throws RepositoryException if an error occurs
      */
@@ -840,7 +842,8 @@
                                     String parentUUID,
                                     ItemStateManager srcStateMgr,
                                     AccessManager srcAccessMgr,
-                                    int flag)
+                                    int flag,
+                                    ReferenceChangeTracker refTracker)
             throws RepositoryException {
 
         NodeState newState;
@@ -851,12 +854,12 @@
             boolean referenceable = ent.includesNodeType(MIX_REFERENCEABLE);
             switch (flag) {
                 case COPY:
-                    /**
-                     * todo FIXME check mix:referenceable
-                     * make sure that copied reference properties are
-                     * refering to new uuid
-                     */
+                    // always create new uuid
                     uuid = UUID.randomUUID().toString();    // create new version 4 uuid
+                    if (referenceable) {
+                        // remember uuid mapping
+                        refTracker.mappedUUID(srcState.getUUID(), uuid);
+                    }
                     break;
                 case CLONE:
                     if (!referenceable) {
@@ -864,6 +867,7 @@
                         uuid = UUID.randomUUID().toString();    // create new version 4 uuid
                         break;
                     }
+                    // use same uuid as source node
                     uuid = srcState.getUUID();
                     id = new NodeId(uuid);
                     if (stateMgr.hasItemState(id)) {
@@ -877,6 +881,7 @@
                         uuid = UUID.randomUUID().toString();    // create new version 4 uuid
                         break;
                     }
+                    // use same uuid as source node
                     uuid = srcState.getUUID();
                     id = new NodeId(uuid);
                     if (stateMgr.hasItemState(id)) {
@@ -908,7 +913,7 @@
                 NodeState srcChildState = (NodeState) srcStateMgr.getItemState(nodeId);
                 // recursive copying of child node
                 NodeState newChildState = copyNodeState(srcChildState, uuid,
-                        srcStateMgr, srcAccessMgr, flag);
+                        srcStateMgr, srcAccessMgr, flag, refTracker);
                 // store new child node
                 stateMgr.store(newChildState);
                 // add new child node entry to new node
@@ -926,6 +931,9 @@
                         (PropertyState) srcStateMgr.getItemState(propId);
                 PropertyState newChildState =
                         copyPropertyState(srcChildState, uuid, entry.getName());
+                if (newChildState.getType() == PropertyType.REFERENCE) {
+                    refTracker.processedReference(newChildState);
+                }
                 // store new property
                 stateMgr.store(newChildState);
                 // add new property entry to new node
@@ -1071,9 +1079,11 @@
         try {
             stateMgr.edit();
 
+            ReferenceChangeTracker refTracker = new ReferenceChangeTracker();
+
             // create deep copy of source node state
             NodeState newState = copyNodeState(srcState, destParentState.getUUID(),
-                    srcWsp.getItemStateManager(), srcAccessMgr, flag);
+                    srcWsp.getItemStateManager(), srcAccessMgr, flag, refTracker);
 
             // add to new parent
             destParentState.addChildNodeEntry(destName.getName(), newState.getUUID());
@@ -1084,6 +1094,37 @@
                             srcState.getNodeTypeName(), destParentState);
             newState.setDefinitionId(new NodeDefId(newNodeDef));
 
+            // adjust references that refer to uuid's which have been mapped to
+            // newly generated uuid's on copy/clone
+            Iterator iter = refTracker.getProcessedReferences();
+            while (iter.hasNext()) {
+                PropertyState prop = (PropertyState) iter.next();
+                // being paranoid...
+                if (prop.getType() != PropertyType.REFERENCE) {
+                    continue;
+                }
+                boolean modified = false;
+                InternalValue[] values = prop.getValues();
+                InternalValue[] newVals = new InternalValue[values.length];
+                for (int i = 0; i < values.length; i++) {
+                    InternalValue val = values[i];
+                    String original = ((UUID) val.internalValue()).toString();
+                    String adjusted = refTracker.getMappedUUID(original);
+                    if (adjusted != null) {
+                        newVals[i] = InternalValue.create(UUID.fromString(adjusted));
+                        modified = true;
+                    } else {
+                        // reference doesn't need adjusting, just copy old value
+                        newVals[i] = val;
+                    }
+                }
+                if (modified) {
+                    prop.setValues(newVals);
+                    stateMgr.store(prop);
+                }
+            }
+            refTracker.clear();
+
             // store states
             stateMgr.store(newState);
             stateMgr.store(destParentState);
@@ -1175,8 +1216,6 @@
             log.debug(msg);
             throw new RepositoryException(msg);
         }
-
-        // @todo re-implement Workspace#clone (respect new removeExisting flag, etc)
 
         // check authorization for specified workspace
         if (!session.getAccessManager().canAccess(srcWorkspace)) {

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ReferenceChangeTracker.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ReferenceChangeTracker.java?view=auto&rev=158489
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ReferenceChangeTracker.java
(added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ReferenceChangeTracker.java
Mon Mar 21 09:50:35 2005
@@ -0,0 +1,95 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Simple helper class that can be used to keep track of uuid mappings
+ * (e.g. if the uuid of an imported or copied node is mapped to a new uuid)
+ * and processed (e.g. imported or copied) reference properties that might
+ * need correcting depending on the uuid mappings.
+ */
+public class ReferenceChangeTracker {
+    /**
+     * mapping <original uuid> to <new uuid> of mix:referenceable nodes
+     */
+    private final HashMap uuidMap = new HashMap();
+    /**
+     * list of processed reference properties that might need correcting
+     */
+    private final ArrayList references = new ArrayList();
+
+    /**
+     * Creates a new instance.
+     */
+    public ReferenceChangeTracker() {
+    }
+
+    /**
+     * Resets all internal state.
+     */
+    public void clear() {
+        uuidMap.clear();
+        references.clear();
+    }
+
+    /**
+     * Store the given uuid mapping for later lookup using
+     * <code>{@link #getMappedUUID(String)}</code>.
+     *
+     * @param oldUUID old uuid
+     * @param newUUID new uuid
+     */
+    public void mappedUUID(String oldUUID, String newUUID) {
+        uuidMap.put(oldUUID, newUUID);
+    }
+
+    /**
+     * Store the given reference property for later retrieval using
+     * <code>{@link #getProcessedReferences()}</code>.
+     *
+     * @param refProp reference property
+     */
+    public void processedReference(Object refProp) {
+        references.add(refProp);
+    }
+
+    /**
+     * Returns the new UUID to which <code>oldUUID</code> has been mapped
+     * or <code>null</code> if no such mapping exists.
+     *
+     * @param oldUUID old uuid
+     * @return mapped new uuid or <code>null</code> if no such mapping exists
+     * @see #mappedUUID(String, String)
+     */
+    public String getMappedUUID(String oldUUID) {
+        return (String) uuidMap.get(oldUUID);
+    }
+
+    /**
+     * Returns an iterator over all processed reference properties.
+     *
+     * @return an iterator over all processed reference properties
+     * @see #processedReference(Object)
+     */
+    public Iterator getProcessedReferences() {
+        return references.iterator();
+    }
+}

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

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java?view=diff&r1=158488&r2=158489
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java
Mon Mar 21 09:50:35 2005
@@ -21,6 +21,7 @@
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.QName;
 import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.util.ReferenceChangeTracker;
 import org.apache.log4j.Logger;
 
 import javax.jcr.ItemExistsException;
@@ -54,13 +55,10 @@
     private Stack parents;
 
     /**
-     * mapping <original uuid> to <new uuid> of mix:referenceable nodes
+     * helper object that keeps track of remapped uuid's and imported reference
+     * properties that might need correcting depending on the uuid mappings
      */
-    private final HashMap uuidMap;
-    /**
-     * list of imported reference properties that might need correcting
-     */
-    private final ArrayList references;
+    private final ReferenceChangeTracker refTracker;
 
     public SessionImporter(NodeImpl importTargetNode,
                            SessionImpl session,
@@ -69,8 +67,7 @@
         this.session = session;
         this.uuidBehavior = uuidBehavior;
 
-        uuidMap = new HashMap();
-        references = new ArrayList();
+        refTracker = new ReferenceChangeTracker();
 
         parents = new Stack();
         parents.push(importTargetNode);
@@ -105,7 +102,7 @@
                     nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), null);
             // remember uuid mapping
             if (node.isNodeType(Constants.MIX_REFERENCEABLE)) {
-                uuidMap.put(nodeInfo.getUUID(), node.getUUID());
+                refTracker.mappedUUID(nodeInfo.getUUID(), node.getUUID());
             }
         } else if (uuidBehavior == IMPORT_UUID_COLLISION_THROW) {
             String msg = "a node with uuid " + nodeInfo.getUUID() + " already exists!";
@@ -256,7 +253,7 @@
             }
             if (type == PropertyType.REFERENCE) {
                 // store reference for later resolution
-                references.add(node.getProperty(propName));
+                refTracker.processedReference(node.getProperty(propName));
             }
         }
 
@@ -276,9 +273,9 @@
     public void end() throws RepositoryException {
         /**
          * adjust references that refer to uuid's which have been mapped to
-         * newly gererated uuid's on import
+         * newly generated uuid's on import
          */
-        Iterator iter = references.iterator();
+        Iterator iter = refTracker.getProcessedReferences();
         while (iter.hasNext()) {
             Property prop = (Property) iter.next();
             // being paranoid...
@@ -291,7 +288,7 @@
                 for (int i = 0; i < values.length; i++) {
                     Value val = values[i];
                     String original = val.getString();
-                    String adjusted = (String) uuidMap.get(original);
+                    String adjusted = refTracker.getMappedUUID(original);
                     if (adjusted != null) {
                         newVals[i] = new ReferenceValue(session.getNodeByUUID(adjusted));
                     } else {
@@ -303,11 +300,12 @@
             } else {
                 Value val = prop.getValue();
                 String original = val.getString();
-                String adjusted = (String) uuidMap.get(original);
+                String adjusted = refTracker.getMappedUUID(original);
                 if (adjusted != null) {
                     prop.setValue(session.getNodeByUUID(adjusted));
                 }
             }
         }
+        refTracker.clear();
     }
 }



Mime
View raw message