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;
+ }
+ }
}