Return-Path: X-Original-To: apmail-jackrabbit-commits-archive@www.apache.org Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D4AE67F7F for ; Thu, 3 Nov 2011 14:15:55 +0000 (UTC) Received: (qmail 97070 invoked by uid 500); 3 Nov 2011 14:15:55 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 97027 invoked by uid 500); 3 Nov 2011 14:15:55 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 97020 invoked by uid 99); 3 Nov 2011 14:15:55 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Nov 2011 14:15:55 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Nov 2011 14:15:52 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id C2ACD238889B; Thu, 3 Nov 2011 14:15:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1197127 - /jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/ Date: Thu, 03 Nov 2011 14:15:31 -0000 To: commits@jackrabbit.apache.org From: mduerig@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111103141531.C2ACD238889B@eris.apache.org> 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 does not 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()); @@ -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()); 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. + *

+ * 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: + * *

  * OBJECT    ::= { (PAIR (, PAIR)*)? }
  * PAIR      ::= STRING : VALUE
  * VALUE     ::= OBJECT | ARRAY | STRING | NUMBER | true | false | null
  * ARRAY     ::= [ (VALUE (, VALUE)*)? ]
  * 
+ * + * 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. + *

+ * Note: In contrast to conventional parsers, this parser does not + * 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 json.org */ public final class JsonParser { private final JsonHandler jsonHandler; @@ -36,7 +51,15 @@ public final class JsonParser { this.jsonHandler = jsonHandler; } - /* OBJECT ::= { (PAIR (, PAIR)*)? } */ + /** + * Parses + *

+     * OBJECT ::= { (PAIR (, PAIR)*)? }
+     * 
+ * 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 + *
+     * PAIR ::= STRING: VALUE
+     * 
+ * @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 + *
+     * VALUE ::= OBJECT | ARRAY | STRING | NUMBER | true | false | null
+     * 
+ * 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 + *
+     * ARRAY ::= [ (VALUE (, VALUE)*)? ]
+     * 
+ * 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 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 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. + *

+ * 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()); @@ -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()); 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 not 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 does 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); }