jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1535820 - in /jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade: JackrabbitNodeState.java PersistenceCopier.java RepositoryUpgrade.java
Date Fri, 25 Oct 2013 19:07:22 GMT
Author: jukka
Date: Fri Oct 25 19:07:21 2013
New Revision: 1535820

URL: http://svn.apache.org/r1535820
Log:
OAK-806: Content migration from Jackrabbit to Oak

Use the NodeState abtraction for content migration

Added:
    jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/JackrabbitNodeState.java
      - copied, changed from r1535777, jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistenceCopier.java
Removed:
    jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistenceCopier.java
Modified:
    jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java

Copied: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/JackrabbitNodeState.java
(from r1535777, jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistenceCopier.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/JackrabbitNodeState.java?p2=jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/JackrabbitNodeState.java&p1=jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistenceCopier.java&r1=1535777&r2=1535820&rev=1535820&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistenceCopier.java
(original)
+++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/JackrabbitNodeState.java
Fri Oct 25 19:07:21 2013
@@ -16,16 +16,15 @@
  */
 package org.apache.jackrabbit.oak.upgrade;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Lists.newArrayListWithCapacity;
-import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
-import static org.apache.jackrabbit.oak.api.Type.NAME;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.math.BigDecimal;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.PropertyType;
@@ -41,18 +40,17 @@ import org.apache.jackrabbit.core.state.
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.memory.AbstractBlob;
+import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 
-/**
- * Tool for copying item states from a Jackrabbit persistence manager to
- * an Oak node builder. Used for migrating repository content from Jackrabbit
- * to Oak.
- */
-class PersistenceCopier {
+class JackrabbitNodeState extends AbstractNodeState {
 
     /**
      * Source persistence manager.
@@ -64,149 +62,149 @@ class PersistenceCopier {
      */
     private final NamespaceRegistry registry;
 
-    /**
-     * Target node store.
-     */
-    private final NodeStore store;
+    private final NodeId id;
 
-    /**
-     * Identifiers of the nodes that have already been copied or that
-     * should explicitly not be copied. Used to avoid duplicate copies
-     * of shareable nodes and to avoid trying to copy "missing" nodes
-     * like the virtual "/jcr:system" node.
-     */
-    private final Set<NodeId> exclude = new HashSet<NodeId>();
+    private NodeState state = null;
 
-    public PersistenceCopier(
+    JackrabbitNodeState(
             PersistenceManager source, NamespaceRegistry registry,
-            NodeStore store) {
+            NodeId id) {
         this.source = source;
         this.registry = registry;
-        this.store = store;
+        this.id = id;
     }
 
-    private String getOakName(Name name) throws RepositoryException {
-        String uri = name.getNamespaceURI();
-        String local = name.getLocalName();
-        if (uri == null || uri.isEmpty()) {
-            return local;
-        } else {
-            return registry.getPrefix(uri) + ":" + local;
+    private NodeState getState() {
+        if (state == null) {
+            try {
+                state = source.load(id);
+            } catch (ItemStateException e) {
+                throw new IllegalStateException(e);
+            }
         }
+        return state;
     }
 
-    private String getOakPath(Path path) throws RepositoryException {
-        StringBuilder builder = new StringBuilder();
-        for (Path.Element element : path.getElements()) {
-            if (builder.length() > 1
-                    || (builder.length() == 1 && !"/".equals(builder.toString())))
{
-                builder.append('/');
-            }
-            if (element.denotesRoot()) {
-                builder.append('/');
-            } else if (element.denotesIdentifier()) {
-                builder.append('[').append(element.getIdentifier()).append(']');
-            } else if (element.denotesName()) {
-                builder.append(getOakName(element.getName()));
-                if (element.getIndex() >= Path.INDEX_DEFAULT) {
-                    builder.append('[').append(element.getIndex()).append(']');
+    //---------------------------------------------------------< NodeState >--
+
+    @Override
+    public boolean exists() {
+        return true;
+    }
+
+    @Override
+    public Iterable<org.apache.jackrabbit.oak.api.PropertyState> getProperties() {
+        List<org.apache.jackrabbit.oak.api.PropertyState> properties = newArrayList();
+        for (Name name : getState().getPropertyNames()) {
+            try {
+                PropertyState property = source.load(new PropertyId(id, name));
+                int type = property.getType();
+                if (property.isMultiValued()) {
+                    properties.add(createProperty(
+                            createName(name), type, property.getValues()));
+                } else {
+                    properties.add(createProperty(
+                            createName(name), type, property.getValues()[0]));
                 }
-            } else if (element.denotesParent()) {
-                builder.append("..");
-            } else if (element.denotesCurrent()) {
-                builder.append('.');
-            } else {
-                throw new RepositoryException(
-                        "Unknown path element: " + element);
+            } catch (Exception e) {
+                throw new IllegalStateException(e);
             }
         }
-        return builder.toString();
+        return properties;
     }
 
-    /**
-     * Explicitly exclude the identified node from being copied. Used for
-     * excluding virtual nodes like "/jcr:system" from the copy process.
-     *
-     * @param id identifier of the node to be excluded
-     */
-    public void excludeNode(NodeId id) {
-        exclude.add(id);
+    @Override
+    public org.apache.jackrabbit.oak.spi.state.NodeState getChildNode(String name) {
+        for (MemoryChildNodeEntry entry : getChildNodeEntries()) {
+            if (name.equals(entry.getName())) {
+                return entry.getNodeState();
+            }
+        }
+        return EmptyNodeState.MISSING_NODE;
     }
 
-    /**
-     * Recursively copies the identified node and all its descendants.
-     * Explicitly excluded nodes and nodes that have already been copied
-     * are automatically skipped.
-     *
-     * @param id identifier of the node to be copied
-     * @throws RepositoryException if the copy operation fails
-     */
-    public void copy(NodeId id, NodeBuilder builder)
-            throws RepositoryException, IOException {
-        try {
-            NodeState node = source.load(id);
-            copy(node, builder);
-
-            for (ChildNodeEntry entry : node.getChildNodeEntries()) {
-                NodeId childId = entry.getId();
-                if (!exclude.contains(childId)) {
-                    exclude.add(childId);
-                    String name = getOakName(entry.getName());
-                    copy(childId, builder.child(name));
-                    exclude.remove(childId);
+    @Override
+    public Iterable<MemoryChildNodeEntry> getChildNodeEntries() {
+        List<MemoryChildNodeEntry> entries = newArrayList();
+        for (ChildNodeEntry entry : getState().getChildNodeEntries()) {
+            try {
+                String name = createName(entry.getName());
+                int index = entry.getIndex();
+                if (index > 1) {
+                    name = name + '[' + index + ']';
                 }
+
+                JackrabbitNodeState state = new JackrabbitNodeState(
+                        source, registry, entry.getId());
+
+                entries.add(new MemoryChildNodeEntry(name, state));
+            } catch (RepositoryException e) {
+                throw new IllegalStateException(e);
             }
-        } catch (ItemStateException e) {
-            throw new RepositoryException("Unable to copy " + id, e);
         }
+        return entries;
     }
 
-    /**
-     * Copies the given node state and all associated property states
-     * to the node builder.
-     *
-     * @param sourceNode source node state
-     * @throws RepositoryException if the copy operation fails
-     */
-    private void copy(NodeState sourceNode, NodeBuilder builder)
-            throws RepositoryException, IOException, ItemStateException {
-        // Copy the node state
-        String primary = getOakName(sourceNode.getNodeTypeName());
-        builder.setProperty(JCR_PRIMARYTYPE, primary, NAME);
-
-        Set<Name> mixinNames = sourceNode.getMixinTypeNames();
-        if (!mixinNames.isEmpty()) {
-            List<String> mixins = newArrayListWithCapacity(mixinNames.size());
-            for (Name name : mixinNames) {
-                mixins.add(getOakName(name));
-            }
-            builder.setProperty(JCR_MIXINTYPES, mixins, Type.NAMES);
-        }
+    @Override
+    public NodeBuilder builder() {
+        return new MemoryNodeBuilder(this);
+    }
 
-        // Copy all associated property states
-        for (Name name : sourceNode.getPropertyNames()) {
-            PropertyId id = new PropertyId(sourceNode.getNodeId(), name);
-            PropertyState sourceState = source.load(id);
-
-            InternalValue[] values = sourceState.getValues();
-            int type = sourceState.getType();
-            String oakName = getOakName(name);
-            if (sourceState.isMultiValued() || values.length != 1) {
-                builder.setProperty(getProperty(oakName, values, type));
-            } else {
-                builder.setProperty(getProperty(oakName, values[0], type));
-            }
+    //-----------------------------------------------------------< private >--
+
+    private org.apache.jackrabbit.oak.api.PropertyState createProperty(
+            String name, int type, InternalValue value)
+            throws RepositoryException, IOException {
+        switch (type) {
+        case PropertyType.BINARY:
+            return PropertyStates.createProperty(
+                    name, createBlob(value), Type.BINARY);
+        case PropertyType.BOOLEAN:
+            return PropertyStates.createProperty(
+                    name, value.getBoolean(), Type.BOOLEAN);
+        case PropertyType.DATE:
+            return PropertyStates.createProperty(
+                    name, value.getString(), Type.DATE);
+        case PropertyType.DECIMAL:
+            return PropertyStates.createProperty(
+                    name, value.getDecimal(), Type.DECIMAL);
+        case PropertyType.DOUBLE:
+            return PropertyStates.createProperty(
+                    name, value.getDouble(), Type.DOUBLE);
+        case PropertyType.LONG:
+            return PropertyStates.createProperty(
+                    name, value.getLong(), Type.LONG);
+        case PropertyType.NAME:
+            return PropertyStates.createProperty(
+                    name, createName(value.getName()), Type.NAME);
+        case PropertyType.PATH:
+            return PropertyStates.createProperty(
+                    name, createPath(value.getPath()), Type.PATH);
+        case PropertyType.REFERENCE:
+            return PropertyStates.createProperty(
+                    name, value.getNodeId().toString(), Type.REFERENCE);
+        case PropertyType.STRING:
+            return PropertyStates.createProperty(
+                    name, value.getString(), Type.STRING);
+        case PropertyType.URI:
+            return PropertyStates.createProperty(
+                    name, value.getURI().toString(), Type.URI);
+        case PropertyType.WEAKREFERENCE:
+            return PropertyStates.createProperty(
+                    name, value.getNodeId().toString(), Type.WEAKREFERENCE);
+        default:
+            throw new RepositoryException("Unknown value type: " + type);
         }
     }
 
-    private org.apache.jackrabbit.oak.api.PropertyState getProperty(
-            String name, InternalValue[] values, int type)
+    private org.apache.jackrabbit.oak.api.PropertyState createProperty(
+            String name, int type, InternalValue[] values)
             throws RepositoryException, IOException {
         switch (type) {
         case PropertyType.BINARY:
             List<Blob> binaries = newArrayListWithCapacity(values.length);
             for (InternalValue value : values) {
-                binaries.add(store.createBlob(value.getStream()));
+                binaries.add(createBlob(value));
             }
             return PropertyStates.createProperty(name, binaries, Type.BINARIES);
         case PropertyType.BOOLEAN:
@@ -242,13 +240,13 @@ class PersistenceCopier {
         case PropertyType.NAME:
             List<String> names = newArrayListWithCapacity(values.length);
             for (InternalValue value : values) {
-                names.add(getOakName(value.getName()));
+                names.add(createName(value.getName()));
             }
             return PropertyStates.createProperty(name, names, Type.NAMES);
         case PropertyType.PATH:
             List<String> paths = newArrayListWithCapacity(values.length);
             for (InternalValue value : values) {
-                paths.add(getOakPath(value.getPath()));
+                paths.add(createPath(value.getPath()));
             }
             return PropertyStates.createProperty(name, paths, Type.PATHS);
         case PropertyType.REFERENCE:
@@ -280,49 +278,64 @@ class PersistenceCopier {
         }
     }
 
-    private org.apache.jackrabbit.oak.api.PropertyState getProperty(
-            String name, InternalValue value, int type)
-            throws RepositoryException, IOException {
-        switch (type) {
-        case PropertyType.BINARY:
-            return PropertyStates.createProperty(
-                    name, store.createBlob(value.getStream()), Type.BINARY);
-        case PropertyType.BOOLEAN:
-            return PropertyStates.createProperty(
-                    name, value.getBoolean(), Type.BOOLEAN);
-        case PropertyType.DATE:
-            return PropertyStates.createProperty(
-                    name, value.getString(), Type.DATE);
-        case PropertyType.DECIMAL:
-            return PropertyStates.createProperty(
-                    name, value.getDecimal(), Type.DECIMAL);
-        case PropertyType.DOUBLE:
-            return PropertyStates.createProperty(
-                    name, value.getDouble(), Type.DOUBLE);
-        case PropertyType.LONG:
-            return PropertyStates.createProperty(
-                    name, value.getLong(), Type.LONG);
-        case PropertyType.NAME:
-            return PropertyStates.createProperty(
-                    name, getOakName(value.getName()), Type.NAME);
-        case PropertyType.PATH:
-            return PropertyStates.createProperty(
-                    name, getOakPath(value.getPath()), Type.PATH);
-        case PropertyType.REFERENCE:
-            return PropertyStates.createProperty(
-                    name, value.getNodeId().toString(), Type.REFERENCE);
-        case PropertyType.STRING:
-            return PropertyStates.createProperty(
-                    name, value.getString(), Type.STRING);
-        case PropertyType.URI:
-            return PropertyStates.createProperty(
-                    name, value.getURI().toString(), Type.URI);
-        case PropertyType.WEAKREFERENCE:
-            return PropertyStates.createProperty(
-                    name, value.getNodeId().toString(), Type.WEAKREFERENCE);
-        default:
-            throw new RepositoryException("Unknown value type: " + type);
+    private Blob createBlob(final InternalValue value) {
+        checkArgument(checkNotNull(value).getType() == PropertyType.BINARY);
+        return new AbstractBlob() {
+            @Override
+            public long length() {
+                try {
+                    return value.getLength();
+                } catch (RepositoryException e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+            @Override
+            public InputStream getNewStream() {
+                try {
+                    return value.getStream();
+                } catch (RepositoryException e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+        };
+    }
+
+    private String createName(Name name) throws RepositoryException {
+        String uri = name.getNamespaceURI();
+        String local = name.getLocalName();
+        if (uri == null || uri.isEmpty()) {
+            return local;
+        } else {
+            return registry.getPrefix(uri) + ":" + local;
         }
     }
 
+    private String createPath(Path path) throws RepositoryException {
+        StringBuilder builder = new StringBuilder();
+        for (Path.Element element : path.getElements()) {
+            if (builder.length() > 1
+                    || (builder.length() == 1 && !"/".equals(builder.toString())))
{
+                builder.append('/');
+            }
+            if (element.denotesRoot()) {
+                builder.append('/');
+            } else if (element.denotesIdentifier()) {
+                builder.append('[').append(element.getIdentifier()).append(']');
+            } else if (element.denotesName()) {
+                builder.append(createName(element.getName()));
+                if (element.getIndex() >= Path.INDEX_DEFAULT) {
+                    builder.append('[').append(element.getIndex()).append(']');
+                }
+            } else if (element.denotesParent()) {
+                builder.append("..");
+            } else if (element.denotesCurrent()) {
+                builder.append('.');
+            } else {
+                throw new RepositoryException(
+                        "Unknown path element: " + element);
+            }
+        }
+        return builder.toString();
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java?rev=1535820&r1=1535819&r2=1535820&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
(original)
+++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
Fri Oct 25 19:07:21 2013
@@ -44,6 +44,9 @@ import static org.apache.jackrabbit.JcrC
 import static org.apache.jackrabbit.JcrConstants.NT_CHILDNODEDEFINITION;
 import static org.apache.jackrabbit.JcrConstants.NT_NODETYPE;
 import static org.apache.jackrabbit.JcrConstants.NT_PROPERTYDEFINITION;
+import static org.apache.jackrabbit.core.RepositoryImpl.ACTIVITIES_NODE_ID;
+import static org.apache.jackrabbit.core.RepositoryImpl.ROOT_NODE_ID;
+import static org.apache.jackrabbit.core.RepositoryImpl.VERSION_STORAGE_NODE_ID;
 import static org.apache.jackrabbit.oak.api.Type.NAME;
 import static org.apache.jackrabbit.oak.api.Type.NAMES;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
@@ -63,21 +66,26 @@ import java.util.Map;
 import java.util.Properties;
 
 import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
 import javax.jcr.RepositoryException;
 import javax.jcr.version.OnParentVersionAction;
 
+import org.apache.jackrabbit.core.NamespaceRegistryImpl;
 import org.apache.jackrabbit.core.RepositoryContext;
-import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
 import org.apache.jackrabbit.core.fs.FileSystem;
 import org.apache.jackrabbit.core.fs.FileSystemException;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.persistence.PersistenceManager;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.name.Namespaces;
 import org.apache.jackrabbit.oak.plugins.nodetype.RegistrationEditorProvider;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.QItemDefinition;
@@ -416,15 +424,18 @@ public class RepositoryUpgrade {
             NodeBuilder root, Map<Integer, String> idxToPrefix)
             throws RepositoryException, IOException {
         logger.info("Copying version histories");
-        NodeBuilder system = root.child(JCR_SYSTEM);
-        NodeBuilder versionStorage = system.child(JCR_VERSIONSTORAGE);
-        NodeBuilder activities = system.child("jcr:activities");
 
-        PersistenceCopier copier = new PersistenceCopier(
-                source.getInternalVersionManager().getPersistenceManager(),
-                source.getNamespaceRegistry(), target);
-        copier.copy(RepositoryImpl.VERSION_STORAGE_NODE_ID, versionStorage);
-        copier.copy(RepositoryImpl.ACTIVITIES_NODE_ID, activities);
+        PersistenceManager pm =
+                source.getInternalVersionManager().getPersistenceManager();
+        NamespaceRegistry nr =source.getNamespaceRegistry();
+
+        NodeBuilder system = root.child(JCR_SYSTEM);
+        system.setChildNode(
+                JCR_VERSIONSTORAGE,
+                new JackrabbitNodeState(pm, nr, VERSION_STORAGE_NODE_ID));
+        system.setChildNode(
+                "jcr:activities",
+                new JackrabbitNodeState(pm, nr, ACTIVITIES_NODE_ID));
     }   
 
     private void copyWorkspaces(
@@ -435,11 +446,21 @@ public class RepositoryUpgrade {
         // Copy all the default workspace content
         RepositoryConfig config = source.getRepositoryConfig();
         String name = config.getDefaultWorkspaceName();
-        PersistenceCopier copier = new PersistenceCopier(
-                source.getWorkspaceInfo(name).getPersistenceManager(),
-                source.getNamespaceRegistry(), target);
-        copier.excludeNode(RepositoryImpl.SYSTEM_ROOT_NODE_ID);
-        copier.copy(RepositoryImpl.ROOT_NODE_ID, root);
+
+        PersistenceManager pm =
+                source.getWorkspaceInfo(name).getPersistenceManager();
+        NamespaceRegistryImpl nr = source.getNamespaceRegistry();
+
+        NodeState state = new JackrabbitNodeState(pm, nr, ROOT_NODE_ID);
+        for (PropertyState property : state.getProperties()) {
+            root.setProperty(property);
+        }
+        for (ChildNodeEntry child : state.getChildNodeEntries()) {
+            String childName = child.getName();
+            if (!JCR_SYSTEM.equals(childName)) {
+                root.setChildNode(childName, child.getNodeState());
+            }
+        }
 
         // TODO: Copy all the active open-scoped locks
     }



Mime
View raw message