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 re...@apache.org on 2012/06/05 17:33:37 UTC

svn commit: r1346426 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/namepath/ test/java/org/apache/jackrabbit/oak/namepath/

Author: reschke
Date: Tue Jun  5 15:33:37 2012
New Revision: 1346426

URL: http://svn.apache.org/viewvc?rev=1346426&view=rev
Log:
OAK-61: add a path mapper variant that only deals with namespace remappings and expanded names

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/PathMapper.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java?rev=1346426&r1=1346425&r2=1346426&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java Tue Jun  5 15:33:37 2012
@@ -146,10 +146,112 @@ public class NamePathMapperImpl implemen
     }
 
     @Override
+    public String mapJcrToOakNamespaces(String jcrPath) {
+        final List<String> elements = new ArrayList<String>();
+        final StringBuilder parseErrors = new StringBuilder();
+
+        if ("/".equals(jcrPath)) {
+            return jcrPath;
+        }
+
+        boolean hasClarkBrackets = false;
+        boolean hasColon = false;
+
+        for (int i = 0; i < jcrPath.length(); i++) {
+            char c = jcrPath.charAt(i);
+            
+            if (c == '{' || c=='}') {
+                hasClarkBrackets = true;
+            }
+            else if (c == ':') {
+                hasColon = true;
+            }
+        }
+
+        // no expanded names and no prefixes, or
+        // no expanded names and no prefix remappings
+        if (!hasClarkBrackets && (!hasColon || !hasSessionLocalMappings())) {
+            return removeTrailingSlash(jcrPath);
+        }
+
+        JcrPathParser.Listener listener = new JcrPathParser.Listener() {
+
+            @Override
+            public boolean root() {
+                if (!elements.isEmpty()) {
+                    parseErrors.append("/ on non-empty path");
+                    return false;
+                }
+                elements.add("");
+                return true;
+            }
+
+            @Override
+            public boolean current() {
+                elements.add(".");
+                return true;
+            }
+
+            @Override
+            public boolean parent() {
+                elements.add("..");
+                return true;
+            }
+
+            @Override
+            public void error(String message) {
+                parseErrors.append(message);
+            }
+
+            @Override
+            public boolean name(String name, int index) {
+                String p = nameMapper.getOakName(name);
+                if (p == null) {
+                    parseErrors.append("Invalid name: ").append(name);
+                    return false;
+                }
+                if (index != 0) {
+                    p += "[" + index + "]";
+                }
+                elements.add(p);
+                return true;
+            }
+        };
+
+        JcrPathParser.parse(jcrPath, listener);
+        if (parseErrors.length() != 0) {
+            log.debug("Could not parse path " + jcrPath + ": " + parseErrors.toString());
+            return null;
+        }
+
+        // Empty path maps to ""
+        if (elements.isEmpty()) {
+            return "";
+        }
+
+        StringBuilder oakPath = new StringBuilder();
+        for (String element : elements) {
+            if (element.isEmpty()) {
+                // root
+                oakPath.append('/');
+            }
+            else {
+                oakPath.append(element);
+                oakPath.append('/');
+            }
+        }
+
+        // root path is special-cased early on so it does not need to
+        // be considered here
+        oakPath.deleteCharAt(oakPath.length() - 1);
+        return oakPath.toString();
+    }
+
+    @Override
     @Nonnull
     public String getJcrPath(String oakPath) {
         final List<String> elements = new ArrayList<String>();
-
+        
         if ("/".equals(oakPath)) {
             // avoid the need to special case the root path later on
             return "/";
@@ -219,4 +321,14 @@ public class NamePathMapperImpl implemen
         jcrPath.deleteCharAt(jcrPath.length() - 1);
         return jcrPath.toString();
     }
+
+    private String removeTrailingSlash(String path) {
+        if ("/".equals(path) || path.isEmpty()) {
+            return path;
+        } else if (path.endsWith("/")) {
+            return path.substring(0, path.length() - 1);
+        } else {
+            return path;
+        }
+    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/PathMapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/PathMapper.java?rev=1346426&r1=1346425&r2=1346426&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/PathMapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/PathMapper.java Tue Jun  5 15:33:37 2012
@@ -36,6 +36,19 @@ public interface PathMapper {
     String getOakPath(String jcrPath);
 
     /**
+     * Maps a JCR path to an Oak path, substituting JCR prefixes with
+     * Oak prefixes, and converting expanded names to Oak qualified form.
+     * Returns the converted path for the given JCR path, or {@code null} if no
+     * such mapping exists because the given JCR path contains a name element
+     * with an unknown namespace URI or prefix, or is otherwise invalid.
+     *
+     * @param jcrPath JCR path
+     * @return mapped path, or {@code null}
+     */
+    @CheckForNull
+    String mapJcrToOakNamespaces(String jcrPath);
+
+    /**
      * Returns the JCR path for the given Oak path. The given path is
      * expected to have come from a valid Oak repository that contains
      * only valid paths whose name elements only use proper namespace

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java?rev=1346426&r1=1346425&r2=1346426&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java Tue Jun  5 15:33:37 2012
@@ -25,20 +25,19 @@ import java.util.Map;
 import java.util.UUID;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
 public class NamePathMapperImplTest {
 
-    private TestNameMapper mapper = new TestNameMapper();
-    private NamePathMapper npMapper = new NamePathMapperImpl(mapper);
-
     @Test
     public void testInvalidIdentifierPath() {
+        TestNameMapper mapper = new TestNameMapper(true);
+        NamePathMapper npMapper = new NamePathMapperImpl(mapper);
+
         List<String> invalid = new ArrayList<String>();
-        invalid.add('[' + UUID.randomUUID().toString()+ "]abc");
-        invalid.add('[' + UUID.randomUUID().toString()+ "]/a/b/c");
+        invalid.add('[' + UUID.randomUUID().toString() + "]abc");
+        invalid.add('[' + UUID.randomUUID().toString() + "]/a/b/c");
 
         for (String jcrPath : invalid) {
             assertNull(npMapper.getOakPath(jcrPath));
@@ -47,45 +46,96 @@ public class NamePathMapperImplTest {
 
     @Test
     public void testJcrToOak() {
+        TestNameMapper mapper = new TestNameMapper(true);
+        NamePathMapper npMapper = new NamePathMapperImpl(mapper);
+
         assertEquals("/", npMapper.getOakPath("/"));
         assertEquals("foo", npMapper.getOakPath("{}foo"));
         assertEquals("/oak-foo:bar", npMapper.getOakPath("/foo:bar"));
-        assertEquals("/oak-foo:bar/oak-quu:qux",
-                npMapper.getOakPath("/foo:bar/quu:qux"));
+        assertEquals("/oak-foo:bar/oak-quu:qux", npMapper.getOakPath("/foo:bar/quu:qux"));
         assertEquals("oak-foo:bar", npMapper.getOakPath("foo:bar"));
-        assertEquals("oak-nt:unstructured", npMapper.getOakPath(
-                "{http://www.jcp.org/jcr/nt/1.0}unstructured"));
-        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath(
-                "foobar/{http://www.jcp.org/jcr/1.0}content"));
-        assertEquals("foobar", npMapper.getOakPath(
-                "foobar/{http://www.jcp.org/jcr/1.0}content/.."));
-        assertEquals("", npMapper.getOakPath(
-                "foobar/{http://www.jcp.org/jcr/1.0}content/../.."));
-        assertEquals("..", npMapper.getOakPath(
-                "foobar/{http://www.jcp.org/jcr/1.0}content/../../.."));
-        assertEquals("../..", npMapper.getOakPath(
-                "foobar/{http://www.jcp.org/jcr/1.0}content/../../../.."));
-        assertEquals("oak-jcr:content", npMapper.getOakPath(
-                "foobar/../{http://www.jcp.org/jcr/1.0}content"));
-        assertEquals("../oak-jcr:content", npMapper.getOakPath(
-                "foobar/../../{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("oak-nt:unstructured", npMapper.getOakPath("{http://www.jcp.org/jcr/nt/1.0}unstructured"));
+        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath("foobar/{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar", npMapper.getOakPath("foobar/{http://www.jcp.org/jcr/1.0}content/.."));
+        assertEquals("", npMapper.getOakPath("foobar/{http://www.jcp.org/jcr/1.0}content/../.."));
+        assertEquals("..", npMapper.getOakPath("foobar/{http://www.jcp.org/jcr/1.0}content/../../.."));
+        assertEquals("../..", npMapper.getOakPath("foobar/{http://www.jcp.org/jcr/1.0}content/../../../.."));
+        assertEquals("oak-jcr:content", npMapper.getOakPath("foobar/../{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("../oak-jcr:content", npMapper.getOakPath("foobar/../../{http://www.jcp.org/jcr/1.0}content"));
         assertEquals("..", npMapper.getOakPath(".."));
         assertEquals("", npMapper.getOakPath("."));
-        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath(
-                "foobar/{http://www.jcp.org/jcr/1.0}content/."));
-        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath(
-                "foobar/{http://www.jcp.org/jcr/1.0}content/./."));
-        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath(
-                "foobar/./{http://www.jcp.org/jcr/1.0}content"));
-        assertEquals("oak-jcr:content", npMapper.getOakPath(
-                "foobar/./../{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath("foobar/{http://www.jcp.org/jcr/1.0}content/."));
+        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath("foobar/{http://www.jcp.org/jcr/1.0}content/./."));
+        assertEquals("foobar/oak-jcr:content", npMapper.getOakPath("foobar/./{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("oak-jcr:content", npMapper.getOakPath("foobar/./../{http://www.jcp.org/jcr/1.0}content"));
+    }
+
+    @Test
+    public void testMapJcrToOakNamespaces() {
+        TestNameMapper mapper = new TestNameMapper(true);
+        NamePathMapper npMapper = new NamePathMapperImpl(mapper);
+
+        assertEquals("/", npMapper.mapJcrToOakNamespaces("/"));
+        assertEquals("foo", npMapper.mapJcrToOakNamespaces("{}foo"));
+        assertEquals("/oak-foo:bar", npMapper.mapJcrToOakNamespaces("/foo:bar"));
+        assertEquals("/oak-foo:bar/oak-quu:qux", npMapper.mapJcrToOakNamespaces("/foo:bar/quu:qux"));
+        assertEquals("oak-foo:bar", npMapper.mapJcrToOakNamespaces("foo:bar"));
+        assertEquals("oak-nt:unstructured", npMapper.mapJcrToOakNamespaces("{http://www.jcp.org/jcr/nt/1.0}unstructured"));
+        assertEquals("foobar/oak-jcr:content", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar/oak-jcr:content/..", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/.."));
+        assertEquals("foobar/oak-jcr:content/../..",
+                npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/../.."));
+        assertEquals("foobar/oak-jcr:content/../../..",
+                npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/../../.."));
+        assertEquals("foobar/oak-jcr:content/../../../..",
+                npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/../../../.."));
+        assertEquals("foobar/../oak-jcr:content", npMapper.mapJcrToOakNamespaces("foobar/../{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar/../../oak-jcr:content",
+                npMapper.mapJcrToOakNamespaces("foobar/../../{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("..", npMapper.mapJcrToOakNamespaces(".."));
+        assertEquals(".", npMapper.mapJcrToOakNamespaces("."));
+        assertEquals("foobar/oak-jcr:content/.", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/."));
+        assertEquals("foobar/oak-jcr:content/./.", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/./."));
+        assertEquals("foobar/./oak-jcr:content", npMapper.mapJcrToOakNamespaces("foobar/./{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar/./../oak-jcr:content",
+                npMapper.mapJcrToOakNamespaces("foobar/./../{http://www.jcp.org/jcr/1.0}content"));
+    }
+
+    @Test
+    public void testMapJcrToOakNamespacesNoRemap() {
+        TestNameMapper mapper = new TestNameMapper(false); // a mapper with no prefix remappings present
+        NamePathMapper npMapper = new NamePathMapperImpl(mapper);
+
+        checkIdentical(npMapper, "/");
+        assertEquals("foo", npMapper.mapJcrToOakNamespaces("{}foo"));
+        checkIdentical(npMapper, "/foo:bar");
+        checkIdentical(npMapper, "/foo:bar/quu:qux");
+        checkIdentical(npMapper, "foo:bar");
+        assertEquals("nt:unstructured", npMapper.mapJcrToOakNamespaces("{http://www.jcp.org/jcr/nt/1.0}unstructured"));
+        assertEquals("foobar/jcr:content", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar/jcr:content/..", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/.."));
+        assertEquals("foobar/jcr:content/../..", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/../.."));
+        assertEquals("foobar/jcr:content/../../..",
+                npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/../../.."));
+        assertEquals("foobar/jcr:content/../../../..",
+                npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/../../../.."));
+        assertEquals("foobar/../jcr:content", npMapper.mapJcrToOakNamespaces("foobar/../{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar/../../jcr:content", npMapper.mapJcrToOakNamespaces("foobar/../../{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("..", npMapper.mapJcrToOakNamespaces(".."));
+        assertEquals(".", npMapper.mapJcrToOakNamespaces("."));
+        assertEquals("foobar/jcr:content/.", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/."));
+        assertEquals("foobar/jcr:content/./.", npMapper.mapJcrToOakNamespaces("foobar/{http://www.jcp.org/jcr/1.0}content/./."));
+        assertEquals("foobar/./jcr:content", npMapper.mapJcrToOakNamespaces("foobar/./{http://www.jcp.org/jcr/1.0}content"));
+        assertEquals("foobar/./../jcr:content", npMapper.mapJcrToOakNamespaces("foobar/./../{http://www.jcp.org/jcr/1.0}content"));
     }
 
     @Test
     public void testOakToJcr() {
+        TestNameMapper mapper = new TestNameMapper(true);
+        NamePathMapper npMapper = new NamePathMapperImpl(mapper);
+
         assertEquals("/jcr-foo:bar", npMapper.getJcrPath("/foo:bar"));
-        assertEquals("/jcr-foo:bar/jcr-quu:qux",
-                npMapper.getJcrPath("/foo:bar/quu:qux"));
+        assertEquals("/jcr-foo:bar/jcr-quu:qux", npMapper.getJcrPath("/foo:bar/quu:qux"));
         assertEquals("jcr-foo:bar", npMapper.getJcrPath("foo:bar"));
         assertEquals(".", npMapper.getJcrPath(""));
 
@@ -102,11 +152,31 @@ public class NamePathMapperImplTest {
         }
     }
 
+    private void checkEquals(NamePathMapper npMapper, String jcrPath) {
+        String oakPath = npMapper.mapJcrToOakNamespaces(jcrPath);
+        assertEquals(jcrPath, oakPath);
+    }
+    
+    private void checkIdentical(NamePathMapper npMapper, String jcrPath) {
+        String oakPath = npMapper.mapJcrToOakNamespaces(jcrPath);
+        checkIdentical(jcrPath, oakPath);
+    }
+
+    private static void checkIdentical(String expected, String actual) {
+        assertEquals(expected, actual);
+        if (expected != actual) {
+            fail("Expected the strings to be the same");
+        }
+    }
+    
     private class TestNameMapper extends AbstractNameMapper {
 
+        private boolean withRemappings;
         private Map<String, String> uri2oakprefix = new HashMap<String, String>();
 
-        public TestNameMapper() {
+        public TestNameMapper(boolean withRemappings) {
+            this.withRemappings = withRemappings;
+
             uri2oakprefix.put("", "");
             uri2oakprefix.put("http://www.jcp.org/jcr/1.0", "jcr");
             uri2oakprefix.put("http://www.jcp.org/jcr/nt/1.0", "nt");
@@ -116,7 +186,7 @@ public class NamePathMapperImplTest {
 
         @Override
         protected String getJcrPrefix(String oakPrefix) {
-            if (oakPrefix.isEmpty()) {
+            if (oakPrefix.isEmpty() || !withRemappings) {
                 return oakPrefix;
             } else {
                 return "jcr-" + oakPrefix;
@@ -125,7 +195,7 @@ public class NamePathMapperImplTest {
 
         @Override
         protected String getOakPrefix(String jcrPrefix) {
-            if (jcrPrefix.isEmpty()) {
+            if (jcrPrefix.isEmpty() || !withRemappings) {
                 return jcrPrefix;
             } else {
                 return "oak-" + jcrPrefix;
@@ -134,12 +204,12 @@ public class NamePathMapperImplTest {
 
         @Override
         protected String getOakPrefixFromURI(String uri) {
-            return "oak-" + uri2oakprefix.get(uri);
+            return (withRemappings ? "oak-" : "") + uri2oakprefix.get(uri);
         }
 
         @Override
         public boolean hasSessionLocalMappings() {
-            return true;
+            return withRemappings;
         }
 
     }