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/04/25 14:24:44 UTC

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

Author: reschke
Date: Wed Apr 25 12:24:43 2012
New Revision: 1330238

URL: http://svn.apache.org/viewvc?rev=1330238&view=rev
Log:
OAK-61: add proposed path/name parsers (inherited from SPI commons), change them to use NameMappper, add a few simple test cases (WIP)

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java
Modified:
    jackrabbit/oak/trunk/oak-core/pom.xml
    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/PathsTest.java

Modified: jackrabbit/oak/trunk/oak-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/pom.xml?rev=1330238&r1=1330237&r2=1330238&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core/pom.xml Wed Apr 25 12:24:43 2012
@@ -81,6 +81,11 @@
       <artifactId>jcr</artifactId>
       <version>2.0</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-jcr-commons</artifactId>
+      <version>2.4.0</version>
+    </dependency>
 
     <!-- Logging -->
     <dependency>

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java?rev=1330238&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java Wed Apr 25 12:24:43 2012
@@ -0,0 +1,175 @@
+/*
+ * 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.util.XMLChar;
+
+public class JcrNameParser {
+
+    // constants for parser
+    private static final int STATE_PREFIX_START = 0;
+    private static final int STATE_PREFIX = 1;
+    private static final int STATE_NAME_START = 2;
+    private static final int STATE_NAME = 3;
+    private static final int STATE_URI_START = 4;
+    private static final int STATE_URI = 5;
+
+    interface Listener {
+        void error(String message);
+        void name(String name);
+    }
+
+    private JcrNameParser() {
+    }
+
+    public static void parse(String jcrName, Listener listener) {
+        // trivial check
+        int len = jcrName == null ? 0 : jcrName.length();
+        if (len == 0) {
+            listener.error("Empty name");
+            return;
+        }
+        if (".".equals(jcrName) || "..".equals(jcrName)) {
+            listener.error("Illegal name:" + jcrName);
+            return;
+        }
+
+        // parse the name
+        String prefix = "";
+        int nameStart = 0;
+        int state = STATE_PREFIX_START;
+        boolean trailingSpaces = false;
+
+        for (int i = 0; i < len; i++) {
+            char c = jcrName.charAt(i);
+            if (c == ':') {
+                if (state == STATE_PREFIX_START) {
+                    listener.error("Prefix must not be empty");
+                    return;
+                } else if (state == STATE_PREFIX) {
+                    if (trailingSpaces) {
+                        listener.error("Trailing spaces not allowed");
+                        return;
+                    }
+                    prefix = jcrName.substring(0, i);
+                    if (!XMLChar.isValidNCName(prefix)) {
+                        listener.error("Invalid name prefix: "+ prefix);
+                        return;
+                    }
+                    state = STATE_NAME_START;
+                } else if (state == STATE_URI) {
+                    // ignore -> validation of uri later on.
+                } else {
+                    listener.error("'" + c + "' not allowed in name");
+                    return;
+                }
+                trailingSpaces = false;
+            } else if (c == ' ') {
+                if (state == STATE_PREFIX_START || state == STATE_NAME_START) {
+                    listener.error("'" + c + "' not valid name start");
+                    return;
+                }
+                trailingSpaces = true;
+            } else if (Character.isWhitespace(c) || c == '[' || c == ']' || c == '*' || c == '|') {
+                listener.error("'" + c + "' not allowed in name");
+                return;
+            } else if (c == '/') {
+                if (state == STATE_URI_START) {
+                    state = STATE_URI;
+                } else if (state != STATE_URI) {
+                    listener.error("'" + c + "' not allowed in name");
+                    return;
+                }
+                trailingSpaces = false;
+            } else if (c == '{') {
+                if (state == STATE_PREFIX_START) {
+                    state = STATE_URI_START;
+                } else if (state == STATE_URI_START || state == STATE_URI) {
+                    // second '{' in the uri-part -> no valid expanded jcr-name.
+                    // therefore reset the nameStart and change state.
+                    state = STATE_NAME;
+                    nameStart = 0;
+                } else if (state == STATE_NAME_START) {
+                    state = STATE_NAME;
+                    nameStart = i;
+                }
+                trailingSpaces = false;
+            } else if (c == '}') {
+                if (state == STATE_URI_START || state == STATE_URI) {
+                    String tmp = jcrName.substring(1, i);
+                    if (tmp.isEmpty() || tmp.indexOf(':') != -1) {
+                        // The leading "{...}" part is empty or contains
+                        // a colon, so we treat it as a valid namespace URI.
+                        // More detailed validity checks (is it well formed,
+                        // registered, etc.) are not needed here.
+                        state = STATE_NAME_START;
+                    } else if (tmp.equals("internal")) {
+                        // As a special Jackrabbit backwards compatibility
+                        // feature, support {internal} as a valid URI prefix
+                        state = STATE_NAME_START;
+                    } else if (tmp.indexOf('/') == -1) {
+                        // The leading "{...}" contains neither a colon nor
+                        // a slash, so we can interpret it as a a part of a
+                        // normal local name.
+                        state = STATE_NAME;
+                        nameStart = 0;
+                    } else {
+                        listener.error("The URI prefix of the name " + jcrName + " is " +
+                                "neither a valid URI nor a valid part of a local name.");
+                        return;
+                    }
+                } else if (state == STATE_PREFIX_START) {
+                    state = STATE_PREFIX; // prefix start -> validation later on will fail.
+                } else if (state == STATE_NAME_START) {
+                    state = STATE_NAME;
+                    nameStart = i;
+                }
+                trailingSpaces = false;
+            } else {
+                if (state == STATE_PREFIX_START) {
+                    state = STATE_PREFIX; // prefix start
+                } else if (state == STATE_NAME_START) {
+                    state = STATE_NAME;
+                    nameStart = i;
+                } else if (state == STATE_URI_START) {
+                    state = STATE_URI;
+                }
+                trailingSpaces = false;
+            }
+        }
+
+        // take care of qualified jcrNames starting with '{' that are not having
+        // a terminating '}' -> make sure there are no illegal characters present.
+        if (state == STATE_URI && (jcrName.indexOf(':') > -1 || jcrName.indexOf('/') > -1)) {
+            listener.error("Local name may not contain ':' nor '/'");
+            return;
+        }
+
+        if (nameStart == len || state == STATE_NAME_START) {
+            listener.error("Local name must not be empty");
+            return;
+        }
+        if (trailingSpaces) {
+            listener.error("Trailing spaces not allowed");
+            return;
+        }
+
+        listener.name(jcrName);
+    }
+
+}

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java?rev=1330238&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java Wed Apr 25 12:24:43 2012
@@ -0,0 +1,285 @@
+/*
+ * 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;
+
+public class JcrPathParser {
+
+    // constants for parser
+    private static final int STATE_PREFIX_START = 0;
+    private static final int STATE_PREFIX = 1;
+    private static final int STATE_NAME_START = 2;
+    private static final int STATE_NAME = 3;
+    private static final int STATE_INDEX = 4;
+    private static final int STATE_INDEX_END = 5;
+    private static final int STATE_DOT = 6;
+    private static final int STATE_DOTDOT = 7;
+    private static final int STATE_IDENTIFIER = 8;
+    private static final int STATE_URI = 9;
+    private static final int STATE_URI_END = 10;
+
+    private static final char EOF = (char) -1;
+
+    private JcrPathParser() {
+    }
+    
+    interface Listener extends JcrNameParser.Listener {
+        void root();
+        void identifier(String identifier);
+        void current();
+        void parent();
+        void index(int index);
+    }
+
+    public static void parse(String jcrPath, Listener listener) {
+        // check for length
+        int len = jcrPath == null ? 0 : jcrPath.length();
+
+        // shortcut
+        if (len == 1 && jcrPath.charAt(0) == '/') {
+            listener.root();
+        }
+
+        if (len == 0) {
+            listener.error("empty path");
+            return;
+        }
+
+        // check if absolute path
+        int pos = 0;
+        if (jcrPath.charAt(0) == '/') {
+            listener.root();
+            pos++;
+        }
+
+        // parse the path
+        int state;
+        if (jcrPath.charAt(0) == '[') {
+            state = STATE_IDENTIFIER;
+            pos++;
+        } else {
+            state = STATE_PREFIX_START;
+        }
+
+        int lastPos = pos;
+        String name = null;
+
+        int index = 0;
+        boolean wasSlash = false;
+
+        while (pos <= len) {
+            char c = pos == len ? EOF : jcrPath.charAt(pos);
+            pos++;
+            // special check for whitespace
+            if (c != ' ' && Character.isWhitespace(c)) {
+                c = '\t';
+            }
+            
+            switch (c) {
+                case '/':
+                case EOF:
+                    if (state == STATE_PREFIX_START && c != EOF) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. " +
+                                "double slash '//' not allowed.");
+                        return;
+                    }
+                    if (state == STATE_PREFIX
+                            || state == STATE_NAME
+                            || state == STATE_INDEX_END
+                            || state == STATE_URI_END) {
+
+                        // eof path element
+                        if (name == null) {
+                            if (wasSlash) {
+                                listener.error('\'' + jcrPath + "' is not a valid path: " +
+                                        "Trailing slashes not allowed in prefixes and names.");
+                                return;
+                            }
+                            name = jcrPath.substring(lastPos, pos - 1);
+                        }
+
+                        JcrNameParser.parse(name, listener);
+                        listener.index(index);
+                        state = STATE_PREFIX_START;
+                        lastPos = pos;
+                        name = null;
+                        index = 0;
+                    } else if (state == STATE_IDENTIFIER) {
+                        if (c == EOF) {
+                            // eof identifier reached                            
+                            if (jcrPath.charAt(pos - 2) != ']') {
+                                listener.error('\'' + jcrPath + "' is not a valid path: " +
+                                        "Unterminated identifier segment.");
+                                return;
+                            }
+                            String identifier = jcrPath.substring(lastPos, pos - 2);
+                            listener.identifier(identifier);
+                            state = STATE_PREFIX_START;
+                            lastPos = pos;
+                        }
+                    } else if (state == STATE_DOT) {
+                        listener.current();
+                        lastPos = pos;
+                        state = STATE_PREFIX_START;
+                    } else if (state == STATE_DOTDOT) {
+                        listener.parent();
+                        lastPos = pos;
+                        state = STATE_PREFIX_START;
+                    } else if (state != STATE_URI
+                            && !(state == STATE_PREFIX_START && c == EOF)) { // ignore trailing slash
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not a valid name character.");
+                        return;
+                    }
+                    break;
+
+                case '.':
+                    if (state == STATE_PREFIX_START) {
+                        state = STATE_DOT;
+                    } else if (state == STATE_DOT) {
+                        state = STATE_DOTDOT;
+                    } else if (state == STATE_DOTDOT) {
+                        state = STATE_PREFIX;
+                    } else if (state == STATE_INDEX_END) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not valid after index. '/' expected.");
+                        return;
+                    }
+                    break;
+
+                case ':':
+                    if (state == STATE_PREFIX_START) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. Prefix " +
+                                "must not be empty");
+                        return;
+                    } else if (state == STATE_PREFIX) {
+                        if (wasSlash) {
+                            listener.error('\'' + jcrPath + "' is not a valid path: " +
+                                    "Trailing slashes not allowed in prefixes and names.");
+                            return;
+                        }
+                        state = STATE_NAME_START;
+                        // don't reset the lastPos/pos since prefix+name are passed together to the NameResolver
+                    } else if (state != STATE_IDENTIFIER && state != STATE_URI) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not valid name character");
+                        return;
+                    }
+                    break;
+
+                case '[':
+                    if (state == STATE_PREFIX || state == STATE_NAME) {
+                        if (wasSlash) {
+                            listener.error('\'' + jcrPath + "' is not a valid path: " +
+                                    "Trailing slashes not allowed in prefixes and names.");
+                            return;
+                        }
+                        state = STATE_INDEX;
+                        name = jcrPath.substring(lastPos, pos - 1);
+                        lastPos = pos;
+                    } else if (state != STATE_IDENTIFIER) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not a valid name character.");
+                        return;
+                    }
+                    break;
+
+                case ']':
+                    if (state == STATE_INDEX) {
+                        try {
+                            index = Integer.parseInt(jcrPath.substring(lastPos, pos - 1));
+                        } catch (NumberFormatException e) {
+                            listener.error('\'' + jcrPath + "' is not a valid path. " +
+                                    "NumberFormatException in index: " +
+                                    jcrPath.substring(lastPos, pos - 1));
+                            return;
+                        }
+                        if (index < 0) {
+                            listener.error('\'' + jcrPath + "' is not a valid path. " +
+                                    "Index number invalid: " + index);
+                            return;
+                        }
+                        state = STATE_INDEX_END;
+                    } else if (state != STATE_IDENTIFIER) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not a valid name character.");
+                        return;
+                    }
+                    break;
+
+                case ' ':
+                    if (state == STATE_PREFIX_START || state == STATE_NAME_START) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not valid name start");
+                        return;
+                    } else if (state == STATE_INDEX_END) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not valid after index. '/' expected.");
+                        return;
+                    } else if (state == STATE_DOT || state == STATE_DOTDOT) {
+                        state = STATE_PREFIX;
+                    }
+                    break;
+
+                case '\t':
+                    if (state != STATE_IDENTIFIER) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. " +
+                                "Whitespace not a allowed in name.");
+                        return;
+                    }
+                    break;
+                case '*':
+                case '|':
+                    if (state != STATE_IDENTIFIER) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not a valid name character.");
+                        return;
+                    }
+                    break;
+                case '{':
+                    if (state == STATE_PREFIX_START && lastPos == pos-1) {
+                        // '{' marks the start of a uri enclosed in an expanded name
+                        // instead of the usual namespace prefix, if it is
+                        // located at the beginning of a new segment.
+                        state = STATE_URI;
+                    } else if (state == STATE_NAME_START || state == STATE_DOT || state == STATE_DOTDOT) {
+                        // otherwise it's part of the local name
+                        state = STATE_NAME;
+                    }
+                    break;
+
+                case '}':
+                    if (state == STATE_URI) {
+                        state = STATE_URI_END;
+                    }
+                    break;
+
+                default:
+                    if (state == STATE_PREFIX_START || state == STATE_DOT || state == STATE_DOTDOT) {
+                        state = STATE_PREFIX;
+                    } else if (state == STATE_NAME_START) {
+                        state = STATE_NAME;
+                    } else if (state == STATE_INDEX_END) {
+                        listener.error('\'' + jcrPath + "' is not a valid path. '" + c +
+                                "' not valid after index. '/' expected.");
+                        return;
+                    }
+            }
+            wasSlash = c == ' ';
+        }
+    }
+
+}

Modified: 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=1330238&r1=1330237&r2=1330238&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/Paths.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/Paths.java Wed Apr 25 12:24:43 2012
@@ -17,9 +17,12 @@
 package org.apache.jackrabbit.oak.namepath;
 
 import org.apache.jackrabbit.mk.util.PathUtils;
+import org.apache.jackrabbit.oak.namepath.JcrNameParser.Listener;
 import org.apache.jackrabbit.oak.util.Function1;
 
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 import java.util.NoSuchElementException;
 
 /**
@@ -185,49 +188,95 @@ public final class Paths {
         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;
-        }
+    public static String toOakName(String name, final NameMapper nm) {
+        final StringBuilder element = new StringBuilder();
+        
+        Listener listener = new JcrNameParser.Listener() {
+            @Override
+            public void error(String message) {
+                // todo implement error
+            }
 
-        String newPrefix = prefixResolver.apply(prefix);
-        if (newPrefix == null) {
-            throw new IllegalArgumentException("Can't resolve prefix " + prefix);
-        }
-        return newPrefix + ':' + getNameFromElement(element);
+            @Override
+            public void name(String name) {
+                String p = nm.getOakName(name);
+                element.append(p);
+            }
+        };
+
+        JcrNameParser.parse(name, listener);
+        return element.toString();
     }
+    
+    public static String toOakPath(String path, final NameMapper nm) {
+        final List<String> elements = new ArrayList<String>();
+        
+        JcrPathParser.Listener listener = new JcrPathParser.Listener() {
+            @Override
+            public void root() {
+                if (!elements.isEmpty()) {
+                    // todo error
+                }
+                elements.add("");
+            }
 
-    /**
-     * 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();
+            @Override
+            public void identifier(String identifier) {
+                if (!elements.isEmpty()) {
+                    // todo error
+                }
+                elements.add(identifier);  // todo resolve identifier
+                // todo seal
+            }
+
+            @Override
+            public void current() {
+                // nothing to do here
+            }
+
+            @Override
+            public void parent() {
+                if (elements.isEmpty()) {
+                    // todo error
+                }
+                elements.remove(elements.size() - 1);
+            }
 
-        String sep = path.charAt(0) == '/' ? "/" : "";
+            @Override
+            public void index(int index) {
+                if (index > 1) {
+                    // todo error
+                }
+            }
 
-        for (String element : split(path, '/')) {
-            resolved.append(sep).append(resolveElement(element, prefixResolver));
-            sep = "/";
+            @Override
+            public void error(String message) {
+                throw new RuntimeException(message);
+            }
+
+            @Override
+            public void name(String name) {
+                String p = nm.getOakName(name);
+                elements.add(p);
+            }
+        };
+
+        JcrPathParser.parse(path, listener);
+        
+        StringBuilder oakPath = new StringBuilder();
+        for (String element : elements) {
+            if (element.isEmpty()) {
+                // root
+                oakPath.append('/');
+            }
+            else {
+                oakPath.append(element);
+                oakPath.append('/');
+            }
         }
         
-        return resolved.toString();
+        oakPath.deleteCharAt(oakPath.length() - 1);
+        return oakPath.toString();
     }
     
     //------------------------------------------------------------< private >--- 

Modified: 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=1330238&r1=1330237&r2=1330238&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/PathsTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/PathsTest.java Wed Apr 25 12:24:43 2012
@@ -16,32 +16,19 @@
 */
 package org.apache.jackrabbit.oak.namepath;
 
-import org.apache.jackrabbit.oak.util.Function1;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 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;
+import org.junit.Test;
 
 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);
-        }
-    };
 
+    private TestNameMapper mapper = new TestNameMapper();
+    
     @Test
     public void getPrefix() {
         assertEquals(null, Paths.getPrefixFromElement("foo"));
@@ -92,50 +79,50 @@ public class PathsTest {
         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) {
-        }
+    public void testJcrToOak() {
+        assertEquals("/oak-foo:bar", Paths.toOakPath("/foo:bar", mapper));
+        assertEquals("/oak-foo:bar/oak-quu:qux", Paths.toOakPath("/foo:bar/quu:qux", mapper));
+        assertEquals("oak-foo:bar", Paths.toOakPath("foo:bar", mapper));
+        assertEquals("oak-nt:unstructured", Paths.toOakPath("{http://www.jcp.org/jcr/nt/1.0}unstructured", mapper));
+        assertEquals("foobar/oak-jcr:content", Paths.toOakPath("foobar/{http://www.jcp.org/jcr/1.0}content", mapper));
     }
+    
+    private class TestNameMapper extends AbstractNameMapper {
 
-    @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();
+        private Map<String, String> uri2oakprefix = new HashMap<String, String>();
+        
+        public TestNameMapper() {
+            uri2oakprefix.put("", "");
+            uri2oakprefix.put("http://www.jcp.org/jcr/1.0", "jcr");
+            uri2oakprefix.put("http://www.jcp.org/jcr/nt/1.0", "nt");
+            uri2oakprefix.put("http://www.jcp.org/jcr/mix/1.0", "mix");
+            uri2oakprefix.put("http://www.w3.org/XML/1998/namespace", "xml");
         }
-        catch (IllegalArgumentException expected) {
+        
+        @Override
+        protected String getJcrPrefix(String oakPrefix) {
+            if (oakPrefix.length() == 0) {
+                return oakPrefix;
+            } else {
+                return "jcr-" + oakPrefix;
+            }
         }
 
-    }
-
-    @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) {
+        @Override
+        protected String getOakPrefix(String jcrPrefix) {
+            if (jcrPrefix.length() == 0) {
+                return jcrPrefix;
+            } else {
+                return "oak-" + jcrPrefix;
+            }
         }
 
+        @Override
+        protected String getOakPrefixFromURI(String uri) {
+            return "oak-" + uri2oakprefix.get(uri);
+        }
+        
     }
-
-}
+}
\ No newline at end of file