Index: jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/DeepNodeCreatorTest.java
===================================================================
--- jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/DeepNodeCreatorTest.java (revision 0)
+++ jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/DeepNodeCreatorTest.java (revision 0)
@@ -0,0 +1,160 @@
+/*
+ * 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.jackrabbit.util;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.junit.Test;
+
+/** Test the DeepNodeCreator class */
+public class DeepNodeCreatorTest {
+
+ @Test
+ public void testExistingNode() throws Exception {
+ final Mockery mockery = new Mockery();
+ final DeepNodeCreator c = new DeepNodeCreator();
+ final String path = "/foo/bar";
+ final Session s = mockery.mock(Session.class);
+ final Node n = mockery.mock(Node.class);
+
+ mockery.checking(new Expectations() {{
+ allowing(s).itemExists(path);
+ will(returnValue(true));
+
+ allowing(s).getItem(path);
+ will(returnValue(n));
+
+ allowing(n).isNode();
+ will(returnValue(true));
+ }});
+
+ final Node result = c.deepCreateNode(path, s, null);
+ assertTrue("Expecting deepCreate to return existing node", result == n);
+ }
+
+ public void testCreateFromRoot() throws Exception {
+ final Mockery mockery = new Mockery();
+ final DeepNodeCreator c = new DeepNodeCreator();
+ final String rootPath = "/";
+ final String fooPath = "/foo";
+ final String barPath = "/foo/bar";
+ final Session s = mockery.mock(Session.class);
+ final Node root = mockery.mock(Node.class, rootPath);
+ final Node foo = mockery.mock(Node.class, fooPath);
+ final Node bar = mockery.mock(Node.class, barPath);
+ final String testNodeType = "NT_TEST";
+
+ mockery.checking(new Expectations() {{
+ allowing(s).itemExists(barPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(fooPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(rootPath);
+ will(returnValue(true));
+
+ allowing(s).getItem(rootPath);
+ will(returnValue(root));
+
+ allowing(root).isNode();
+ will(returnValue(true));
+
+ allowing(root).addNode("foo", testNodeType);
+ will(returnValue(foo));
+
+ allowing(foo).addNode("bar", testNodeType);
+ will(returnValue(bar));
+
+ allowing(s).save();
+ }});
+
+ final Node result = c.deepCreateNode(barPath, s, testNodeType);
+ assertTrue("Expecting deepCreate to return create node", result == bar);
+ }
+
+ public void testCreateWithVariousTypes() throws Exception {
+ final Mockery mockery = new Mockery();
+
+ final String fooPath = "/foo";
+ final String barPath = "/foo/bar";
+ final String wiiPath = "/foo/bar/wii";
+ final Session s = mockery.mock(Session.class);
+ final Node foo = mockery.mock(Node.class, fooPath);
+ final Node bar = mockery.mock(Node.class, barPath);
+ final Node wii = mockery.mock(Node.class, wiiPath);
+
+ mockery.checking(new Expectations() {{
+ allowing(s).itemExists(wiiPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(barPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(fooPath);
+ will(returnValue(true));
+
+ allowing(s).getItem(fooPath);
+ will(returnValue(foo));
+
+ allowing(foo).isNode();
+ will(returnValue(true));
+
+ allowing(foo).getPath();
+ will(returnValue(fooPath));
+
+ allowing(foo).addNode("bar", "NT_/foo.bar");
+ will(returnValue(bar));
+
+ allowing(bar).getPath();
+ will(returnValue(barPath));
+
+ allowing(bar).addNode("wii", "NT_/foo/bar.wii");
+ will(returnValue(wii));
+
+ allowing(s).save();
+ }});
+
+ final AtomicInteger counter = new AtomicInteger();
+ final DeepNodeCreator c = new DeepNodeCreator() {
+
+ @Override
+ protected String getNodeType(Node parent, String childPath, String suggestedNodeType)
+ throws RepositoryException {
+ return "NT_" + parent.getPath() + "." + childPath;
+ }
+
+ @Override
+ protected void nodeCreated(Node n) throws RepositoryException {
+ counter.addAndGet(1);
+ }
+ };
+ final Node result = c.deepCreateNode(wiiPath, s, null);
+ assertTrue("Expecting deepCreate to return created node", result == wii);
+ assertEquals("Expecting correct count of nodeCreated calls", 2, counter.get());
+ }
+}
Property changes on: jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/DeepNodeCreatorTest.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision Rev URL
Added: svn:eol-style
+ native
Index: jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/DeepNodeCreator.java
===================================================================
--- jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/DeepNodeCreator.java (revision 0)
+++ jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/DeepNodeCreator.java (revision 0)
@@ -0,0 +1,74 @@
+/*
+ * 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.jackrabbit.util;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+/**
+ * Deep-creation of nodes: parent nodes are created if needed.
+ */
+public class DeepNodeCreator {
+
+ /** Create a node, also creating parent nodes as needed
+ * @param path Path of the node to create
+ * @param session Used to create nodes
+ * @param nodeType Node type of created nodes, can be
+ * overridden via {@link #getNodeType}
+ * @return The created node
+ * @throws RepositoryException In case of problems
+ */
+ public Node deepCreateNode(String path, Session session, String nodeType)
+ throws RepositoryException {
+ Node result = null;
+ if (session.itemExists(path)) {
+ final Item it = session.getItem(path);
+ if (it.isNode()) {
+ result = (Node) it;
+ }
+ } else {
+ final int slashPos = path.lastIndexOf("/");
+ String parentPath = path.substring(0, slashPos);
+ if(parentPath.length() == 0) {
+ parentPath = "/";
+ }
+ final String childPath = path.substring(slashPos + 1);
+ final Node parent = deepCreateNode(parentPath, session, nodeType);
+ result = parent.addNode(childPath, getNodeType(parent, childPath, nodeType));
+ nodeCreated(result);
+ session.save();
+ }
+ return result;
+ }
+
+ /** Can be overridden to return a specific nodetype to use at a given path.
+ * @param parent the parent of the node that is being created
+ * @param childPath the path of the child that is being created
+ * @param suggestedNodeType the nodeType value passed to {@link deepCreateNode}
+ * @return suggestedNodeType by default
+ */
+ protected String getNodeType(Node parent, String childPath, String suggestedNodeType)
+ throws RepositoryException {
+ return suggestedNodeType;
+ }
+
+ /** Can be overridden to customize the created nodes, add mixins etc. */
+ protected void nodeCreated(Node n) throws RepositoryException {
+ }
+}
Property changes on: jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/DeepNodeCreator.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision Rev URL
Added: svn:eol-style
+ native
Index: jackrabbit-jcr-commons/pom.xml
===================================================================
--- jackrabbit-jcr-commons/pom.xml (revision 967083)
+++ jackrabbit-jcr-commons/pom.xml (working copy)
@@ -71,6 +71,12 @@
json
test
+
+ org.jmock
+ jmock-junit4
+ 2.5.1
+ test
+
-
+
\ No newline at end of file