You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2012/04/21 01:30:59 UTC
svn commit: r1328538 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/
oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/
oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/
Author: mduerig
Date: Fri Apr 20 23:30:59 2012
New Revision: 1328538
URL: http://svn.apache.org/viewvc?rev=1328538&view=rev
Log:
OAK-61: initial draft / prove of concept of path handling in oak-core
OAK-15: Clean up oak-jcr: use path utilities from oak-core
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamespaceRegistry.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/Paths.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NameSpaceRegistryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/PathsTest.java
Removed:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Paths.java
Modified:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamespaceRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamespaceRegistry.java?rev=1328538&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamespaceRegistry.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamespaceRegistry.java Fri Apr 20 23:30:59 2012
@@ -0,0 +1,143 @@
+/*
+* 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.oak.namepath;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Prove of concept implementation for OAK-61.
+ *
+ * This implementation is entirely in memory. TODO: persist mappings
+ *
+ * For each registered mapping from a jcr prefix to a namespace a
+ * a mk prefix is generated. The mk prefixes are in one to one relation
+ * ship with the registered namespaces and should be used as shorthands
+ * in place of the actual namespaces in all further name and path handling.
+ *
+ * TODO: expose the relevant methods through the Oak API.
+ */
+public class NamespaceRegistry {
+ private final Map<String, String> jcr2NsMap = new HashMap<String, String>();
+ private final Map<String, String> ns2MkMap = new HashMap<String, String>();
+ private final Map<String, String> mk2JcrMap = new HashMap<String, String>();
+
+ /**
+ * Add a mapping jcr prefix to namespace mapping. If either
+ * {@code jcrPrefix} or {@code namespace} is already mapped, the
+ * existing mapping is removed first.
+ *
+ * @param jcrPrefix
+ * @param namespace
+ */
+ public void registerNamespace(String jcrPrefix, String namespace) {
+ if (jcrPrefix == null || namespace == null) {
+ throw new IllegalArgumentException();
+ }
+
+ unregisterJcrPrefix(jcrPrefix);
+ unregisterNamespace(namespace);
+
+ String mk = ns2MkMap.get(namespace);
+ if (mk == null) {
+ // Generate a mk prefix. Use jcrPrefix if possible, disambiguate otherwise
+ mk = jcrPrefix;
+ while (ns2MkMap.containsValue(mk)) {
+ mk += "+"; // todo: use more sophisticated approach for generating unique names
+ }
+ ns2MkMap.put(namespace, mk);
+ }
+
+ mk2JcrMap.put(mk, jcrPrefix);
+ jcr2NsMap.put(jcrPrefix, namespace);
+ }
+
+ /**
+ * Remove the mapping of {@code jcrPrefix} if such exists.
+ * @param jcrPrefix
+ * @return the namespace to which {@code jcrPrefix} mapped or
+ * {@code null} if none.
+ */
+ public String unregisterJcrPrefix(String jcrPrefix) {
+ if (jcrPrefix == null) {
+ throw new IllegalArgumentException();
+ }
+
+ String ns = jcr2NsMap.remove(jcrPrefix);
+ mk2JcrMap.remove(ns2MkMap.get(ns));
+ return ns;
+ }
+
+ /**
+ * Remove the mapping for {@code namespace} if such exists.
+ * @param namespace
+ * @return the jcr prefix which mapped to {@code namespace} or
+ * {@code null} if none.
+ */
+ public String unregisterNamespace(String namespace) {
+ if (namespace == null) {
+ throw new IllegalArgumentException();
+ }
+
+ String jcrPrefix = mk2JcrMap.remove(ns2MkMap.get(namespace));
+ jcr2NsMap.remove(jcrPrefix);
+ return jcrPrefix;
+ }
+
+ /**
+ * Retrieve the namespace which {@code jcrPrefix} maps to if any
+ * or {@code null} otherwise.
+ * @param jcrPrefix
+ * @return namespace or {@code null}
+ */
+ public String getNamespace(String jcrPrefix) {
+ return jcr2NsMap.get(jcrPrefix);
+ }
+
+ /**
+ * Retrieve the jcr prefix which maps to {@code namespace} if any
+ * or {@code null} otherwise.
+ * @param namespace
+ * @return jcr prefix or {@code null}
+ */
+ public String getJcrPrefix(String namespace) {
+ return mk2JcrMap.get(ns2MkMap.get(namespace));
+ }
+
+ //------------------------------------------------------------< internal >---
+
+ /**
+ * Retrieve the jcr prefix which maps to {@code mkPrefix} if any
+ * or {@code null} otherwise.
+ * @param mkPrefix
+ * @return jcr prefix or {@code null}
+ */
+ String getJcrPrefixFromMk(String mkPrefix) {
+ return mk2JcrMap.get(mkPrefix);
+ }
+
+ /**
+ * Retrieve the mk prefix which maps to {@code jcrPrefix} if any
+ * or {@code null} otherwise.
+ * @param jcrPrefix
+ * @return mk prefix or {@code null}
+ */
+ String getMkPrefixFromJcr(String jcrPrefix) {
+ return ns2MkMap.get(jcr2NsMap.get(jcrPrefix));
+ }
+
+}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/Paths.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/Paths.java?rev=1328538&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/Paths.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/Paths.java Fri Apr 20 23:30:59 2012
@@ -0,0 +1,288 @@
+/*
+* 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.oak.namepath;
+
+import org.apache.jackrabbit.mk.util.PathUtils;
+import org.apache.jackrabbit.oak.util.Function1;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * All path in the Oak API have the following form
+ * <p>
+ * <pre>
+ * PATH := ("/" ELEMENT)* | ELEMENT ("/" ELEMENT)*
+ * ELEMENT := [PREFIX ":"] NAME
+ * PREFIX := non empty string not containing ":" and "/"
+ * NAME := non empty string not containing ":" and "/" TODO: check whether this is correct
+ * </pre>
+ */
+public final class Paths {
+
+ private Paths() {}
+
+ /**
+ * Get the parent of a path. The parent of the root path ("/") is the root
+ * path.
+ *
+ * @param path the path
+ * @return the parent path
+ */
+ public static String getParentPath(String path) {
+ return PathUtils.getParentPath(path);
+ }
+
+ /**
+ * Get the last element of the (absolute or relative) path. The name of the
+ * root node ("/") and the name of the empty path ("") is the empty path.
+ *
+ * @param path the complete path
+ * @return the last element
+ */
+ public static String getName(String path) {
+ return PathUtils.getName(path);
+ }
+
+ /**
+ * Get the nth ancestor of a path. The 1st ancestor is the parent path,
+ * 2nd ancestor the grandparent path, and so on...
+ * <p/>
+ * If nth <= 0, the path argument is returned as is.
+ *
+ * @param path the path
+ * @return the ancestor path
+ */
+ public static String getAncestorPath(String path, int nth) {
+ return PathUtils.getAncestorPath(path, nth);
+ }
+
+ /**
+ * Concatenate path elements.
+ *
+ * @param parentPath the parent path
+ * @param subPath the subPath path to add
+ * @return the concatenated path
+ */
+ public static String concat(String parentPath, String subPath) {
+ return PathUtils.concat(parentPath, subPath);
+ }
+
+ /**
+ * Relativize a path wrt. a parent path such that
+ * {@code relativize(parentPath, concat(parentPath, path)) == paths}
+ * holds.
+ *
+ * @param parentPath parent pth
+ * @param path path to relativize
+ * @return relativized path
+ */
+ public static String relativize(String parentPath, String path) {
+ return PathUtils.relativize(parentPath, path);
+ }
+
+ /**
+ * Calculate the number of elements in the path. The root path has zero
+ * elements.
+ *
+ * @param path the path
+ * @return the number of elements
+ */
+ public static int getDepth(String path) {
+ return PathUtils.getDepth(path);
+ }
+
+ /**
+ * Get the prefix of an element. Undefined if {@code element} is
+ * not an {@code ELEMENT}.
+ * @param element
+ * @return the {@code PREFIX} of {@code element} or {@code null} if none
+ */
+ public static String getPrefixFromElement(String element) {
+ int pos = element.indexOf(':');
+ if (pos == -1) {
+ return null;
+ }
+ else {
+ return element.substring(0, pos);
+ }
+ }
+
+ /**
+ * Get the name of an element. Undefined if {@code element} is
+ * not an {@code ELEMENT}.
+ * @param element
+ * @return the {@code NAME} of {@code element}
+ */
+ public static String getNameFromElement(String element) {
+ int pos = element.indexOf(':');
+ if (pos == -1) {
+ return element;
+ }
+ else {
+ return element.substring(pos + 1);
+ }
+ }
+
+ /**
+ * Determine whether {@code string} is a valid {@code ELEMENT}.
+ * @param string
+ * @return {@code true} iff {@code string} is a valid {@code ELEMENT}.
+ */
+ public static boolean isValidElement(String string) {
+ if (string.isEmpty()) {
+ return false;
+ }
+
+ int colons = 0;
+ int pos = -1;
+ for (int k = 0; k < string.length(); k++) {
+ if (string.charAt(k) == ':') {
+ colons += 1;
+ pos = k;
+ }
+ else if (string.charAt(k) == '/') {
+ return false;
+ }
+ }
+
+ return colons <= 1 && (pos != 0 && pos != string.length() - 1);
+ }
+
+ /**
+ * Determine whether {@code string} is a valid {@code PATH}.
+ * @param string
+ * @return {@code true} iff {@code string} is a valid {@code PATH}.
+ */
+ public static boolean isValidPath(String string) {
+ if (string.isEmpty()) {
+ return false;
+ }
+ if (string.length() > 1 && string.endsWith("/")) {
+ return false;
+ }
+
+ for (String part : split(string, '/')) {
+ if (!isValidElement(part)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Resolve {@code element} against {@code prefixResolver}: replace the
+ * prefix of this element with the prefix returned by the prefix resolver.
+ * Undefined if {@code element} is not a valid {@code ELEMENT}.
+ * @param element {@code ELEMENT}
+ * @param prefixResolver prefix resolver
+ * @return resolved element
+ * @throws IllegalArgumentException if {@code prefixResolver} returns {@code null}
+ * for the prefix of {@code element}.
+ */
+ public static String resolveElement(String element, Function1<String, String> prefixResolver) {
+ String prefix = getPrefixFromElement(element);
+ if (prefix == null) {
+ return element;
+ }
+
+ String newPrefix = prefixResolver.apply(prefix);
+ if (newPrefix == null) {
+ throw new IllegalArgumentException("Can't resolve prefix " + prefix);
+ }
+ return newPrefix + ':' + getNameFromElement(element);
+ }
+
+ /**
+ * Resolve {@code path} against {@code prefixResolver} by resolving each
+ * element of the path against that prefix resolver.
+ * @param path {@code PATH}
+ * @param prefixResolver prefix resolver
+ * @return resolved path
+ * @throws IllegalArgumentException if {@code prefixResolver} returns {@code null}
+ * for a prefix in any of the elements of {@code path}.
+ */
+ public static String resolvePath(String path, Function1<String, String> prefixResolver) {
+ StringBuilder resolved = new StringBuilder();
+
+ String sep = path.charAt(0) == '/' ? "/" : "";
+
+ for (String element : split(path, '/')) {
+ resolved.append(sep).append(resolveElement(element, prefixResolver));
+ sep = "/";
+ }
+
+ return resolved.toString();
+ }
+
+ //------------------------------------------------------------< private >---
+
+ private static Iterable<String> split(final String string, final char separator) {
+ return new Iterable<String>() {
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ int pos = !string.isEmpty() && string.charAt(0) == separator ? 1 : 0;
+ String next;
+
+ @Override
+ public boolean hasNext() {
+ if (next == null) {
+ if (pos >= string.length()) {
+ return false;
+ }
+ else {
+ int i = string.indexOf(separator, pos);
+ if (i < 0) {
+ next = string.substring(pos);
+ pos = string.length();
+ }
+ else {
+ next = string.substring(pos, i);
+ pos = i + 1;
+ }
+ return true;
+ }
+ }
+ else {
+ return true;
+ }
+ }
+
+ @Override
+ public String next() {
+ if (hasNext()) {
+ String next = this.next;
+ this.next = null;
+ return next;
+ }
+ else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("remove");
+ }
+ };
+ }
+ };
+ }
+
+}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NameSpaceRegistryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NameSpaceRegistryTest.java?rev=1328538&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NameSpaceRegistryTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NameSpaceRegistryTest.java Fri Apr 20 23:30:59 2012
@@ -0,0 +1,81 @@
+/*
+* 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.oak.namepath;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class NameSpaceRegistryTest {
+
+ @Test
+ public void nameSpaceRegistry() {
+ NamespaceRegistry r = new NamespaceRegistry();
+
+ r.registerNamespace("p", "n");
+ assertEquals(r.getNamespace("p"), "n");
+ assertEquals(r.getJcrPrefix("n"), "p");
+ String mk = r.getMkPrefixFromJcr("p");
+ assertNotNull(mk);
+ assertEquals("p", r.getJcrPrefixFromMk(mk));
+
+ r.registerNamespace("p", "n2");
+ assertEquals(r.getNamespace("p"), "n2");
+ assertEquals(r.getJcrPrefix("n2"), "p");
+ assertNull(r.getJcrPrefix("n"));
+ mk = r.getMkPrefixFromJcr("p");
+ assertNotNull(mk);
+ assertEquals("p", r.getJcrPrefixFromMk(mk));
+
+ r.registerNamespace("p2", "n");
+ assertEquals(r.getNamespace("p2"), "n");
+ assertEquals(r.getJcrPrefix("n"), "p2");
+ assertEquals(r.getNamespace("p"), "n2");
+ assertEquals(r.getJcrPrefix("n2"), "p");
+ mk = r.getMkPrefixFromJcr("p");
+ assertNotNull(mk);
+ assertEquals("p", r.getJcrPrefixFromMk(mk));
+ mk = r.getMkPrefixFromJcr("p2");
+ assertNotNull(mk);
+ assertEquals("p2", r.getJcrPrefixFromMk(mk));
+
+ r.registerNamespace("p2", "n2");
+ assertEquals(r.getNamespace("p2"), "n2");
+ assertEquals(r.getJcrPrefix("n2"), "p2");
+ assertNull(r.getJcrPrefix("n"));
+ assertNull(r.getNamespace("p"));
+ mk = r.getMkPrefixFromJcr("p");
+ assertNull(mk);
+ mk = r.getMkPrefixFromJcr("p2");
+ assertNotNull(mk);
+ assertEquals("p2", r.getJcrPrefixFromMk(mk));
+
+ r.registerNamespace("p", "n");
+ assertEquals(r.getNamespace("p2"), "n2");
+ assertEquals(r.getJcrPrefix("n2"), "p2");
+ assertEquals(r.getNamespace("p"), "n");
+ assertEquals(r.getJcrPrefix("n"), "p");
+ mk = r.getMkPrefixFromJcr("p");
+ assertNotNull(mk);
+ assertEquals("p", r.getJcrPrefixFromMk(mk));
+ mk = r.getMkPrefixFromJcr("p2");
+ assertNotNull(mk);
+ assertEquals("p2", r.getJcrPrefixFromMk(mk));
+ }
+}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/PathsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/PathsTest.java?rev=1328538&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/PathsTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/PathsTest.java Fri Apr 20 23:30:59 2012
@@ -0,0 +1,141 @@
+/*
+* 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.oak.namepath;
+
+import org.apache.jackrabbit.oak.util.Function1;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class PathsTest {
+ private static final Function1<String, String> RESOLVER = new Function1<String, String>() {
+ private final Map<String, String> map = new HashMap<String, String>();
+ {
+ map.put("a", "x");
+ map.put("b", "y");
+ map.put("c", "z");
+ }
+
+ @Override
+ public String apply(String argument) {
+ return map.get(argument);
+ }
+ };
+
+ @Test
+ public void getPrefix() {
+ assertEquals(null, Paths.getPrefixFromElement("foo"));
+ assertEquals("foo", Paths.getPrefixFromElement("foo:bar"));
+ }
+
+ @Test
+ public void getName() {
+ assertEquals("foo", Paths.getNameFromElement("foo"));
+ assertEquals("bar", Paths.getNameFromElement("foo:bar"));
+ }
+
+ @Test
+ public void isValidElement() {
+ assertTrue(Paths.isValidElement("foo"));
+ assertTrue(Paths.isValidElement("foo:bar"));
+
+ assertFalse(Paths.isValidElement(""));
+ assertFalse(Paths.isValidElement(":"));
+ assertFalse(Paths.isValidElement("foo:"));
+ assertFalse(Paths.isValidElement("fo/o:"));
+ assertFalse(Paths.isValidElement(":bar"));
+ }
+
+ @Test
+ public void isValidAbsolutePath() {
+ assertTrue(Paths.isValidPath("/"));
+ assertTrue(Paths.isValidPath("/a/b/c"));
+ assertTrue(Paths.isValidPath("/p:a/q:b/r:c"));
+
+ assertFalse(Paths.isValidPath(""));
+ assertFalse(Paths.isValidPath("/a/b/c/"));
+ assertFalse(Paths.isValidPath("/p:a/:b/r:c"));
+ assertFalse(Paths.isValidPath("/p:a/q:/r:c"));
+ assertFalse(Paths.isValidPath("/p:a/:/r:c"));
+ assertFalse(Paths.isValidPath("/p:a//r:c"));
+ assertFalse(Paths.isValidPath("//"));
+ }
+
+ @Test
+ public void isValidRelativePath() {
+ assertTrue(Paths.isValidPath("a/b/c"));
+ assertTrue(Paths.isValidPath("p:a/q:b/r:c"));
+
+ assertFalse(Paths.isValidPath("a/b/c/"));
+ assertFalse(Paths.isValidPath("p:a/:b/r:c"));
+ assertFalse(Paths.isValidPath("p:a/q:/r:c"));
+ assertFalse(Paths.isValidPath("p:a/:/r:c"));
+ assertFalse(Paths.isValidPath("p:a//r:c"));
+ }
+
+ @Test
+ public void resolveElement() {
+ assertEquals("foo", Paths.resolveElement("foo", RESOLVER));
+ assertEquals("x:foo", Paths.resolveElement("a:foo", RESOLVER));
+
+ try {
+ Paths.resolveElement("q:foo", RESOLVER);
+ fail();
+ }
+ catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void resolveAbsolutePath() {
+ assertEquals("/foo", Paths.resolvePath("/foo", RESOLVER));
+ assertEquals("/foo/bar", Paths.resolvePath("/foo/bar", RESOLVER));
+ assertEquals("/x:foo", Paths.resolvePath("/a:foo", RESOLVER));
+ assertEquals("/x:foo/y:bar", Paths.resolvePath("/a:foo/b:bar", RESOLVER));
+
+ try {
+ Paths.resolvePath("/a:foo/q:bar", RESOLVER);
+ fail();
+ }
+ catch (IllegalArgumentException expected) {
+ }
+
+ }
+
+ @Test
+ public void resolveRelativePath() {
+ assertEquals("foo", Paths.resolvePath("foo", RESOLVER));
+ assertEquals("foo/bar", Paths.resolvePath("foo/bar", RESOLVER));
+ assertEquals("x:foo", Paths.resolvePath("a:foo", RESOLVER));
+ assertEquals("x:foo/y:bar", Paths.resolvePath("a:foo/b:bar", RESOLVER));
+
+ try {
+ Paths.resolvePath("a:foo/q:bar", RESOLVER);
+ fail();
+ }
+ catch (IllegalArgumentException expected) {
+ }
+
+ }
+
+}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1328538&r1=1328537&r2=1328538&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Fri Apr 20 23:30:59 2012
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.oak.jcr.uti
import org.apache.jackrabbit.oak.jcr.util.LogUtil;
import org.apache.jackrabbit.oak.jcr.util.ValueConverter;
import org.apache.jackrabbit.oak.kernel.ScalarImpl;
+import org.apache.jackrabbit.oak.namepath.Paths;
import org.apache.jackrabbit.oak.util.Function1;
import org.apache.jackrabbit.oak.util.Iterators;
import org.apache.jackrabbit.oak.util.Predicate;
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java?rev=1328538&r1=1328537&r2=1328538&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java Fri Apr 20 23:30:59 2012
@@ -21,6 +21,7 @@ import org.apache.jackrabbit.oak.api.Pro
import org.apache.jackrabbit.oak.api.TransientNodeState;
import org.apache.jackrabbit.oak.jcr.util.LogUtil;
import org.apache.jackrabbit.oak.jcr.util.ValueConverter;
+import org.apache.jackrabbit.oak.namepath.Paths;
import org.apache.jackrabbit.value.ValueHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1328538&r1=1328537&r2=1328538&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java Fri Apr 20 23:30:59 2012
@@ -17,10 +17,11 @@
package org.apache.jackrabbit.oak.jcr;
import org.apache.jackrabbit.commons.AbstractSession;
+import org.apache.jackrabbit.oak.api.Branch;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Connection;
-import org.apache.jackrabbit.oak.api.Branch;
import org.apache.jackrabbit.oak.api.TransientNodeState;
+import org.apache.jackrabbit.oak.namepath.Paths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java?rev=1328538&r1=1328537&r2=1328538&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java Fri Apr 20 23:30:59 2012
@@ -16,10 +16,11 @@
*/
package org.apache.jackrabbit.oak.jcr;
+import org.apache.jackrabbit.oak.api.Branch;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Connection;
-import org.apache.jackrabbit.oak.api.Branch;
import org.apache.jackrabbit.oak.jcr.query.QueryManagerImpl;
+import org.apache.jackrabbit.oak.namepath.Paths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;