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 th...@apache.org on 2013/04/16 13:37:46 UTC

svn commit: r1468377 - in /jackrabbit/oak/trunk/oak-mongomk/src: main/java/org/apache/jackrabbit/mongomk/ test/java/org/apache/jackrabbit/mongomk/

Author: thomasm
Date: Tue Apr 16 11:37:45 2013
New Revision: 1468377

URL: http://svn.apache.org/r1468377
Log:
OAK-771 Correct behavior for strange node and property names

Modified:
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoDocumentStore.java
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoMK.java
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/Utils.java
    jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/SimpleTest.java

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoDocumentStore.java?rev=1468377&r1=1468376&r2=1468377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoDocumentStore.java Tue Apr 16 11:37:45 2013
@@ -49,6 +49,11 @@ import com.mongodb.WriteResult;
 public class MongoDocumentStore implements DocumentStore {
 
     private static final Logger LOG = LoggerFactory.getLogger(MongoDocumentStore.class);
+    
+    /**
+     * The number of documents to cache.
+     */
+    private static final int CACHE_DOCUMENTS = Integer.getInteger("oak.mongoMK.cacheDocs", 20 * 1024);
 
     private static final boolean LOG_TIME = false;
 
@@ -78,7 +83,7 @@ public class MongoDocumentStore implemen
 
         // TODO expire entries if the parent was changed
         nodesCache = CacheBuilder.newBuilder()
-                .maximumSize(MongoMK.CACHE_DOCUMENTS)
+                .maximumSize(CACHE_DOCUMENTS)
                 .build();
         
     }

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoMK.java?rev=1468377&r1=1468376&r2=1468377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoMK.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/MongoMK.java Tue Apr 16 11:37:45 2013
@@ -62,11 +62,6 @@ public class MongoMK implements MicroKer
     private static final Logger LOG = LoggerFactory.getLogger(MongoMK.class);
 
     /**
-     * The number of documents to cache.
-     */
-    static final int CACHE_DOCUMENTS = Integer.getInteger("oak.mongoMK.cacheDocs", 20 * 1024);
-
-    /**
      * The number of child node list entries to cache.
      */
     private static final int CACHE_CHILDREN = Integer.getInteger("oak.mongoMK.cacheChildren", 1024);

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/Utils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/Utils.java?rev=1468377&r1=1468376&r2=1468377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/Utils.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/Utils.java Tue Apr 16 11:37:45 2013
@@ -75,22 +75,71 @@ public class Utils {
     }
 
     public static String escapePropertyName(String propertyName) {
-        String key = propertyName;
-        if (key.startsWith("$") || key.startsWith("_")) {
-            key = "_" + key;
-        }
-        // '*' in a property name is illegal in JCR I believe
-        // TODO find a better solution
-        key = key.replace('.', '*');
-        return key;
+        int len = propertyName.length();
+        if (len == 0) {
+            return "_";
+        }
+        // avoid creating a buffer if escaping is not needed
+        StringBuilder buff = null;
+        char c = propertyName.charAt(0);
+        int i = 0;
+        if (c == '_' || c == '$') {
+            buff = new StringBuilder(len + 1);
+            buff.append('_').append(c);
+            i++;
+        }
+        for (; i < len; i++) {
+            c = propertyName.charAt(i);
+            char rep;
+            switch (c) {
+            case '.':
+                rep = 'd';
+                break;
+            case '\\':
+                rep = '\\';
+                break;
+            default:
+                rep = 0;
+            }
+            if (rep != 0) {
+                if (buff == null) {
+                    buff = new StringBuilder(propertyName.substring(0, i));
+                }
+                buff.append('\\').append(rep);
+            } else if (buff != null) {
+                buff.append(c);
+            }
+        }
+        return buff == null ? propertyName : buff.toString();
     }
     
     public static String unescapePropertyName(String key) {
-        if (key.startsWith("__") || key.startsWith("_$")) {
+        int len = key.length();
+        if (key.startsWith("_")
+                && (key.startsWith("__") || key.startsWith("_$") || len == 1)) {
             key = key.substring(1);
+            len--;
+        }
+        // avoid creating a buffer if escaping is not needed
+        StringBuilder buff = null;
+        for (int i = 0; i < len; i++) {
+            char c = key.charAt(i);
+            if (c == '\\') {
+                if (buff == null) {
+                    buff = new StringBuilder(key.substring(0, i));
+                }
+                c = key.charAt(++i);
+                if (c == '\\') {
+                    // ok
+                } else if (c == 'd') {
+                    c = '.';
+                }
+                buff.append(c);
+            } else if (buff != null) {
+                buff.append(c);
+            }
         }
-        key = key.replace('*', '.');
-        return key;
+        return buff == null ? key : buff.toString();
     }
     
     public static boolean isPropertyName(String key) {

Modified: jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/SimpleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/SimpleTest.java?rev=1468377&r1=1468376&r2=1468377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/SimpleTest.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/SimpleTest.java Tue Apr 16 11:37:45 2013
@@ -23,11 +23,12 @@ import static org.junit.Assert.assertTru
 import static org.junit.Assert.fail;
 
 import java.util.Map;
+import java.util.Random;
 
 import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mk.json.JsopBuilder;
 import org.apache.jackrabbit.mongomk.DocumentStore.Collection;
 import org.apache.jackrabbit.mongomk.Node.Children;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import com.google.common.collect.Lists;
@@ -292,28 +293,80 @@ public class SimpleTest {
     }
     
     @Test
-    @Ignore
-    // OAK-771 (WIP)
+    public void escapeUnescape() {
+        MongoMK mk = createMK();
+        String rev;
+        String nodes; 
+        Random r = new Random(1);
+        for (int i = 0; i < 20; i++) {
+            int len = 1 + r.nextInt(5);
+            StringBuilder buff = new StringBuilder();
+            for (int j = 0; j < len; j++) {
+                buff.append((char) (32 + r.nextInt(128)));
+            }
+            String s = buff.toString();
+            String x2 = Utils.escapePropertyName(s);
+            String s2 = Utils.unescapePropertyName(x2);
+            if (!s.equals(s2)) {
+                assertEquals(s, s2);
+            }
+            if (s.indexOf('/') >= 0) {
+                continue;
+            }
+            JsopBuilder jsop = new JsopBuilder();
+            jsop.tag('+').key(s).object().key(s).value("x").endObject();
+            rev = mk.commit("/", jsop.toString(), 
+                    null, null);
+            nodes = mk.getNodes("/" + s, rev, 0, 0, 10, null);
+            jsop = new JsopBuilder();
+            jsop.object().key(s).value("x").
+                    key(":childNodeCount").value(0).endObject();
+            String n = jsop.toString();
+            assertEquals(n, nodes);
+            nodes = mk.getNodes("/", rev, 0, 0, 10, null);
+            jsop = new JsopBuilder();
+            jsop.object().key(s).object().endObject().
+            key(":childNodeCount").value(1).endObject();
+            n = jsop.toString();
+            assertEquals(n, nodes);
+            jsop = new JsopBuilder();
+            jsop.tag('-').value(s);
+            rev = mk.commit("/", jsop.toString(), rev, null);
+            
+        }
+    }
+    
+    @Test
     public void nodeAndPropertyNames() {
         MongoMK mk = createMK();
-
-        mk.commit("/", "+\"0\":{\"name\": \"Hello\"}", null, null);
-        mk.commit("/testDel", "+\"a\":{\"name\": \"World\"}", null, null);
-        mk.commit("/testDel", "+\"b\":{\"name\": \"!\"}", null, null);
-        String r1 = mk.commit("/testDel", "+\"c\":{\"name\": \"!\"}", null, null);
-
-        Children c = mk.getChildren("/testDel", Revision.fromString(r1),
-                Integer.MAX_VALUE);
-        assertEquals(3, c.children.size());
-
-        String r2 = mk.commit("/testDel", "-\"c\"", null, null);
-        c = mk.getChildren("/testDel", Revision.fromString(r2),
-                Integer.MAX_VALUE);
-        assertEquals(2, c.children.size());
-
-        String r3 = mk.commit("/", "-\"testDel\"", null, null);
-        Node n = mk.getNode("/testDel", Revision.fromString(r3));
-        assertNull(n);
+        String rev;
+        String nodes; 
+        for (String s : new String[] { "_", "$", "__", "_id", "$x", ".", ".\\", "x\\", "\\x", "first.name" }) {
+            String x2 = Utils.escapePropertyName(s);
+            String s2 = Utils.unescapePropertyName(x2);
+            if (!s.equals(s2)) {
+                assertEquals(s, s2);
+            }
+            JsopBuilder jsop = new JsopBuilder();
+            jsop.tag('+').key(s).object().key(s).value("x").endObject();
+            rev = mk.commit("/", jsop.toString(), 
+                    null, null);
+            nodes = mk.getNodes("/" + s, rev, 0, 0, 10, null);
+            jsop = new JsopBuilder();
+            jsop.object().key(s).value("x").
+                    key(":childNodeCount").value(0).endObject();
+            String n = jsop.toString();
+            assertEquals(n, nodes);
+            nodes = mk.getNodes("/", rev, 0, 0, 10, null);
+            jsop = new JsopBuilder();
+            jsop.object().key(s).object().endObject().
+            key(":childNodeCount").value(1).endObject();
+            n = jsop.toString();
+            assertEquals(n, nodes);
+            jsop = new JsopBuilder();
+            jsop.tag('-').value(s);
+            rev = mk.commit("/", jsop.toString(), rev, null);
+        }
     }
 
     @Test