You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by un...@apache.org on 2012/04/23 17:16:23 UTC

svn commit: r1329278 [2/2] - in /rave/sandbox/content-services: ./ demo-portal/ rave-jcr-config/ rave-jcr-config/src/ rave-jcr-config/src/main/ rave-jcr-config/src/main/java/ rave-jcr-config/src/main/java/org/ rave-jcr-config/src/main/java/org/apache/ ...

Added: rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/importing/ContentImporterTest.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/importing/ContentImporterTest.java?rev=1329278&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/importing/ContentImporterTest.java (added)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/importing/ContentImporterTest.java Mon Apr 23 15:16:22 2012
@@ -0,0 +1,449 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.jcr.importing;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+public class ContentImporterTest extends AbstractJCRTest {
+
+    private Session session;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        session = testRootNode.getSession();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        session.refresh(false);
+    }
+
+    // simple node import
+
+    public void testImportNode() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\" }";
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        assertTrue(testRootNode.hasNode("foo"));
+        assertEquals("nt:unstructured", testRootNode.getNode("foo").getPrimaryNodeType().getName());
+    }
+
+    public void testImportNodeWithSubnode() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : {} }";
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        assertTrue(testRootNode.hasNode("foo"));
+        assertTrue(testRootNode.getNode("foo").hasNode("bar"));
+    }
+
+    public void testImportNodeWithPrimaryType() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:primaryType\" : \"nt:folder\" }";
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        assertTrue(testRootNode.hasNode("foo"));
+        assertEquals("nt:folder", testRootNode.getNode("foo").getPrimaryNodeType().getName());
+    }
+
+    public void testImportNodeWithMixin() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:mixinTypes\" : [ \"mix:referenceable\" ] }";
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        assertTrue(testRootNode.hasNode("foo"));
+        final Node foo = testRootNode.getNode("foo");
+        assertEquals("nt:unstructured", foo.getPrimaryNodeType().getName());
+        final NodeType[] mixinNodeTypes = foo.getMixinNodeTypes();
+        assertEquals(1, mixinNodeTypes.length);
+        assertEquals("mix:referenceable", mixinNodeTypes[0].getName());
+    }
+
+    public void testImportNodeWithMixins() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:mixinTypes\" : [ \"mix:referenceable\", \"mix:lockable\" ] }";
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        assertTrue(testRootNode.hasNode("foo"));
+        final Node foo = testRootNode.getNode("foo");
+        assertEquals("nt:unstructured", foo.getPrimaryNodeType().getName());
+        final NodeType[] mixinNodeTypes = foo.getMixinNodeTypes();
+        assertEquals(2, mixinNodeTypes.length);
+        assertEquals("mix:referenceable", mixinNodeTypes[0].getName());
+        assertEquals("mix:lockable", mixinNodeTypes[1].getName());
+    }
+
+    // single and multi-valued property import of various types
+
+    public void testImportStringProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : \"qux\" }";
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        assertTrue(testRootNode.getNode("foo").hasProperty("bar"));
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.STRING, property.getType());
+        assertEquals("qux", property.getString());
+    }
+
+    public void testImportMultivaluedStringProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : [ \"qux\", \"quux\" ] }";
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        assertTrue(testRootNode.getNode("foo").hasProperty("bar"));
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.STRING, property.getType());
+        final Value[] values = property.getValues();
+        assertEquals(2, values.length);
+        assertEquals("qux", values[0].getString());
+        assertEquals("quux", values[1].getString());
+    }
+
+    public void testImportLongProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : 1 }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.LONG, property.getType());
+        assertEquals(1l, property.getLong());
+    }
+
+    public void testImportMultivaluedLongProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : [ 1, 2 ] }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.LONG, property.getType());
+        final Value[] values = property.getValues();
+        assertEquals(1l, values[0].getLong());
+        assertEquals(2l, values[1].getLong());
+    }
+
+    public void testImportDoubleProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : 1.0 }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.DOUBLE, property.getType());
+        assertEquals(1.0d, property.getDouble());
+    }
+
+    public void testImportMultivaluedDoubleProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : [ 1.0, 2.0 ] }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.DOUBLE, property.getType());
+        final Value[] values = property.getValues();
+        assertEquals(1.0d, values[0].getDouble());
+        assertEquals(2.0d, values[1].getDouble());
+    }
+
+    public void testImportBooleanProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : true }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.BOOLEAN, property.getType());
+        assertEquals(true, property.getBoolean());
+    }
+
+    public void testImportMultivaluedBooleanProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : [ true, false ] }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.BOOLEAN, property.getType());
+        final Value[] values = property.getValues();
+        assertEquals(true, values[0].getBoolean());
+        assertEquals(false, values[1].getBoolean());
+    }
+
+    // immediate reference type property import when referenced property is already present
+
+    public void testImportReferenceProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:reference:bar\" : \"" + testRootNode.getPath() + "/foo/bar" + "\" }";
+
+        final Node foo = testRootNode.addNode("foo");
+        foo.addNode("bar").addMixin("mix:referenceable");
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.MERGE));
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.REFERENCE, property.getType());
+        assertEquals(testRootNode.getNode("foo").getNode("bar").getPath(), property.getNode().getPath());
+    }
+
+    public void testImportMultiValuedReferenceProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:reference:barbaz\" : [ \"" + testRootNode.getPath() + "/foo/bar\", \"" + testRootNode.getPath() + "/foo/baz\" ] }";
+
+        final Node foo = testRootNode.addNode("foo");
+        foo.addNode("bar").addMixin("mix:referenceable");
+        foo.addNode("baz").addMixin("mix:referenceable");
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.MERGE));
+
+        final Value[] values = testRootNode.getNode("foo").getProperty("barbaz").getValues();
+        assertEquals(2, values.length);
+        for (Value value : values) {
+            assertEquals(PropertyType.REFERENCE, value.getType());
+            final String path = session.getNodeByIdentifier(value.getString()).getPath();
+            assertTrue(path.equals(testRootNode.getNode("foo/bar").getPath()) || path.equals(testRootNode.getNode("foo/baz").getPath()));
+        }
+    }
+
+    // delayed reference type property import when referenced property is in imported file
+
+    public void testImportDelayedReferenceProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:reference:bar\" : \"" + testRootNode.getPath() + "/foo/bar" + "\"," +
+                " \"bar\" : { \"jcr:mixinTypes\" :  [ \"mix:referenceable\" ] } }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.REFERENCE, property.getType());
+        assertEquals(testRootNode.getNode("foo").getNode("bar").getPath(), property.getNode().getPath());
+    }
+
+    public void testImportDelayedMultiValuedReferenceProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:reference:barbaz\" : [ \"" + testRootNode.getPath() + "/foo/bar\", \"" + testRootNode.getPath() + "/foo/baz\" ]," +
+                " \"bar\" : { \"jcr:mixinTypes\" :  [ \"mix:referenceable\" ] }," +
+                " \"baz\" : { \"jcr:mixinTypes\" :  [ \"mix:referenceable\" ] } }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Value[] values = testRootNode.getNode("foo").getProperty("barbaz").getValues();
+        assertEquals(2, values.length);
+        for (Value value : values) {
+            assertEquals(PropertyType.REFERENCE, value.getType());
+            final String path = session.getNodeByIdentifier(value.getString()).getPath();
+            assertTrue(path.equals(testRootNode.getNode("foo/bar").getPath()) || path.equals(testRootNode.getNode("foo/baz").getPath()));
+        }
+    }
+
+    public void testImportPathProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:path:bar\" : \"/qux/quux\" }";
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.PATH, property.getType());
+        assertEquals("/qux/quux", property.getString());
+    }
+
+    public void testImportMultivaluedPathProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:path:bar\" : [ \"/qux/quux\", \"baz\" ] }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.PATH, property.getType());
+
+        final Value[] values = property.getValues();
+        assertEquals(2, values.length);
+        assertEquals("/qux/quux", values[0].getString());
+        assertEquals("baz", values[1].getString());
+    }
+
+    public void testImportNameProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:name:bar\" : \"qux\" }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+
+        assertEquals(PropertyType.NAME, property.getType());
+        assertEquals("qux", property.getString());
+    }
+
+    public void testImportMultivaluedNameProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:name:bar\" : [ \"qux\", \"quux\" ] }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.NAME, property.getType());
+
+        final Value[] values = property.getValues();
+        assertEquals(2, values.length);
+        assertEquals("qux", values[0].getString());
+        assertEquals("quux", values[1].getString());
+    }
+
+    public void testImportUriProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:uri:bar\" : \"qux\" }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+
+        assertEquals(PropertyType.URI, property.getType());
+        assertEquals("qux", property.getString());
+    }
+
+    public void testImportMultivaluedUriProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:uri:bar\" : [ \"qux\", \"quux\" ] }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.URI, property.getType());
+
+        final Value[] values = property.getValues();
+        assertEquals(2, values.length);
+        assertEquals("qux", values[0].getString());
+        assertEquals("quux", values[1].getString());
+    }
+
+    public void testImportDateProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : \"2012-04-19T15:32:34.775+0200\" }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+
+        assertEquals(PropertyType.DATE, property.getType());
+    }
+
+    public void testImportMultivaluedDateProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : [ \"2012-04-19T15:32:34.775+0200\", \"2012-04-20T15:32:34.775+0200\" ] }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+        assertEquals(PropertyType.DATE, property.getType());
+
+        final Value[] values = property.getValues();
+        assertEquals(2, values.length);
+    }
+
+    public void testImportBinaryProperty() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:binary:bar\" : \"R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\" }";
+
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, ImportBehavior.DEFAULT_BEHAVIOR);
+
+        final Property property = testRootNode.getNode("foo").getProperty("bar");
+
+        assertEquals(PropertyType.BINARY, property.getType());
+    }
+
+    // various tests with different node behaviors when node already exists
+
+    public void testImportExistingNodeSkip() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:primaryType\" : \"nt:folder\" }";
+        testRootNode.addNode("foo");
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.SKIP));
+        final Node foo = testRootNode.getNode("foo");
+        assertEquals("nt:unstructured", foo.getPrimaryNodeType().getName());
+    }
+
+    public void testImportExistingNodeReplace() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:primaryType\" : \"nt:folder\" }";
+        testRootNode.addNode("foo");
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.REPLACE));
+        assertTrue(testRootNode.hasNode("foo"));
+        final Node foo = testRootNode.getNode("foo");
+        assertEquals("nt:folder", foo.getPrimaryNodeType().getName());
+    }
+
+    public void testImportExistingNodeAdd() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:primaryType\" : \"nt:folder\" }";
+        testRootNode.addNode("foo");
+        final ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.ADD));
+        final NodeIterator iterator = testRootNode.getNodes("foo");
+        assertEquals(2, iterator.getSize());
+    }
+
+    public void testImportExistingNodeMerge() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"jcr:mixinTypes\" : [ \"mix:referenceable\" ], \"bar\" : \"quz\" }";
+        Node foo = testRootNode.addNode("foo");
+        foo.setProperty("baz", "qux");
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.MERGE));
+        assertTrue(testRootNode.hasNode("foo"));
+        foo = testRootNode.getNode("foo");
+        assertTrue(foo.hasProperty("bar"));
+        assertTrue(foo.hasProperty("baz"));
+        final NodeType[] mixinNodeTypes = foo.getMixinNodeTypes();
+        assertEquals(1, mixinNodeTypes.length);
+        assertEquals("mix:referenceable", mixinNodeTypes[0].getName());
+    }
+
+    // various tests with different property behaviors when property already exists
+
+    public void testImportExistingNodeMergeAndPropertySkip() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : \"baz\" }";
+        Node foo = testRootNode.addNode("foo");
+        foo.setProperty("bar", "qux");
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.MERGE, ImportBehavior.ImportPropertyBehavior.SKIP));
+        foo = testRootNode.getNode("foo");
+        assertTrue(foo.hasProperty("bar"));
+        assertEquals("qux", foo.getProperty("bar").getString());
+    }
+
+    public void testImportExistingNodeMergeAndPropertyOverride() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : \"baz\" }";
+        Node foo = testRootNode.addNode("foo");
+        foo.setProperty("bar","quz");
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.MERGE, ImportBehavior.ImportPropertyBehavior.OVERRIDE));
+        foo = testRootNode.getNode("foo");
+        assertTrue(foo.hasProperty("bar"));
+        assertEquals("baz", foo.getProperty("bar").getString());
+    }
+
+    public void testImportExistingNodeMergeAndPropertyReplace() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : \"baz\" }";
+        Node foo = testRootNode.addNode("foo");
+        foo.setProperty("bar", 1l);
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.MERGE, ImportBehavior.ImportPropertyBehavior.REPLACE));
+        foo = testRootNode.getNode("foo");
+        assertTrue(foo.hasProperty("bar"));
+        assertEquals("baz", foo.getProperty("bar").getString());
+    }
+
+    public void testImportExistingNodeMergeAndPropertyAppend() throws Exception {
+        final String content = "{ \"jcr:name\" : \"foo\", \"bar\" : [ \"baz\" ] }";
+        Node foo = testRootNode.addNode("foo");
+        foo.setProperty("bar", new String[] { "qux" });
+        ContentImporter contentImporter = new ContentImporter(session);
+        contentImporter.importContent(testRootNode.getPath(), content, new ImportBehavior(ImportBehavior.ImportNodeBehavior.MERGE, ImportBehavior.ImportPropertyBehavior.APPEND));
+        foo = testRootNode.getNode("foo");
+        final Value[] values = foo.getProperty("bar").getValues();
+        assertEquals(2, values.length);
+    }
+
+}

Added: rave/sandbox/content-services/rave-jcr-config/src/test/repository/repository.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/repository/repository.xml?rev=1329278&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/repository/repository.xml (added)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/repository/repository.xml Mon Apr 23 15:16:22 2012
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+  -->
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN" "http://jackrabbit.apache.org/dtd/repository-1.6.dtd">
+<Repository>
+  <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
+
+  <DataStore class="org.apache.jackrabbit.core.data.FileDataStore"/>
+
+  <Security appName="Jackrabbit">
+    <SecurityManager class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager" workspaceName="security"/>
+    <AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager"/>
+    <LoginModule class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule"/>
+  </Security>
+
+  <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default" maxIdleTime="2"/>
+
+  <Workspace name="${wsp.name}">
+    <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
+    <PersistenceManager class="org.apache.jackrabbit.core.persistence.mem.InMemBundlePersistenceManager"/>
+  </Workspace>
+
+  <Versioning rootPath="${rep.home}/version">
+    <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
+    <PersistenceManager class="org.apache.jackrabbit.core.persistence.mem.InMemBundlePersistenceManager"/>
+  </Versioning>
+
+</Repository>

Added: rave/sandbox/content-services/rave-jcr-config/src/test/repository/workspaces/default/workspace.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/repository/workspaces/default/workspace.xml?rev=1329278&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/repository/workspaces/default/workspace.xml (added)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/repository/workspaces/default/workspace.xml Mon Apr 23 15:16:22 2012
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+  -->
+<Workspace name="default">
+  <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
+  <PersistenceManager class="org.apache.jackrabbit.core.persistence.mem.InMemBundlePersistenceManager"/>
+</Workspace>
\ No newline at end of file

Added: rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryHelperPool.properties
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryHelperPool.properties?rev=1329278&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryHelperPool.properties (added)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryHelperPool.properties Mon Apr 23 15:16:22 2012
@@ -0,0 +1,17 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You 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.
+
+# first helper uses default values
+helper.0.=

Added: rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryStubImpl.properties
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryStubImpl.properties?rev=1329278&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryStubImpl.properties (added)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/resources/repositoryStubImpl.properties Mon Apr 23 15:16:22 2012
@@ -0,0 +1,17 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You 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.
+
+# Stub implementation class
+javax.jcr.tck.repository_stub_impl=org.apache.jackrabbit.core.JackrabbitRepositoryStub

Propchange: rave/sandbox/content-services/rave-jcr-service/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Apr 23 15:16:22 2012
@@ -1,3 +1,4 @@
+rave-jcr-service.iml
 .settings
 target
 .classpath