You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2011/12/01 15:43:13 UTC

svn commit: r1209107 - /jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java

Author: stefan
Date: Thu Dec  1 14:43:11 2011
New Revision: 1209107

URL: http://svn.apache.org/viewvc?rev=1209107&view=rev
Log:
experimental mongodb support: verbose serialization format for debug purposes

Modified:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java?rev=1209107&r1=1209106&r2=1209107&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java Thu Dec  1 14:43:11 2011
@@ -38,7 +38,9 @@ import org.bson.types.ObjectId;
 import java.io.File;
 import java.io.InputStream;
 import java.security.MessageDigest;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.Map;
 
 /**
  *
@@ -124,8 +126,8 @@ public class MongoPersistenceManager ext
                 return Serializer.fromBytes(id, bytes, Node.class);
             } else {
                 return new StoredNode(id,
-                        ((BasicDBObject) nodeObject.get(PROPERTIES_OBJECT)).toMap(),
-                        (LinkedHashMap<String, String>) ((BasicDBObject) nodeObject.get(PROPERTIES_OBJECT)).toMap());
+                        decodeKeys(((BasicDBObject) nodeObject.get(PROPERTIES_OBJECT)).toMap()),
+                        (LinkedHashMap<String, String>) decodeKeys(((BasicDBObject) nodeObject.get(CHILDREN_OBJECT)).toMap()));
             }
         } else {
             throw new NotFoundException(id);
@@ -143,8 +145,8 @@ public class MongoPersistenceManager ext
             nodeObject = new BasicDBObject(ID_FIELD, key).append(DATA_FIELD, bytes);
         } else {
             nodeObject = new BasicDBObject(ID_FIELD, id)
-                    .append(PROPERTIES_OBJECT, new BasicDBObject(node.getProperties()))
-                    .append(CHILDREN_OBJECT, new BasicDBObject(node.getChildNodeEntries()));
+                    .append(PROPERTIES_OBJECT, new BasicDBObject(encodeKeys(node.getProperties())))
+                    .append(CHILDREN_OBJECT, new BasicDBObject(encodeKeys(node.getChildNodeEntries())));
         }
         try {
             nodes.insert(nodeObject);
@@ -240,4 +242,115 @@ public class MongoPersistenceManager ext
 
         return f.getLength();
     }
+
+    protected static Map<String, String> encodeKeys(Map<String, String> map) {
+        boolean needsEncoding = false;
+        for (String key : map.keySet()) {
+            if (needsEncoding = needsEncoding(key)) {
+                break;
+            }
+        }
+        if (!needsEncoding) {
+            return map;
+        }
+        Map<String, String> result;
+        if (map instanceof LinkedHashMap) {
+            result = new LinkedHashMap<String, String>(map.size());
+        } else {
+            result = new HashMap<String, String>(map.size());
+        }
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            result.put(encodeName(entry.getKey()), entry.getValue());
+        }
+        return result;
+    }
+
+    protected static Map<String, String> decodeKeys(Map<String, String> map) {
+        boolean needsDecoding = false;
+        for (String key : map.keySet()) {
+            if (needsDecoding = needsDecoding(key)) {
+                break;
+            }
+        }
+        if (!needsDecoding) {
+            return map;
+        }
+        Map<String, String> result;
+        if (map instanceof LinkedHashMap) {
+            result = new LinkedHashMap<String, String>(map.size());
+        } else {
+            result = new HashMap<String, String>(map.size());
+        }
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            result.put(decodeName(entry.getKey()), entry.getValue());
+        }
+        return result;
+    }
+
+    protected final static String ENCODED_DOT = "_x46_";
+    protected final static String ENCODED_DOLLAR_SIGN = "_x36_";
+
+    protected static boolean needsEncoding(String name) {
+        return name.startsWith("$") || name.indexOf('.') != -1;
+    }
+
+    protected static boolean needsDecoding(String name) {
+        return name.startsWith(ENCODED_DOLLAR_SIGN) || name.indexOf(ENCODED_DOT) != -1;
+    }
+
+    /**
+     * see http://www.mongodb.org/display/DOCS/Legal+Key+Names
+     *
+     * @param name
+     * @return
+     */
+    protected static String encodeName(String name) {
+        StringBuilder buf = null;
+        for (int i = 0; i < name.length(); i++) {
+            if (i == 0 && name.charAt(i) == '$') {
+                // mongodb field names must not start with '$'
+                buf = new StringBuilder();
+                buf.append(ENCODED_DOLLAR_SIGN);
+            } else if (name.charAt(i) == '.') {
+                // . is a reserved char for mongodb field names
+                if (buf == null) {
+                    buf = new StringBuilder(name.substring(0, i));
+                }
+                buf.append(ENCODED_DOT);
+            } else {
+                if (buf != null) {
+                    buf.append(name.charAt(i));
+                }
+            }
+        }
+
+        return buf == null ? name : buf.toString();
+    }
+
+    protected static String decodeName(String name) {
+        StringBuilder buf = null;
+
+        int lastPos = 0;
+        if (name.startsWith(ENCODED_DOLLAR_SIGN)) {
+            buf = new StringBuilder("$");
+            lastPos = ENCODED_DOLLAR_SIGN.length();
+        }
+
+        int pos = -1;
+        while ((pos = name.indexOf(ENCODED_DOT, lastPos)) != -1) {
+            if (buf == null) {
+                buf = new StringBuilder();
+            }
+            buf.append(name.substring(lastPos, pos));
+            buf.append('.');
+            lastPos = pos + ENCODED_DOT.length();
+        }
+
+        if (buf != null) {
+            buf.append(name.substring(lastPos));
+            return buf.toString();
+        } else {
+            return name;
+        }
+    }
 }