You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2011/03/22 13:58:28 UTC
svn commit: r1084154 - in /jackrabbit/sandbox/jackrabbit-j3/src:
main/java/org/apache/jackrabbit/j3/json/JsopTokenizer.java
main/java/org/apache/jackrabbit/j3/mc/Val.java
test/java/org/apache/jackrabbit/j3/json/TestTokenizer.java
Author: thomasm
Date: Tue Mar 22 12:58:27 2011
New Revision: 1084154
URL: http://svn.apache.org/viewvc?rev=1084154&view=rev
Log:
Json/Jsop Tokenizer
Modified:
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/json/JsopTokenizer.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java
jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/json/TestTokenizer.java
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/json/JsopTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/json/JsopTokenizer.java?rev=1084154&r1=1084153&r2=1084154&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/json/JsopTokenizer.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/json/JsopTokenizer.java Tue Mar 22 12:58:27 2011
@@ -24,16 +24,23 @@ public class JsopTokenizer {
// "- " is "patch remove", without space is a negative number
// please note .0 and -.1 are not valid numbers
- final static int END = 0;
- final static int STRING = 1, NUMBER = 2, TRUE = 3, FALSE = 4, NULL = 5, ERROR = 6;
+ final static int STRING = 0, NUMBER = 1, TRUE = 2, FALSE = 3, NULL = 4;
+ final static int ERROR = 5, END = 6;
+
+ private static final String[] TYPE = {
+ "string", "number", "true", "false", "null", "error", "end"
+ };
private final String jsop;
private int pos;
- private int tokenType;
+ private int currentType;
private String currentToken;
+ private int lastType;
+ private String lastToken;
public JsopTokenizer(String json) {
this.jsop = json;
+ read();
}
public String toString() {
@@ -46,7 +53,7 @@ public class JsopTokenizer {
* @return the token type
*/
public int getTokenType() {
- return tokenType;
+ return lastType;
}
/**
@@ -57,7 +64,35 @@ public class JsopTokenizer {
* @return the token
*/
public String getToken() {
- return currentToken;
+ return lastToken;
+ }
+
+ /**
+ * Read a token which must match a given token type.
+ *
+ * @param type the token type
+ * @throws IllegalStateException if the token type doesn't match
+ */
+ public String read(int type) {
+ String token = currentToken;
+ if (matches(type)) {
+ return token;
+ }
+ throw getFormatException(jsop, pos, getTokenType(type));
+ }
+
+ /**
+ * Read a token which must match a given token type.
+ *
+ * @param type the token type
+ * @throws IllegalStateException if the token type doesn't match
+ */
+ public boolean matches(int type) {
+ if (currentType == type) {
+ read();
+ return true;
+ }
+ return false;
}
/**
@@ -66,19 +101,25 @@ public class JsopTokenizer {
* @return the token type
*/
public int read() {
+ lastType = currentType;
+ lastToken = currentToken;
try {
- return readToken();
+ currentType = readToken();
+ } catch (IllegalArgumentException e) {
+ currentType = ERROR;
+ currentToken = e.getMessage();
} catch (StringIndexOutOfBoundsException e) {
- tokenType = ERROR;
- throw getFormatException(jsop, pos);
+ currentType = ERROR;
+ currentToken = addAsterisk(jsop, pos);
}
+ return lastType;
}
private int readToken() {
char ch;
while (true) {
if (pos >= jsop.length()) {
- return tokenType = END;
+ return END;
}
ch = jsop.charAt(pos);
if (ch > ' ') {
@@ -101,12 +142,11 @@ public class JsopTokenizer {
}
String s = jsop.substring(start + 1, pos - 1);
if (escaped) {
- currentToken = jsonDecode(s);
+ currentToken = decode(s);
} else {
currentToken = s;
}
- tokenType = STRING;
- break;
+ return STRING;
}
case '{':
case '}':
@@ -115,19 +155,16 @@ public class JsopTokenizer {
case '+':
case ':':
case ',':
- tokenType = ch;
- break;
+ return ch;
case '-':
ch = jsop.charAt(pos);
if (ch < '0' || ch > '9') {
// lookahead
- tokenType = '-';
- break;
+ return '-';
}
// else fall though
default:
if (ch >= '0' && ch <= '9') {
- tokenType = NUMBER;
while (pos < jsop.length()) {
ch = jsop.charAt(pos);
if (ch < '0' || ch > '9') {
@@ -159,6 +196,7 @@ public class JsopTokenizer {
}
}
currentToken = jsop.substring(start, pos);
+ return NUMBER;
} else if (ch >= 'a' && ch <= 'z') {
while (pos < jsop.length()) {
ch = jsop.charAt(pos);
@@ -169,22 +207,19 @@ public class JsopTokenizer {
}
String s = jsop.substring(start, pos);
if ("null".equals(s)) {
- tokenType = NULL;
+ return NULL;
} else if ("true".equals(s)) {
- tokenType = TRUE;
+ return TRUE;
} else if ("false".equals(s)) {
- tokenType = FALSE;
+ return FALSE;
} else {
- tokenType = ERROR;
+ // currentToken = s;
+ // return STRING;
throw getFormatException(jsop, pos);
}
- break;
- } else {
- tokenType = ERROR;
- throw getFormatException(jsop, pos);
}
+ throw getFormatException(jsop, pos);
}
- return tokenType;
}
/**
@@ -193,7 +228,7 @@ public class JsopTokenizer {
* @param s the encoded string
* @return the string
*/
- public static String jsonDecode(String s) {
+ public static String decode(String s) {
int length = s.length();
StringBuilder buff = new StringBuilder(length);
for (int i = 0; i < length; i++) {
@@ -257,7 +292,7 @@ public class JsopTokenizer {
* @param s the text to convert
* @return the Json representation (including double quotes)
*/
- public static String jsonEncode(String s) {
+ public static String encode(String s) {
int length = s.length();
StringBuilder buff = new StringBuilder(length + 2);
buff.append('\"');
@@ -307,6 +342,14 @@ public class JsopTokenizer {
return buff.toString();
}
+ private static String getTokenType(int type) {
+ return type <= END ? TYPE[type] : "'" + (char) type + "'";
+ }
+
+ private static IllegalArgumentException getFormatException(String s, int i, String expected) {
+ return new IllegalArgumentException(addAsterisk(s, i) + " expected: " + expected);
+ }
+
private static IllegalArgumentException getFormatException(String s, int i) {
return new IllegalArgumentException(addAsterisk(s, i));
}
@@ -320,7 +363,8 @@ public class JsopTokenizer {
* @return the text with asterisk
*/
private static String addAsterisk(String s, int index) {
- if (s != null && index < s.length()) {
+ if (s != null) {
+ index = Math.min(index, s.length());
s = s.substring(0, index) + "[*]" + s.substring(index);
}
return s;
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java?rev=1084154&r1=1084153&r2=1084154&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java Tue Mar 22 12:58:27 2011
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.j3.mc;
import java.util.Arrays;
import java.util.HashMap;
import javax.jcr.PropertyType;
+import org.apache.jackrabbit.j3.json.JsopTokenizer;
import org.apache.jackrabbit.j3.util.Constants;
import org.apache.jackrabbit.j3.util.ExceptionFactory;
@@ -303,10 +304,18 @@ public class Val implements Comparable<V
return buff.append(" ]").toString();
}
case TYPE_BINARY_REFERENCE: {
- return "binaryRef:" + value;
+ return "/* binaryRef */ \"" + value + "\"";
}
+ case PropertyType.BOOLEAN:
+ case PropertyType.LONG:
+ return value.toString();
+ case PropertyType.DECIMAL:
+ case PropertyType.DOUBLE:
+ return "/* " + PropertyType.nameFromValue(type) + " */ " + value.toString();
+ case PropertyType.STRING:
+ return JsopTokenizer.encode(value.toString());
default:
- return value + ":" + PropertyType.nameFromValue(type);
+ return "/* " + PropertyType.nameFromValue(type) + " */ " + JsopTokenizer.encode(value.toString());
}
}
Modified: jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/json/TestTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/json/TestTokenizer.java?rev=1084154&r1=1084153&r2=1084154&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/json/TestTokenizer.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/json/TestTokenizer.java Tue Mar 22 12:58:27 2011
@@ -25,31 +25,32 @@ public class TestTokenizer extends TestC
public void test() {
try {
- JsopTokenizer.jsonDecode("test\\");
+ JsopTokenizer.decode("test\\");
fail();
} catch (IllegalArgumentException e) {
// ok
}
try {
- JsopTokenizer.jsonDecode("wrong\\uxxxx");
+ JsopTokenizer.decode("wrong\\uxxxx");
fail();
} catch (IllegalArgumentException e) {
// ok
}
try {
- JsopTokenizer.jsonDecode("wrong\\m");
+ JsopTokenizer.decode("wrong\\m");
fail();
} catch (IllegalArgumentException e) {
// ok
}
- test("/* error */", "\"\\");
- test("/* error */1", ".1");
+ test("/error/", "\"\\");
+ test("/error/1", ".1");
assertEquals("x", new JsopTokenizer("x").toString());
- test("/* error */", "true" + "true");
- test("/* error */", "truer");
- test("/* error */", "falsehood");
- test("/* error */", "nil");
- test("/* error */", "\"invalid");
+ test("/error/", "true" + "true");
+ test("/error/", "truer");
+ test("/error/", "falsehood");
+ test("/error/", "nil");
+ test("/error/1", "nil 1");
+ test("/error/", "\"invalid");
test("- \"test/test\"", "-\"test\\/test\"");
test(" {\n\"x\": 1, \"y\": 2\n}\n", "{\"x\":1, \"y\":2}");
test(" [\ntrue, false, null\n]\n", "[true, false, null]");
@@ -59,6 +60,25 @@ public class TestTokenizer extends TestC
test("\"Hello\"", "\"Hello\"");
test(" [\n\n]\n", "[]");
test(" {\n\n}\n", "{}");
+
+ JsopTokenizer t = new JsopTokenizer("{}123");
+ assertFalse(t.matches('+'));
+ assertTrue(t.matches('{'));
+ t.read('}');
+
+ try {
+ t.read('+');
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("{}123[*] expected: '+'", e.getMessage());
+ }
+ try {
+ t.read(JsopTokenizer.STRING);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("{}123[*] expected: string", e.getMessage());
+ }
+
}
static void test(String expected, String json) {
@@ -70,30 +90,20 @@ public class TestTokenizer extends TestC
StringBuilder buff = new StringBuilder();
JsopTokenizer t = new JsopTokenizer(jsop);
while (true) {
- try {
- prettyPrint(buff, t);
- } catch (IllegalArgumentException e) {
- buff.append("/* error */");
- }
+ prettyPrint(buff, t);
if (t.getTokenType() == JsopTokenizer.END) {
return buff.toString();
}
}
}
- static String prettyPrint(String jsop) {
- StringBuilder buff = new StringBuilder();
- JsopTokenizer t = new JsopTokenizer(jsop);
- return prettyPrint(buff, t);
- }
-
static String prettyPrint(StringBuilder buff, JsopTokenizer t) {
while (true) {
switch (t.read()) {
case JsopTokenizer.END:
return buff.toString();
case JsopTokenizer.STRING:
- buff.append(JsopTokenizer.jsonEncode(t.getToken()));
+ buff.append(JsopTokenizer.encode(t.getToken()));
break;
case JsopTokenizer.NUMBER:
buff.append(t.getToken());
@@ -107,6 +117,9 @@ public class TestTokenizer extends TestC
case JsopTokenizer.NULL:
buff.append("null");
break;
+ case JsopTokenizer.ERROR:
+ buff.append("/error/");
+ break;
case '{':
buff.append(" {\n");
break;
@@ -135,7 +148,7 @@ public class TestTokenizer extends TestC
buff.append("^ ");
break;
default:
- throw new IllegalArgumentException("token type: " + t.getTokenType());
+ throw new AssertionError("token type: " + t.getTokenType());
}
}
}