You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2011/11/03 15:15:31 UTC
svn commit: r1197127 -
/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/
Author: mduerig
Date: Thu Nov 3 14:15:30 2011
New Revision: 1197127
URL: http://svn.apache.org/viewvc?rev=1197127&view=rev
Log:
Microkernel based Jackrabbit prototype (WIP): Javadoc
Modified:
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/FullJsonParser.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonHandler.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonParser.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonTokenizer.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonValue.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/LevelOrderJsonParser.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/ParseException.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java
jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/UnescapingJsonTokenizer.java
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java Thu Nov 3 14:15:30 2011
@@ -24,15 +24,30 @@ import org.apache.jackrabbit.spi2microke
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * This JSON tokenizer operates on a string as its input. For maximal performance
+ * it <em>does not</em> unescape JSON string values.
+ * Use {@link JsonValue#unescape(String)} to unescape the text of {@link Token}s
+ * of type {@link Type#STRING}.
+ *
+ * @see UnescapingJsonTokenizer
+ */
public class DefaultJsonTokenizer extends JsonTokenizer {
private final String json;
private int pos;
+ /**
+ * Create a tokenizer for the given input string
+ * @param json
+ */
public DefaultJsonTokenizer(String json) {
this.json = json;
}
+ /**
+ * @see JsonTokenizer#JsonTokenizer(JsonTokenizer)
+ */
protected DefaultJsonTokenizer(DefaultJsonTokenizer tokenizer) {
super(tokenizer);
json = tokenizer.json;
@@ -84,16 +99,34 @@ public class DefaultJsonTokenizer extend
//------------------------------------------< protected >---
+ /**
+ * Advance {@link #pos()} until the current character is not a
+ * whitespace character.
+ */
protected void skipWhiteSpace() {
while (pos < json.length() && Character.isWhitespace(json.charAt(pos))) {
pos++;
}
}
+ /**
+ * Factory method for creating {@link Token}s
+ * @param type
+ * @param text
+ * @param pos
+ * @return a new token
+ */
protected Token createToken(Type type, String text, int pos) {
return new Token(type, text, pos);
}
+ /**
+ * Read the literal {@code text} and create a token of the given {@code type}
+ * @param type
+ * @param text
+ * @return a new token
+ * @throws ParseException if {@code text} cannot be read at the current position
+ */
protected Token readLiteral(Type type, String text) {
if (json.substring(pos).startsWith(text)) {
Token token = createToken(type, text, pos);
@@ -105,6 +138,11 @@ public class DefaultJsonTokenizer extend
}
}
+ /**
+ * Read a JSON string and create a {@link Token.Type#STRING} token.
+ * @return a new token
+ * @throws ParseException if no string can be read at the current position
+ */
protected Token readString() {
int i;
boolean found = false;
@@ -129,6 +167,11 @@ public class DefaultJsonTokenizer extend
private static final Pattern NUMBER_PATTERN = Pattern.compile(
"(\\+|-)?(\\d+)((\\.)(\\d+))?(((e|E)(\\+|-)?)(\\d+))?");
+ /**
+ * Read a JSON number and create a {@link Token.Type#NUMBER} token.
+ * @return a new token
+ * @throws ParseException if no number can be read at the current position
+ */
protected Token readNumber() {
Matcher matcher = NUMBER_PATTERN.matcher(json.substring(pos));
if (matcher.lookingAt()) {
@@ -141,6 +184,11 @@ public class DefaultJsonTokenizer extend
}
}
+ /**
+ * Read from the current position until a new token starts and create a
+ * {@link Token.Type#UNKNOWN} token.
+ * @return a new token
+ */
protected Token readUnknown() {
int start = pos++;
while (pos < json.length() && "{}[]:,tfn+-0123456789\" ".indexOf(json.charAt(pos)) == -1) {
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/FullJsonParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/FullJsonParser.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/FullJsonParser.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/FullJsonParser.java Thu Nov 3 14:15:30 2011
@@ -26,21 +26,43 @@ import org.apache.jackrabbit.spi2microke
import java.util.ArrayList;
import java.util.LinkedHashMap;
+/**
+ * Utility class for parsing JSON objects and arrays into
+ * {@link JsonObject}s and {@link JsonArray}s, respectively.
+ *
+ * @see LevelOrderJsonParser
+ */
public class FullJsonParser {
private FullJsonParser() { }
+ /**
+ * Parse a JSON object from {@code tokenizer}
+ * @param tokenizer
+ * @return a {@code JsonObject}
+ * @throws ParseException
+ */
public static JsonObject parseObject(JsonTokenizer tokenizer) {
ObjectHandler objectHandler = new ObjectHandler();
new JsonParser(objectHandler).parseObject(tokenizer);
return objectHandler.getObject();
}
+ /**
+ * Parse a JSON array from {@code tokenizer}
+ * @param tokenizer
+ * @return a {@code JsonArray}
+ * @throws ParseException
+ */
public static JsonArray parseArray(JsonTokenizer tokenizer) {
ArrayHandler arrayHandler = new ArrayHandler();
new JsonParser(arrayHandler).parseArray(tokenizer);
return arrayHandler.getArray();
}
+ /**
+ * This implementation of a {@code JsonHandler} builds up a {@code JsonObject}
+ * by recursively descending into its constituents.
+ */
public static class ObjectHandler extends JsonHandler {
private final JsonObject object = new JsonObject(new LinkedHashMap<String, JsonValue>());
@@ -65,6 +87,10 @@ public class FullJsonParser {
}
+ /**
+ * This implementation of a {@code JsonHandler} builds up a {@code JsonArray}
+ * by recursively descending into its constituents.
+ */
public static class ArrayHandler extends JsonHandler {
private final JsonArray array = new JsonArray(new ArrayList<JsonValue>());
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonHandler.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonHandler.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonHandler.java Thu Nov 3 14:15:30 2011
@@ -19,20 +19,65 @@
package org.apache.jackrabbit.spi2microkernel.json;
+/**
+ * Handler for semantic actions of a {@link JsonParser}.
+ * This class provides a handler which fully parses a JSON
+ * document by recursive decent without executing any actions.
+ * <p/>
+ * Override this class to add semantic actions as needed.
+ */
public class JsonHandler {
+
+ /**
+ * Default instance which can be used to skip any part of a
+ * JSON document.
+ */
public static final JsonHandler INSTANCE = new JsonHandler();
-
+
+ /**
+ * A primitive JSON value (ATOM) has been parsed.
+ * @param key
+ * @param value
+ */
public void atom(Token key, Token value) { }
+
+ /**
+ * A COMMA has been parsed
+ * @param token
+ */
public void comma(Token token) { }
+ /**
+ * Parser PAIR. This implementation simply delegates back
+ * to {@link JsonParser#parsePair(JsonTokenizer)}
+ *
+ * @param parser
+ * @param tokenizer
+ */
public void pair(JsonParser parser, JsonTokenizer tokenizer) {
parser.parsePair(tokenizer);
}
+ /**
+ * Parser OBJECT. This implementation simply delegates back
+ * to {@link JsonParser#parseObject(JsonTokenizer)}
+ *
+ * @param parser
+ * @param key
+ * @param tokenizer
+ */
public void object(JsonParser parser, Token key, JsonTokenizer tokenizer) {
parser.parseObject(tokenizer);
}
+ /**
+ * Parser ARRAY. This implementation simply delegates back
+ * to {@link JsonParser#parseArray(JsonTokenizer)}
+ *
+ * @param parser
+ * @param key
+ * @param tokenizer
+ */
public void array(JsonParser parser, Token key, JsonTokenizer tokenizer) {
parser.parseArray(tokenizer);
}
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonParser.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonParser.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonParser.java Thu Nov 3 14:15:30 2011
@@ -22,12 +22,27 @@ package org.apache.jackrabbit.spi2microk
import org.apache.jackrabbit.spi2microkernel.json.Token.Type;
/**
+ * A parser for the JSON format accepting the following grammar:
+ *
* <pre>
* OBJECT ::= { (PAIR (, PAIR)*)? }
* PAIR ::= STRING : VALUE
* VALUE ::= OBJECT | ARRAY | STRING | NUMBER | true | false | null
* ARRAY ::= [ (VALUE (, VALUE)*)? ]
* </pre>
+ *
+ * Semantic actions are attached through a {@link JsonHandler} instance
+ * which is passed to the constructor. For each of the above productions
+ * the parser provides a corresponding method which take a {@link JsonTokenizer}
+ * for reading the JSON input. These methods call the respective call back on the
+ * {@code JsonHandler} for each of the constituents of the production.
+ * <p/>
+ * Note: In contrast to conventional parsers, this parser <em>does not</em>
+ * recursively decent into nested structures (OBJECT, ARRAY and PAIR, that is).
+ * Instead it calls the respective method on the {@code JsonHandler} which
+ * is can use this parser instance or any other parser to continue parsing.
+ *
+ * @see <a href="http://www.json.org/">json.org</a>
*/
public final class JsonParser {
private final JsonHandler jsonHandler;
@@ -36,7 +51,15 @@ public final class JsonParser {
this.jsonHandler = jsonHandler;
}
- /* OBJECT ::= { (PAIR (, PAIR)*)? } */
+ /**
+ * Parses
+ * <pre>
+ * OBJECT ::= { (PAIR (, PAIR)*)? }
+ * </pre>
+ * Calls {@link JsonHandler#comma(Token)}
+ * @param tokenizer
+ * @throws ParseException
+ */
public void parseObject(JsonTokenizer tokenizer) {
tokenizer.read(Type.BEGIN_OBJECT);
@@ -51,7 +74,14 @@ public final class JsonParser {
tokenizer.read(Type.END_OBJECT);
}
- /* PAIR ::= STRING: VALUE */
+ /**
+ * Parses
+ * <pre>
+ * PAIR ::= STRING: VALUE
+ * </pre>
+ * @param tokenizer
+ * @throws ParseException
+ */
public void parsePair(JsonTokenizer tokenizer) {
if (!tokenizer.peek(Type.STRING)) {
throw new ParseException(tokenizer.pos(), "Expected string, found: " + tokenizer.peek());
@@ -62,7 +92,17 @@ public final class JsonParser {
parseValue(key, tokenizer);
}
- /* VALUE ::= OBJECT | ARRAY | STRING | NUMBER | true | false | null */
+ /**
+ * Parses
+ * <pre>
+ * VALUE ::= OBJECT | ARRAY | STRING | NUMBER | true | false | null
+ * </pre>
+ * Calls one of {@link JsonHandler#object(JsonParser, Token, JsonTokenizer)},
+ * {@link JsonHandler#array(JsonParser, Token, JsonTokenizer)} and
+ * {@link JsonHandler#atom(Token, Token)}
+ * @param tokenizer
+ * @throws ParseException
+ */
public void parseValue(Token key, JsonTokenizer tokenizer) {
switch (tokenizer.peek().type()) {
case BEGIN_OBJECT:
@@ -83,7 +123,15 @@ public final class JsonParser {
}
}
- /* ARRAY ::= [ (VALUE (, VALUE)*)? ] */
+ /**
+ * Parses
+ * <pre>
+ * ARRAY ::= [ (VALUE (, VALUE)*)? ]
+ * </pre>
+ * Calls {@link JsonHandler#comma(Token)}
+ * @param tokenizer
+ * @throws ParseException
+ */
public void parseArray(JsonTokenizer tokenizer) {
tokenizer.read(Type.BEGIN_ARRAY);
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonTokenizer.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonTokenizer.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonTokenizer.java Thu Nov 3 14:15:30 2011
@@ -21,15 +21,34 @@ package org.apache.jackrabbit.spi2microk
import org.apache.jackrabbit.spi2microkernel.json.Token.Type;
+/**
+ * Abstract base class for JSON tokenizers.
+ * A JSON tokenizer breaks a stream of character into {@link Token}s. It has
+ * a current {@link #pos() position} and methods for inspecting, reading and
+ * skipping the token at the current position.
+ */
public abstract class JsonTokenizer {
+
+ /**
+ * The current token which has been read ahead, if any.
+ * {@code null} otherwise.
+ */
protected Token currentToken;
+ /**
+ * Copy constructor. To be used in conjunction with {@link #copy()}
+ * @param tokenizer
+ */
protected JsonTokenizer(JsonTokenizer tokenizer) {
currentToken = tokenizer.currentToken;
}
protected JsonTokenizer() { }
+ /**
+ * Returns the current token without advancing the {@link #pos() position}
+ * @return current token
+ */
public Token peek() {
if (currentToken == null) {
currentToken = nextToken();
@@ -38,10 +57,18 @@ public abstract class JsonTokenizer {
return currentToken;
}
+ /**
+ * @param type
+ * @return {@code true} if and only if the current token is of the given {@code type}
+ */
public boolean peek(Type type) {
return peek().type() == type;
}
+ /**
+ * Returns the current token and advances the {@link #pos() position}
+ * @return current token
+ */
public Token read() {
if (currentToken == null) {
return nextToken();
@@ -53,6 +80,13 @@ public abstract class JsonTokenizer {
}
}
+ /**
+ * Returns the current token and advances the {@link #pos() position} if the token
+ * is of the given {@code type}.
+ * @param type
+ * @return current token
+ * @throws ParseException if the token is not of the given {@code type}.
+ */
public Token read(Type type) {
Token token = peek();
if (token.type() == type) {
@@ -63,6 +97,11 @@ public abstract class JsonTokenizer {
}
}
+ /**
+ * Advances the {@link #pos() position} if the token is of the given {@code type}.
+ * @param type
+ * @return {@code true} if and only if the is token is of the given {@code type}.
+ */
public boolean skip(Type type) {
if (peek(type)) {
read();
@@ -73,8 +112,27 @@ public abstract class JsonTokenizer {
}
}
+ /**
+ * @return the current position
+ */
public abstract int pos();
+
+ /**
+ * Set the current position
+ * @param pos
+ */
public abstract void setPos(int pos);
+
+ /**
+ * Create a copy of this tokenizer with the same state. Implementations usually
+ * create a new instance by calling the (overriden) {@link #JsonTokenizer(JsonTokenizer) copy constructor}.
+ * @return copy of this tokenizer
+ */
public abstract JsonTokenizer copy();
+
+ /**
+ * Read the next token from the input and advance the current {@link #pos() positon}.
+ * @return next token
+ */
protected abstract Token nextToken();
}
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonValue.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonValue.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsonValue.java Thu Nov 3 14:15:30 2011
@@ -23,6 +23,11 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+/**
+ * A {@code JsonValue} represents either an {@link JsonArray array}, an
+ * {@link JsonObject object} or a {@link JsonAtom primitive value} (atom)
+ * of a JSON document.
+ */
public abstract class JsonValue {
public enum Type {
STRING(false),
@@ -38,17 +43,29 @@ public abstract class JsonValue {
this.compound = compound;
}
+ /**
+ * @return {@code true} for {@link Type#ARRAY} and {@link Type#OBJECT},
+ * {@code false} otherwise.
+ */
public boolean compound() {
return compound;
}
}
+ /**
+ * Visitor for dispatching compound {@code JsonValue}s.
+ */
public abstract static class Visitor {
public void visit(JsonAtom atom) { }
public void visit(JsonArray array) { }
public void visit(JsonObject object) { }
}
+ /**
+ * Convert {@code jsonValue} to its JSON representation.
+ * @param jsonValue
+ * @return a JSON representation of {@code jsonValue}
+ */
public static String toJson(JsonValue jsonValue) {
final StringBuilder sb = new StringBuilder();
jsonValue.accept(new Visitor() {
@@ -86,12 +103,15 @@ public abstract class JsonValue {
}
/**
- * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
+ * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters
+ * (U+0000 through U+001F) in {@code text}.
+ * @param text
+ * @return {@code text} with control characters escaped
*/
- public static String escape(String string) {
+ public static String escape(String text) {
StringBuilder sb = new StringBuilder();
- for (int i = 0; i < string.length(); i++) {
- char ch = string.charAt(i);
+ for (int i = 0; i < text.length(); i++) {
+ char ch = text.charAt(i);
switch (ch) {
case '"':
sb.append("\\\"");
@@ -137,8 +157,11 @@ public abstract class JsonValue {
}
/**
- * @throws StringIndexOutOfBoundsException
- * @throws NumberFormatException
+ * Unescape escaped control characters in {@code text}
+ * @param text
+ * @return {@code text} with control characters escaped
+ * @throws StringIndexOutOfBoundsException on unterminated escape sequences
+ * @throws NumberFormatException on invalid escape sequences
*/
public static String unescape(String text) {
if (text.length() == 0) {
@@ -185,26 +208,58 @@ public abstract class JsonValue {
return sb.toString();
}
+ /**
+ * @return the value carried by this {@code JsonValue}
+ */
public abstract Object value();
+
+ /**
+ * @return the type of this {@code JsonValue}
+ */
public abstract Type type();
+
+ /**
+ * Dispatch this {@code JsonValue} using {@code visitor}
+ * @param visitor
+ */
public abstract void accept(Visitor visitor);
+ /**
+ * @return {@code this} as {@code JsonAtom}
+ * @throws UnsupportedOperationException if {@code this} is not an instance of {@code JsonAtom}
+ */
public JsonAtom asAtom() {
throw new UnsupportedOperationException();
}
+ /**
+ * @return {@code this} as {@code JsonArray}
+ * @throws UnsupportedOperationException if {@code this} is not an instance of {@code JsonArray}
+ */
public JsonArray asArray() {
throw new UnsupportedOperationException();
}
+ /**
+ * @return {@code this} as {@code JsonObject}
+ * @throws UnsupportedOperationException if {@code this} is not an instance of {@code JsonObject}
+ */
public JsonObject asObject() {
throw new UnsupportedOperationException();
}
+ /**
+ * Convert this {@code JsonValue} to its JSON representation.
+ * @return a JSON representation of this {@code JsonValue}
+ */
public String toJson() {
return toJson(this);
}
+ /**
+ * This class represents primitive JSON values (atoms). These are values of type
+ * {@link Type#STRING} {@link Type#NUMBER} {@link Type#BOOLEAN} and {@link Type#NULL}.
+ */
public static class JsonAtom extends JsonValue {
private final String value;
private final Type type;
@@ -214,6 +269,12 @@ public abstract class JsonValue {
this.type = type;
}
+ /**
+ * Create a new {@code JsonAtom} from {@code token}.
+ * @param token
+ * @throws IllegalArgumentException if {@code token} does not represent
+ * an primitive type (atom).
+ */
public JsonAtom(Token token) {
this(token.text(), valueType(token.type()));
}
@@ -278,6 +339,9 @@ public abstract class JsonValue {
}
}
+ /**
+ * This class represents JSON arrays.
+ */
public static class JsonArray extends JsonValue {
private final List<JsonValue> values;
@@ -285,10 +349,19 @@ public abstract class JsonValue {
this.values = values;
}
+ /**
+ * Append {@code value} to the end of this array.
+ * @param value
+ */
public void add(JsonValue value) {
values.add(value);
}
+ /**
+ * @param index
+ * @return the {@code JsonValue} at {@code index}.
+ * @throws IndexOutOfBoundsException if {@code index} is out of range
+ */
public JsonValue get(int index) {
return values.get(index);
}
@@ -335,6 +408,9 @@ public abstract class JsonValue {
}
}
+ /**
+ * This class represents JSON objects.
+ */
public static class JsonObject extends JsonValue {
private final Map<String, JsonValue> values;
@@ -342,10 +418,20 @@ public abstract class JsonValue {
this.values = values;
}
+ /**
+ * Put {@code value} into this object
+ * @param key
+ * @param value
+ */
public void put(String key, JsonValue value) {
values.put(key, value);
}
+ /**
+ * @param key
+ * @return the {@code JsonValue} identified by {@code key} or {@code null}
+ * if no value exists for {@code key}.
+ */
public JsonValue get(String key) {
return values.get(key);
}
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/LevelOrderJsonParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/LevelOrderJsonParser.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/LevelOrderJsonParser.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/LevelOrderJsonParser.java Thu Nov 3 14:15:30 2011
@@ -27,21 +27,51 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
+/**
+ * Utility class for parsing JSON objects and arrays into {@link JsonObject}s
+ * and {@link JsonArray}s, respectively. In contrast to {@link FullJsonParser},
+ * this implementation resolves nested structures lazily. That, is it does a
+ * level order traverse of the JSON tree.
+ * <p/>
+ * The parser looks for 'hints' in the JSON text to speed up parsing: when it
+ * encounters an integer value with the key ":size" in an object, that value
+ * is used for the size of the entire object (including sub-objects).
+ *
+ * @see FullJsonParser
+ */
public final class LevelOrderJsonParser {
private LevelOrderJsonParser() { }
+ /**
+ * Parse a JSON object from {@code tokenizer}
+ * @param tokenizer
+ * @return a {@code JsonObject}
+ * @throws ParseException
+ */
public static JsonObject parseObject(JsonTokenizer tokenizer) {
ObjectHandler objectHandler = new ObjectHandler();
new JsonParser(objectHandler).parseObject(tokenizer);
return objectHandler.getObject();
}
+ /**
+ * Parse a JSON array from {@code tokenizer}
+ * @param tokenizer
+ * @return a {@code JsonArray}
+ * @throws ParseException
+ */
public static JsonArray parseArray(JsonTokenizer tokenizer) {
ArrayHandler arrayHandler = new ArrayHandler();
new JsonParser(arrayHandler).parseArray(tokenizer);
return arrayHandler.getArray();
}
+ /**
+ * This implementation of a {@code JsonHandler} builds up a {@code JsonObject}
+ * from its constituents. Nested objects are not fully parsed though, but a
+ * reference to the parser is kept which is only invoked when that nested object
+ * is actually accessed.
+ */
public static class ObjectHandler extends JsonHandler {
private final JsonObject object = new JsonObject(new LinkedHashMap<String, JsonValue>());
@@ -67,6 +97,12 @@ public final class LevelOrderJsonParser
}
+ /**
+ * This implementation of a {@code JsonHandler} builds up a {@code JsonArray}
+ * from its constituents. Nested objects are not fully parsed though, but a
+ * reference to the parser is kept which is only invoked when that nested object
+ * is actually accessed.
+ */
public static class ArrayHandler extends JsonHandler {
private final JsonArray array = new JsonArray(new ArrayList<JsonValue>());
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/ParseException.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/ParseException.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/ParseException.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/ParseException.java Thu Nov 3 14:15:30 2011
@@ -19,6 +19,10 @@
package org.apache.jackrabbit.spi2microkernel.json;
+/**
+ * This exception is thrown when a lexical or a syntax error occurs
+ * while parsing a JSON document.
+ */
public class ParseException extends RuntimeException {
public ParseException(int pos, String message) {
super(pos + ": " + message);
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java Thu Nov 3 14:15:30 2011
@@ -19,6 +19,13 @@
package org.apache.jackrabbit.spi2microkernel.json;
+/**
+ * A token represents the smallest lexical unit in a JSON document.
+ * A token has a {@link Type type}, a {@link #text() text} and a
+ * {@link #pos() position} which refers to its place in the originating
+ * JSON document. Note that the position is <em>not</em> taken into account
+ * for equality.
+ */
public final class Token {
private final Type type;
private final String text;
@@ -55,6 +62,10 @@ public final class Token {
return 37 * (37 * (17 + type().hashCode()) + text().hashCode());
}
+ /**
+ * Two tokens are equal if and only if their texts and their types
+ * are equal.
+ */
@Override
public boolean equals(Object other) {
if (other instanceof Token) {
Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/UnescapingJsonTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/UnescapingJsonTokenizer.java?rev=1197127&r1=1197126&r2=1197127&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/UnescapingJsonTokenizer.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/UnescapingJsonTokenizer.java Thu Nov 3 14:15:30 2011
@@ -21,11 +21,18 @@ package org.apache.jackrabbit.spi2microk
import org.apache.jackrabbit.spi2microkernel.json.Token.Type;
+/**
+ * This JSON tokenizer operates on a string as its input. In contrast to
+ * {@link DefaultJsonTokenizer} it <em>does</em> unescape JSON string values.
+ */
public class UnescapingJsonTokenizer extends DefaultJsonTokenizer {
public UnescapingJsonTokenizer(String json) {
super(json);
}
+ /**
+ * @see JsonTokenizer#JsonTokenizer(JsonTokenizer)
+ */
protected UnescapingJsonTokenizer(UnescapingJsonTokenizer tokenizer) {
super(tokenizer);
}