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/12/08 19:18:45 UTC
svn commit: r1212018 [3/7] - in /jackrabbit/sandbox/jackrabbit-microkernel:
./ src/ src/main/ src/main/java/ src/main/java/org/
src/main/java/org/apache/ src/main/java/org/apache/jackrabbit/
src/main/java/org/apache/jackrabbit/configuration/ src/main/j...
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.json;
+
+import org.apache.jackrabbit.json.Token.Type;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * DIFFS ::= DIFF*
+ * DIFF ::= ADD | SET | REMOVE | MOVE | TEST | METADATA | EXTENSION
+ * ADD ::= + STRING : (OBJECT | ATOM | ARRAY)
+ * SET ::= ^ STRING : ATOM | ARRAY
+ * REMOVE ::= - STRING
+ * MOVE ::= > STRING : (STRING | { STRING : STRING })
+ * TEST ::= = STRING : ATOM | ARRAY
+ * METADATA ::= @ OBJECT
+ * EXTENSION ::= OP STRING ":" (OBJECT | ATOM | ARRAY)
+ */
+public class JsopParser {
+ private final JsopHandler jsopHandler;
+
+ public JsopParser(JsopHandler jsopHandler) {
+ this.jsopHandler = jsopHandler;
+ }
+
+ /* DIFFS ::= DIFF* */
+ public void parseJsop(JsonTokenizer tokenizer) {
+ for (Token token = tokenizer.peek(); token.type() != Type.EOF; token = tokenizer.peek()) {
+ parseDiff(tokenizer);
+ }
+ }
+
+ /* DIFF ::= ADD | SET | REMOVE | MOVE */
+ public void parseDiff(JsonTokenizer tokenizer) {
+ Token token = tokenizer.read(Type.UNKNOWN);
+ String text = token.text();
+ if (text.length() != 1) {
+ throw new ParseException(token.pos(), "Expected one of +, -, ^ or >. Found: " + token);
+ }
+
+ switch (text.charAt(0)) {
+ case '+':
+ parseAdd(tokenizer);
+ break;
+ case '-':
+ parseRemove(tokenizer);
+ break;
+ case '^':
+ parseSet(tokenizer);
+ break;
+ case '>':
+ parseMove(tokenizer);
+ break;
+ case '=':
+ parseTest(tokenizer);
+ break;
+ case '@':
+ parseMetadata(tokenizer);
+ break;
+ default:
+ parseExtension(text.charAt(0), tokenizer);
+ }
+ }
+
+ /* ADD ::= + STRING : (OBJECT | ATOM | ARRAY) */
+ public void parseAdd(JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ switch (tokenizer.peek().type()) {
+ case BEGIN_OBJECT:
+ jsopHandler.add(path, tokenizer);
+ break;
+ case BEGIN_ARRAY:
+ jsopHandler.add(path, parseArray(tokenizer));
+ break;
+ default:
+ jsopHandler.add(path, parseAtom(tokenizer));
+ }
+ }
+
+ /* REMOVE ::= - STRING */
+ public void parseRemove(JsonTokenizer tokenizer) {
+ jsopHandler.remove(tokenizer.read(Type.STRING));
+ }
+
+ /* SET ::= ^ STRING : ATOM | ARRAY*/
+ public void parseSet(JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ Token token = tokenizer.peek();
+ switch (token.type()) {
+ case BEGIN_OBJECT:
+ throw new ParseException(token.pos(), "Expected one of atom or array. Found: " + token);
+ case BEGIN_ARRAY:
+ jsopHandler.set(path, parseArray(tokenizer));
+ break;
+ default:
+ jsopHandler.set(path, parseAtom(tokenizer));
+ }
+ }
+
+ /* MOVE ::= > STRING : (STRING | { STRING : STRING }) */
+ public void parseMove(JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ if (tokenizer.peek(Type.BEGIN_OBJECT)) {
+ tokenizer.read(Type.BEGIN_OBJECT);
+ Token position = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ Token target = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.END_OBJECT);
+ jsopHandler.reorder(path, position, target);
+ }
+ else {
+ jsopHandler.move(path, tokenizer.read(Type.STRING));
+ }
+ }
+
+ /* TEST ::= = STRING : ATOM | ARRAY */
+ public void parseTest(JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ Token token = tokenizer.peek();
+ switch (token.type()) {
+ case BEGIN_OBJECT:
+ throw new ParseException(token.pos(), "Expected one of atom or array. Found: " + token);
+ case BEGIN_ARRAY:
+ jsopHandler.test(path, parseArray(tokenizer));
+ break;
+ default:
+ jsopHandler.test(path, parseAtom(tokenizer));
+ }
+ }
+
+ /* METADATA ::= @ OBJECT */
+ public void parseMetadata(JsonTokenizer tokenizer) {
+ jsopHandler.metaData(tokenizer);
+ }
+
+ /* EXTENSION ::= OP STRING ":" (OBJECT | ATOM | ARRAY) */
+ public void parseExtension(char op, JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ switch (tokenizer.peek().type()) {
+ case BEGIN_OBJECT:
+ jsopHandler.extension(op, path, tokenizer);
+ break;
+ case BEGIN_ARRAY:
+ jsopHandler.extension(op, parseArray(tokenizer));
+ break;
+ default:
+ jsopHandler.extension(op, parseAtom(tokenizer));
+ }
+ }
+
+ //------------------------------------------< private >---
+
+ private static Token parseAtom(JsonTokenizer tokenizer) {
+ Token token = tokenizer.peek();
+ Type type = token.type();
+ if (type != Type.TRUE && type != Type.FALSE && type != Type.NULL && type != Type.STRING && type != Type.NUMBER) {
+ throw new ParseException(token.pos(), "Expected one of atom. Found: " + token);
+ }
+ return tokenizer.read();
+ }
+
+ private static Token[] parseArray(JsonTokenizer tokenizer) {
+ final List<Token> values = new ArrayList<Token>();
+
+ new JsonParser(new JsonHandler(){
+ @Override
+ public void atom(Token key, Token value) {
+ values.add(value);
+ }
+ }).parseArray(tokenizer);
+
+ return values.toArray(new Token[values.size()]);
+ }
+
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java.orig
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java.orig?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java.orig (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopParser.java.orig Thu Dec 8 18:18:42 2011
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package michid.jcr.json;
+
+import michid.jcr.json.Token.Type;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * DIFFS ::= DIFF*
+ * DIFF ::= ADD | SET | REMOVE | MOVE
+ * ADD ::= + STRING : (OBJECT | ATOM | ARRAY)
+ * SET ::= ^ STRING : ATOM | ARRAY
+ * REMOVE ::= - STRING
+ * MOVE ::= > STRING : (STRING | { STRING : STRING })
+ */
+public class JsopParser {
+ private final JsopHandler jsopHandler;
+
+ public JsopParser(JsopHandler jsopHandler) {
+ this.jsopHandler = jsopHandler;
+ }
+
+ /* DIFFS ::= DIFF* */
+ public void parseJsop(JsonTokenizer tokenizer) {
+ for (Token token = tokenizer.peek(); token.type() != Type.EOF; token = tokenizer.peek()) {
+ parseDiff(tokenizer);
+ }
+ }
+
+ /* DIFF ::= ADD | SET | REMOVE | MOVE */
+ public void parseDiff(JsonTokenizer tokenizer) {
+ Token token = tokenizer.read(Type.UNKNOWN);
+ String text = token.text();
+ if (text.length() != 1) {
+ throw new ParseException(token.pos(), "Expected one of +, -, ^ or >. Found: " + token);
+ }
+
+ switch (text.charAt(0)) {
+ case '+':
+ parseAdd(tokenizer);
+ break;
+ case '-':
+ parseRemove(tokenizer);
+ break;
+ case '^':
+ parseSet(tokenizer);
+ break;
+ case '>':
+ parseMove(tokenizer);
+ break;
+ default:
+ throw new ParseException(token.pos(), "Expected one of +, -, ^ or >. Found: " + token);
+ }
+ }
+
+ /* ADD ::= + STRING : (OBJECT | ATOM | ARRAY) */
+ public void parseAdd(JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ switch (tokenizer.peek().type()) {
+ case BEGIN_OBJECT:
+ jsopHandler.add(path, tokenizer);
+ break;
+ case BEGIN_ARRAY:
+ jsopHandler.add(path, parseArray(tokenizer));
+ break;
+ default:
+ jsopHandler.add(path, parseAtom(tokenizer));
+ }
+ }
+
+ /* REMOVE ::= - STRING */
+ public void parseRemove(JsonTokenizer tokenizer) {
+ jsopHandler.remove(tokenizer.read(Type.STRING));
+ }
+
+ /* SET ::= ^ STRING : ATOM | ARRAY*/
+ public void parseSet(JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ Token token = tokenizer.peek();
+ switch (token.type()) {
+ case BEGIN_OBJECT:
+ throw new ParseException(token.pos(), "Expected one of atom or array. Found: " + token);
+ case BEGIN_ARRAY:
+ jsopHandler.set(path, parseArray(tokenizer));
+ break;
+ default:
+ jsopHandler.set(path, parseAtom(tokenizer));
+ }
+ if (tokenizer.peek(Type.BEGIN_OBJECT)) {
+ }
+ }
+
+ /* MOVE ::= > STRING : (STRING | { STRING : STRING }) */
+ public void parseMove(JsonTokenizer tokenizer) {
+ Token path = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ if (tokenizer.peek(Type.BEGIN_OBJECT)) {
+ tokenizer.read(Type.BEGIN_OBJECT);
+ Token position = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.COLON);
+ Token target = tokenizer.read(Type.STRING);
+ tokenizer.read(Type.END_OBJECT);
+ jsopHandler.reorder(path, position, target);
+ }
+ else {
+ jsopHandler.move(path, tokenizer.read(Type.STRING));
+ }
+ }
+
+ //------------------------------------------< private >---
+
+ private static Token parseAtom(JsonTokenizer tokenizer) {
+ Token token = tokenizer.peek();
+ Type type = token.type();
+ if (type != Type.TRUE && type != Type.FALSE && type != Type.NULL && type != Type.STRING && type != Type.NUMBER) {
+ throw new ParseException(token.pos(), "Expected one of atom. Found: " + token);
+ }
+ return tokenizer.read();
+ }
+
+ private static Token[] parseArray(JsonTokenizer tokenizer) {
+ final List<Token> values = new ArrayList<Token>();
+
+ new JsonParser(new JsonHandler(){
+ @Override
+ public void atom(Token key, Token value) {
+ values.add(value);
+ }
+ }).parseArray(tokenizer);
+
+ return values.toArray(new Token[values.size()]);
+ }
+
+}
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/LevelOrderJsonParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/LevelOrderJsonParser.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/LevelOrderJsonParser.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/LevelOrderJsonParser.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.json;
+
+import org.apache.jackrabbit.json.JsonValue.JsonArray;
+import org.apache.jackrabbit.json.JsonValue.JsonAtom;
+import org.apache.jackrabbit.json.JsonValue.JsonObject;
+
+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>());
+
+ @Override
+ public void atom(Token key, Token value) {
+ object.put(key.text(), new JsonAtom(value));
+ }
+
+ @Override
+ public void object(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+ object.put(key.text(), new DeferredObjectValue(tokenizer.copy()));
+ tokenizer.setPos(getNextPairPos(tokenizer.copy()));
+ }
+
+ @Override
+ public void array(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+ object.put(key.text(), parseArray(tokenizer));
+ }
+
+ public JsonObject getObject() {
+ return object;
+ }
+
+ }
+
+ /**
+ * 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>());
+
+ @Override
+ public void atom(Token key, Token value) {
+ array.add(new JsonAtom(value));
+ }
+
+ @Override
+ public void object(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+ array.add(new DeferredObjectValue(tokenizer.copy()));
+ tokenizer.setPos(getNextPairPos(tokenizer.copy()));
+ }
+
+ @Override
+ public void array(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+ array.add(parseArray(tokenizer));
+ }
+
+ public JsonArray getArray() {
+ return array;
+ }
+ }
+
+ //------------------------------------------< private >---
+
+ private static class BreakException extends RuntimeException{
+ private static final BreakException BREAK = new BreakException();
+ }
+
+ private static int getNextPairPos(JsonTokenizer tokenizer) {
+ SkipObjectHandler skipObjectHandler = new SkipObjectHandler(tokenizer.pos());
+ try {
+ new JsonParser(skipObjectHandler).parseObject(tokenizer);
+ }
+ catch (BreakException e) {
+ return skipObjectHandler.newPos;
+ }
+ return tokenizer.pos();
+ }
+
+ private static class DeferredObjectValue extends JsonObject {
+ private final JsonTokenizer tokenizer;
+
+ public DeferredObjectValue(JsonTokenizer tokenizer) {
+ super(null);
+ this.tokenizer = tokenizer;
+ }
+
+ @Override
+ public void put(String key, JsonValue value) {
+ throw new IllegalStateException("Cannot add value");
+ }
+
+ @Override
+ public JsonValue get(String key) {
+ return value().get(key);
+ }
+
+ @Override
+ public Map<String, JsonValue> value() {
+ return parseObject(tokenizer.copy()).value();
+ }
+
+ @Override
+ public String toString() {
+ return "<deferred>";
+ }
+
+ }
+
+ private static class SkipObjectHandler extends JsonHandler {
+ private final int startPos;
+ private int newPos;
+
+ public SkipObjectHandler(int startPos) {
+ this.startPos = startPos;
+ }
+
+ @Override
+ public void atom(Token key, Token value) {
+ if (key != null && ":size".equals(key.text()) && Token.Type.NUMBER == value.type()) {
+ newPos = startPos + Integer.parseInt(value.text());
+ throw BreakException.BREAK;
+ }
+ }
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/LevelOrderJsonParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/LevelOrderJsonParser.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/ParseException.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/ParseException.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/ParseException.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/ParseException.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.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);
+ }
+
+ public ParseException(int pos, String message, Throwable cause) {
+ super(pos + ": " + message, cause);
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/ParseException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/ParseException.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/Token.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/Token.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/Token.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/Token.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.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;
+ private final int pos;
+
+ public enum Type {BEGIN_OBJECT, END_OBJECT, BEGIN_ARRAY, END_ARRAY, COLON, COMMA, EOF, TRUE,
+ FALSE, NULL, STRING, NUMBER, UNKNOWN}
+
+ public Token(Type type, String text, int pos) {
+ this.type = type;
+ this.text = text;
+ this.pos = pos;
+ }
+
+ public Type type() {
+ return type;
+ }
+
+ public String text() {
+ return text;
+ }
+
+ public int pos() {
+ return pos;
+ }
+
+ @Override
+ public String toString() {
+ return "Token[" + type + ", " + text + ", " + pos + ']';
+ }
+
+ @Override
+ public int hashCode() {
+ 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) {
+ Token that = (Token) other;
+ return that.type == type && that.text.equals(text);
+ }
+ else {
+ return false;
+ }
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/Token.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/Token.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/UnescapingJsonTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/UnescapingJsonTokenizer.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/UnescapingJsonTokenizer.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/UnescapingJsonTokenizer.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.json;
+
+import org.apache.jackrabbit.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);
+ }
+
+ @Override
+ public UnescapingJsonTokenizer copy() {
+ return new UnescapingJsonTokenizer(this);
+ }
+
+ //------------------------------------------< protected >---
+
+ @Override
+ protected Token createToken(Type type, String text, int pos) {
+ return super.createToken(type, type == Type.STRING ? unescape(text) : text, pos);
+ }
+
+ //------------------------------------------< private >---
+
+ private String unescape(String text) {
+ try {
+ return JsonValue.unescape(text);
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new ParseException(pos(), "Invalid character escaping in string", e);
+ }
+ catch (NumberFormatException e) {
+ throw new ParseException(pos(), "Invalid character escaping in string", e);
+ }
+ }
+
+
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/UnescapingJsonTokenizer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/UnescapingJsonTokenizer.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/Authenticator.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/Authenticator.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/Authenticator.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/Authenticator.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.security;
+
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+
+public interface Authenticator {
+ CredentialsInfo authenticate(Credentials credentials) throws LoginException;
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/Authenticator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/Authenticator.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/AuthenticatorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/AuthenticatorImpl.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/AuthenticatorImpl.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/AuthenticatorImpl.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.security;
+
+
+import javax.jcr.Credentials;
+import javax.jcr.GuestCredentials;
+import javax.jcr.LoginException;
+import javax.jcr.SimpleCredentials;
+
+import java.util.Arrays;
+
+import static java.text.MessageFormat.format;
+
+public class AuthenticatorImpl implements Authenticator {
+ public static final Authenticator INSTANCE = new AuthenticatorImpl();
+
+ private AuthenticatorImpl() {}
+
+ @Override
+ public CredentialsInfo authenticate(Credentials credentials) throws LoginException {
+ // todo implement authentication, split into aggregate of SimpleAuthenticator, GuestAuthenticator, etc
+ if (credentials == null) {
+ return new CredentialsInfo() {
+ @Override
+ public String getUserId() {
+ return "null";
+ }
+
+ @Override
+ public String[] getAttributeNames() {
+ return new String[0];
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return null;
+ }
+ };
+ }
+ else if (credentials instanceof SimpleCredentials) {
+ final SimpleCredentials c = ((SimpleCredentials) credentials);
+ Arrays.fill(c.getPassword(), '\0');
+ return new CredentialsInfo() {
+ @Override
+ public String getUserId() {
+ return c.getUserID();
+ }
+
+ @Override
+ public String[] getAttributeNames() {
+ return c.getAttributeNames();
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return c.getAttribute(name);
+ }
+ };
+ }
+ else if (credentials instanceof GuestCredentials) {
+ return new CredentialsInfo() {
+ @Override
+ public String getUserId() {
+ return "anonymous";
+ }
+
+ @Override
+ public String[] getAttributeNames() {
+ return new String[0];
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return null;
+ }
+ };
+ }
+ else {
+ throw new LoginException(format("Login failed for {0}", credentials));
+ }
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/AuthenticatorImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/AuthenticatorImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/CredentialsInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/CredentialsInfo.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/CredentialsInfo.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/CredentialsInfo.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.security;
+
+public interface CredentialsInfo {
+ String getUserId();
+ String[] getAttributeNames();
+ Object getAttribute(String name);
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/CredentialsInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/security/CredentialsInfo.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeLog.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeLog.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeLog.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeLog.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.state;
+
+import javax.jcr.RepositoryException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChangeLog implements Operation {
+ private final List<Operation> operations = new ArrayList<Operation>();
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ for (Operation operation : operations) {
+ operation.accept(visitor);
+ }
+ }
+
+ public void addOperation(Operation operation) {
+ if (!(operation instanceof ChangeLog)) {
+ operations.add(operation);
+ }
+ }
+
+ public void clear() {
+ operations.clear();
+ }
+
+ public boolean isEmpty() {
+ return operations.isEmpty();
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeLog.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeLog.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeDelta.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeDelta.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeDelta.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeDelta.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.Path;
+import org.apache.jackrabbit.json.JsonValue;
+
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class NodeDelta {
+ private final Map<String, NodeDelta> childNodes = new HashMap<String, NodeDelta>();
+ private final Set<String> removedNodes = new HashSet<String>();
+ private final Map<String, NodeDelta> addedNodes = new HashMap<String, NodeDelta>();
+ private final Map<String, JsonValue> properties = new HashMap<String, JsonValue>();
+ private final Path persistentPath;
+
+ private Path sessionPath;
+
+ public NodeDelta(Path sessionPath, Path persistentPath) {
+ this.sessionPath = sessionPath;
+ this.persistentPath = persistentPath;
+ }
+
+ public boolean hasChildNode(String name) {
+ return childNodes.containsKey(name);
+ }
+
+ public NodeDelta getChildNode(String name) {
+ return childNodes.get(name);
+ }
+
+ public boolean hasRemovedNode(String name) {
+ return removedNodes.contains(name);
+ }
+
+ public Set<String> getRemovedNodes() {
+ return removedNodes;
+ }
+
+ public boolean hasAddedNode(String name) {
+ return addedNodes.containsKey(name);
+ }
+
+ public NodeDelta getAddedNode(String name) {
+ return addedNodes.get(name);
+ }
+
+ public Map<String, NodeDelta> getAddedNodes() {
+ return addedNodes;
+ }
+
+ public boolean hasAddedProperty(String name) {
+ return properties.containsKey(name) && properties.get(name) != null;
+ }
+
+ public boolean hasRemovedProperty(String name) {
+ return properties.containsKey(name) && properties.get(name) == null;
+ }
+
+ public Map<String, JsonValue> getProperties() {
+ return properties;
+ }
+
+ public Path getPersistentPath() {
+ return persistentPath;
+ }
+
+ public Path getSessionPath() {
+ return sessionPath;
+ }
+
+ public void setSessionPath(Path sessionPath) {
+ this.sessionPath = sessionPath;
+ }
+
+ public boolean isNew() {
+ return persistentPath == null;
+ }
+
+ public boolean isModified() {
+ return addedNodes.isEmpty() && removedNodes.isEmpty() && properties.isEmpty();
+ }
+
+ public NodeDelta addNode(String name, NodeDelta delta) throws ItemExistsException {
+ if (childNodes.containsKey(name) || addedNodes.containsKey(name)) {
+ throw new ItemExistsException(name);
+ }
+
+ removedNodes.remove(name);
+ addedNodes.put(name, delta);
+ return delta;
+ }
+
+ public void removeNode(String name) throws ItemNotFoundException {
+ if (removedNodes.contains(name)) {
+ throw new ItemNotFoundException(name);
+ }
+
+ childNodes.remove(name);
+ addedNodes.remove(name);
+ removedNodes.add(name);
+ }
+
+ public NodeDelta addChild(String name, NodeDelta delta) {
+ childNodes.put(name, delta);
+ return delta;
+ }
+
+ public void addProperty(String name, JsonValue value) throws ItemExistsException {
+ if (hasAddedProperty(name)) {
+ throw new ItemExistsException(name);
+ }
+
+ properties.put(name, value);
+ }
+
+ public void setValue(String name, JsonValue value) {
+ properties.put(name, value);
+ }
+
+ public JsonValue getProperty(String name) {
+ return properties.get(name);
+ }
+
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeDelta.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeDelta.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/Operation.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/Operation.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/Operation.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/Operation.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.Path;
+import org.apache.jackrabbit.json.JsonValue;
+import org.apache.jackrabbit.json.JsonValue.JsonArray;
+
+import javax.jcr.RepositoryException;
+
+interface Operation {
+ void accept(Visitor visitor) throws RepositoryException;
+
+ interface Visitor {
+ void visit(AddNode addNode) throws RepositoryException;
+ void visit(AddProperty addProperty) throws RepositoryException;
+ void visit(SetValue setValue) throws RepositoryException;
+ void visit(RemoveNode removeNode) throws RepositoryException;
+ void visit(RemoveProperty removeProperty) throws RepositoryException;
+ void visit(Reorder reorder) throws RepositoryException;
+ void visit(SetMixin setMixin) throws RepositoryException;
+ void visit(SetPrimaryType setPrimaryType) throws RepositoryException;
+ void visit(Move move) throws RepositoryException;
+ }
+
+ class AddNode implements Operation {
+ private final Path parent;
+ private final String name;
+
+ public AddNode(Path parent, String name) {
+ this.parent = parent;
+ this.name = name;
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+
+ public Path getParent() {
+ return parent;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ class AddProperty implements Operation {
+ private final Path parent;
+ private final String name;
+ private final JsonValue value;
+
+ public AddProperty(Path parent, String name, JsonValue value) {
+ this.parent = parent;
+ this.name = name;
+ this.value = value;
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+
+ public Path getParent() {
+ return parent;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public JsonValue getValue() {
+ return value;
+ }
+ }
+
+ class SetValue implements Operation {
+ private final Path path;
+ private final JsonValue value;
+
+ public SetValue(Path path, JsonValue value) {
+ this.path = path;
+ this.value = value;
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ public JsonValue getValue() {
+ return value;
+ }
+ }
+
+ abstract class Remove implements Operation {
+ private final Path path;
+
+ protected Remove(Path path) {
+ this.path = path;
+ }
+
+ public Path getPath() {
+ return path;
+ }
+ }
+
+ class RemoveNode extends Remove {
+ public RemoveNode(Path path) {
+ super(path);
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+ }
+
+ class RemoveProperty extends Remove {
+ public RemoveProperty(Path path) {
+ super(path);
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+ }
+
+ class Reorder implements Operation {
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+ }
+
+ class SetMixin implements Operation {
+ private final Path path;
+ private final JsonArray mixins;
+
+ public SetMixin(Path path, JsonArray mixins) {
+ this.path = path;
+ this.mixins = mixins;
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ public JsonValue getMixins() {
+ return mixins;
+ }
+ }
+
+ class SetPrimaryType implements Operation {
+ private final Path path;
+ private final JsonValue primaryType;
+
+ public SetPrimaryType(Path path, JsonValue primaryType) {
+ this.path = path;
+ this.primaryType = primaryType;
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ public JsonValue getPrimaryType() {
+ return primaryType;
+ }
+ }
+
+ class Move implements Operation {
+ private final Path source;
+ private final Path destination;
+
+ public Move(Path source, Path destination) {
+ this.source = source;
+ this.destination = destination;
+ }
+
+ @Override
+ public void accept(Visitor visitor) throws RepositoryException {
+ visitor.visit(this);
+ }
+
+ public Path getSource() {
+ return source;
+ }
+
+ public Path getDestination() {
+ return destination;
+ }
+ }
+
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/Operation.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/Operation.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.Path;
+import org.apache.jackrabbit.json.JsonValue;
+import org.apache.jackrabbit.json.JsonValue.JsonArray;
+import org.apache.jackrabbit.json.JsonValue.JsonAtom;
+import org.apache.jackrabbit.state.Operation.AddNode;
+import org.apache.jackrabbit.state.Operation.AddProperty;
+import org.apache.jackrabbit.state.Operation.Move;
+import org.apache.jackrabbit.state.Operation.RemoveNode;
+import org.apache.jackrabbit.state.Operation.RemoveProperty;
+import org.apache.jackrabbit.state.Operation.Reorder;
+import org.apache.jackrabbit.state.Operation.SetMixin;
+import org.apache.jackrabbit.state.Operation.SetPrimaryType;
+import org.apache.jackrabbit.state.Operation.SetValue;
+import org.apache.jackrabbit.state.Operation.Visitor;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.api.MicroKernelException;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+
+public class TransientSpace {
+ private final ChangeLog changeLog = new ChangeLog();
+ private final MicroKernel microKernel;
+ private final Path rootPath;
+
+ private String revision;
+ private NodeDelta root;
+
+ public TransientSpace(MicroKernel microKernel, String revision, Path rootPath) {
+ this.microKernel = microKernel;
+ this.rootPath = rootPath;
+ this.revision = revision;
+ root = new NodeDelta(rootPath, rootPath);
+ }
+
+ public void apply(Operation operation) throws RepositoryException {
+ operation.accept(new Visitor() {
+ @Override
+ public void visit(Operation.AddNode addNode) throws RepositoryException {
+ Path parentPath = addNode.getParent();
+ String name = addNode.getName();
+ NodeDelta parent = getOrCreateNodeDelta(parentPath);
+ parent.addNode(name, new NodeDelta(parentPath.concat(name), null));
+ }
+
+ @Override
+ public void visit(Operation.AddProperty addProperty) throws RepositoryException {
+ NodeDelta parent = getOrCreateNodeDelta(addProperty.getParent());
+ parent.addProperty(addProperty.getName(), addProperty.getValue());
+ }
+
+ @Override
+ public void visit(Operation.SetValue setValue) throws RepositoryException {
+ Path path = setValue.getPath();
+ NodeDelta parent = getOrCreateNodeDelta(path.getParent());
+ parent.setValue(path.getName(), setValue.getValue());
+ }
+
+ @Override
+ public void visit(Operation.RemoveNode removeNode) throws RepositoryException {
+ Path path = removeNode.getPath();
+ NodeDelta parent = getOrCreateNodeDelta(path.getParent());
+ parent.removeNode(path.getName());
+ }
+
+ @Override
+ public void visit(RemoveProperty removeProperty) throws RepositoryException {
+ Path path = removeProperty.getPath();
+ NodeDelta parent = getOrCreateNodeDelta(path.getParent());
+ parent.setValue(path.getName(), JsonAtom.NULL);
+ }
+
+ @Override
+ public void visit(Operation.Reorder reorder) {
+ // todo implement visit(Reorder)
+ }
+
+ @Override
+ public void visit(Operation.SetMixin setMixin) throws RepositoryException {
+ NodeDelta parent = getOrCreateNodeDelta(setMixin.getPath());
+ parent.setValue("jcr:mixinTypes", setMixin.getMixins());
+ }
+
+ @Override
+ public void visit(Operation.SetPrimaryType setPrimaryType) throws RepositoryException {
+ NodeDelta parent = getOrCreateNodeDelta(setPrimaryType.getPath());
+ parent.setValue("jcr:primaryType", setPrimaryType.getPrimaryType());
+ }
+
+ @Override
+ public void visit(Operation.Move move) throws RepositoryException {
+ Path source = move.getSource();
+ Path destination = move.getDestination();
+
+ NodeDelta sourceNode = getOrCreateNodeDelta(source);
+ NodeDelta sourceParent = getOrCreateNodeDelta(source.getParent());
+ sourceParent.removeNode(source.getName());
+ sourceNode.setSessionPath(destination);
+
+ NodeDelta destinationParent = getOrCreateNodeDelta(destination.getParent());
+ destinationParent.addNode(destination.getName(), sourceNode);
+ }
+
+ private NodeDelta getOrCreateNodeDelta(Path path) throws PathNotFoundException {
+ String[] names = path.getNames();
+ NodeDelta delta = root;
+ for (String name : names) {
+ if (delta.hasChildNode(name)) {
+ delta = delta.getChildNode(name);
+ }
+ else if (delta.hasAddedNode(name)) {
+ delta = delta.getAddedNode(name);
+ }
+ else if (delta.hasRemovedNode(name)) {
+ throw new PathNotFoundException(path.toString());
+ }
+ else {
+ Path persistedPath = delta.getPersistentPath();
+ if (persistedPath == null) {
+ throw new PathNotFoundException(path.toString());
+ }
+
+ persistedPath = persistedPath.concat(name);
+ if (!microKernel.nodeExists(persistedPath.getMkPath(), revision)) {
+ throw new PathNotFoundException(path.toString());
+ }
+
+ Path sessionPath = delta.getSessionPath().concat(name);
+ delta = delta.addChild(name, new NodeDelta(sessionPath, persistedPath));
+ }
+ }
+ return delta;
+ }
+ });
+
+ changeLog.addOperation(operation);
+ }
+
+ public NodeDelta getNodeDelta(final Path path) {
+ if (!rootPath.getWorkspace().equals(path.getWorkspace())) {
+ return new NodeDelta(path, path);
+ }
+
+ String[] names = path.getNames();
+ NodeDelta delta = root;
+ for (String name : names) {
+ if (delta.hasRemovedNode(name)) {
+ return null;
+ }
+ else if (delta.hasAddedNode(name)) {
+ delta = delta.getAddedNode(name);
+ }
+ else if (delta.hasChildNode(name)) {
+ delta = delta.getChildNode(name);
+ }
+ else {
+ return new NodeDelta(path, path);
+ }
+ }
+ return delta;
+ }
+
+ public ChangeLog getChangeLog() {
+ return changeLog;
+ }
+
+ public String refresh(boolean keepChanges) throws RepositoryException {
+ NodeDelta oldRoot = root;
+ try {
+ root = new NodeDelta(rootPath, rootPath);
+
+ if (keepChanges) {
+ apply(changeLog);
+ }
+ else {
+ changeLog.clear();
+ }
+
+ return revision = microKernel.getHeadRevision();
+ }
+ catch (RepositoryException e) {
+ root = oldRoot;
+ throw e;
+ }
+ }
+
+ public String save() throws RepositoryException {
+ try {
+ final StringBuilder jsop = new StringBuilder();
+
+ changeLog.accept(new Visitor() {
+ @Override
+ public void visit(AddNode addNode) {
+ Path target = addNode.getParent().concat(addNode.getName());
+ jsop.append("+\"")
+ .append(target.getMkPath().substring(1))
+ .append("\":")
+ .append("{}")
+ .append('\n');
+ }
+
+ @Override
+ public void visit(AddProperty addProperty) {
+ Path target = addProperty.getParent().concat(addProperty.getName());
+ jsop.append("^\"")
+ .append(target.getMkPath().substring(1))
+ .append("\":")
+ .append(addProperty.getValue().toJson())
+ .append('\n');
+ }
+
+ @Override
+ public void visit(SetValue setValue) {
+ jsop.append("^\"")
+ .append(setValue.getPath().getMkPath().substring(1))
+ .append("\":")
+ .append(setValue.getValue().toJson())
+ .append('\n');
+ }
+
+ @Override
+ public void visit(RemoveNode removeNode) {
+ jsop.append("-\"")
+ .append(removeNode.getPath().getMkPath().substring(1))
+ .append("\"\n");
+ }
+
+ @Override
+ public void visit(RemoveProperty removeProperty) {
+ jsop.append("^\"")
+ .append(removeProperty.getPath().getMkPath().substring(1))
+ .append("\":null\n");
+ }
+
+ @Override
+ public void visit(Reorder reorder) throws UnsupportedRepositoryOperationException {
+ throw new UnsupportedRepositoryOperationException("Reorder");
+ }
+
+ @Override
+ public void visit(SetMixin setMixin) {
+ Path target = setMixin.getPath().concat("jcr:mixinTypes");
+ jsop.append("^\"")
+ .append(target.getMkPath().substring(1))
+ .append("\":")
+ .append(setMixin.getMixins().toJson())
+ .append('\n');
+ }
+
+ @Override
+ public void visit(SetPrimaryType setPrimaryType) {
+ Path target = setPrimaryType.getPath().concat("jcr:primaryType");
+ jsop.append("^\"")
+ .append(target.getMkPath().substring(1))
+ .append("\":")
+ .append(setPrimaryType.getPrimaryType().toJson())
+ .append('\n');
+ }
+
+ @Override
+ public void visit(Move move) {
+ jsop.append(">\"")
+ .append(move.getSource().getMkPath().substring(1))
+ .append("\":\"")
+ .append(move.getDestination().getMkPath().substring(1))
+ .append("\"\n");
+ }
+ });
+
+ revision = microKernel.commit("/", jsop.toString(), revision, "");
+ root = new NodeDelta(rootPath, rootPath);
+ changeLog.clear();
+ return revision;
+ }
+ catch (MicroKernelException e) {
+ throw new RepositoryException(e.getMessage(), e);
+ }
+ }
+
+ public boolean isDirty() {
+ return !changeLog.isEmpty();
+ }
+
+ //------------------------------------------< convenience >---
+
+ public void addNode(Path parent, String name) throws RepositoryException {
+ apply(new Operation.AddNode(parent, name));
+ }
+
+ public void addProperty(Path parent, String name, JsonValue value) throws RepositoryException {
+ apply(new Operation.AddProperty(parent, name, value));
+ }
+
+ public void setValue(Path path, JsonValue value) throws RepositoryException {
+ apply(new Operation.SetValue(path, value));
+ }
+
+ public void removeNode(Path path) throws RepositoryException {
+ apply(new Operation.RemoveNode(path));
+ }
+
+ public void removeProperty(Path path) throws RepositoryException {
+ apply(new Operation.RemoveProperty(path));
+ }
+
+ public void reorder() throws RepositoryException {
+ apply(new Operation.Reorder());
+ }
+
+ public void setMixin(Path path, JsonArray mixins) throws RepositoryException {
+ apply(new Operation.SetMixin(path, mixins));
+ }
+
+ public void setPrimaryType(Path path, JsonValue type) throws RepositoryException {
+ apply(new Operation.SetPrimaryType(path, type));
+ }
+
+ public void move(Path source, Path target) throws RepositoryException {
+ apply(new Operation.Move(source, target));
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Arrays.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Arrays.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Arrays.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Arrays.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.utils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public final class Arrays {
+ private Arrays() {}
+
+ public static <T> boolean contains(T[] array, T element) {
+ for (T t : array) {
+ if (element == null && t == null || element != null && element.equals(t)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static <T> Set<T> toSet(T... elements) {
+ return new HashSet<T>(java.util.Arrays.asList(elements));
+ }
+
+ public static <T> T[] add(T[] array, T value) {
+ T[] copy = java.util.Arrays.copyOf(array, array.length + 1);
+ copy[array.length] = value;
+ return copy;
+ }
+
+ public static <T> T[] remove(T[] array, T value) {
+ List<T> copy = new ArrayList<T>(array.length);
+ for (T v : array) {
+ if (value == null) {
+ if (v != null) {
+ copy.add(v);
+ }
+ }
+ else if (!value.equals(v)) {
+ copy.add(v);
+ }
+ }
+
+ return (T[]) copy.toArray();
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Arrays.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Arrays.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/ChildItemCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/ChildItemCollector.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/ChildItemCollector.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/ChildItemCollector.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.utils;
+
+import org.apache.jackrabbit.json.JsonValue;
+import org.apache.jackrabbit.spi.commons.iterator.Iterators;
+import org.apache.jackrabbit.spi.commons.iterator.Predicate;
+import org.apache.jackrabbit.spi.commons.iterator.Transformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Item;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.StringTokenizer;
+
+public abstract class ChildItemCollector<T extends Item> implements Iterable<T> {
+ static final Logger log = LoggerFactory.getLogger(ChildItemCollector.class);
+
+ static final char WILDCARD_CHAR = '*';
+ static final String OR = "|";
+
+ private final Iterator<Entry<String, JsonValue>> items;
+
+ protected ChildItemCollector(Iterator<Entry<String, JsonValue>> items) {
+ this.items = items;
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return Iterators.transformIterator(
+ Iterators.filterIterator(items,
+ new Predicate<Entry<String, JsonValue>>() {
+ @Override
+ public boolean evaluate(Entry<String, JsonValue> entry) {
+ return include(entry.getKey(), entry.getValue());
+ }
+ }),
+
+ new Transformer<Entry<String, JsonValue>, T>() {
+ @Override
+ public T transform(Entry<String, JsonValue> entry) {
+ return createItem(entry.getKey(), entry.getValue());
+ }
+ });
+ }
+
+ protected abstract boolean include(String name, JsonValue value);
+ protected abstract T createItem(String name, JsonValue value);
+
+ /**
+ * Matches the name pattern against the specified name.
+ * <p/>
+ * The pattern may be a full name or a partial name with one or more
+ * wildcard characters ("*"), or a disjunction (using the "|" character
+ * to represent logical <i>OR</i>) of these. For example,
+ * <p/>
+ * {@code "jcr:*|foo:bar"}
+ * <p/>
+ * would match
+ * <p/>
+ * {@code "foo:bar"}, but also {@code "jcr:whatever"}.
+ * <p/>
+ * <pre>
+ * The EBNF for pattern is:
+ *
+ * namePattern ::= disjunct {'|' disjunct}
+ * disjunct ::= name [':' name]
+ * name ::= '*' |
+ * ['*'] fragment {'*' fragment}['*']
+ * fragment ::= char {char}
+ * char ::= nonspace | ' '
+ * nonspace ::= (* Any Unicode character except:
+ * '/', ':', '[', ']', '*',
+ * ''', '"', '|' or any whitespace
+ * character *)
+ * </pre>
+ * Note that leading and trailing whitespace around a pattern <i>is</i> ignored.
+ *
+ * @param name the name to test the pattern with
+ * @param pattern the pattern to be matched against the name
+ * @return true if the specified name matches the pattern
+ * @see javax.jcr.Node#getNodes(String)
+ */
+ public static boolean matches(String name, String pattern) {
+ StringTokenizer st = new StringTokenizer(pattern, OR, false);
+ while (st.hasMoreTokens()) {
+ // remove leading & trailing whitespace from token
+ String token = st.nextToken().trim();
+ if (internalMatches(name, token, 0, 0)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Matches the {@code nameGlob} strings in the passed array against
+ * the specified name.
+ * <p>
+ * A glob may be a full name or a partial name with one or more
+ * wildcard characters ("{@code *}").
+ * <p>
+ * Note that unlike in the case of the {@link #matches(String, String)}
+ * leading and trailing whitespace around a glob is <i>not</i> ignored.
+ *
+ * @param name the name to test the pattern with
+ * @param nameGlobs an array of globbing strings
+ * @return true if the specified name matches any of the globs
+ * @see javax.jcr.Node#getNodes(String[])
+ */
+ public static boolean matches(String name, String[] nameGlobs) {
+ for (String nameGlob : nameGlobs) {
+ // use globbing string as-is. Don't trim any leading/trailing whitespace
+ if (internalMatches(name, nameGlob, 0, 0)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Internal helper used to recursively match the pattern
+ *
+ * @param s The string to be tested
+ * @param pattern The pattern
+ * @param sOff offset within {@code s}
+ * @param pOff offset within {@code pattern}.
+ * @return true if {@code s} matched pattern, else false.
+ */
+ private static boolean internalMatches(String s, String pattern, int sOff, int pOff) {
+ int pLen = pattern.length();
+ int sLen = s.length();
+
+ while (true) {
+ if (pOff >= pLen) {
+ if (sOff >= sLen) {
+ return true;
+ } else if (s.charAt(sOff) == '[') {
+ // check for subscript notation (e.g. "whatever[1]")
+ // the entire pattern matched up to the subscript:
+ // -> ignore the subscript
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if (sOff >= sLen && pattern.charAt(pOff) != WILDCARD_CHAR) {
+ return false;
+ }
+
+ // check for a '*' as the next pattern char; this is handled by
+ // a recursive call for each postfix of the name.
+ if (pattern.charAt(pOff) == WILDCARD_CHAR) {
+ if (++pOff >= pLen) {
+ return true;
+ }
+
+ while (true) {
+ if (internalMatches(s, pattern, sOff, pOff)) {
+ return true;
+ }
+ if (sOff >= sLen) {
+ return false;
+ }
+ sOff++;
+ }
+ }
+
+ if (pOff < pLen && sOff < sLen) {
+ if (pattern.charAt(pOff) != s.charAt(sOff)) {
+ return false;
+ }
+ }
+ pOff++;
+ sOff++;
+ }
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/ChildItemCollector.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/ChildItemCollector.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/NodeIteratorAdapter.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/NodeIteratorAdapter.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/NodeIteratorAdapter.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/NodeIteratorAdapter.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.utils;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import java.util.Collection;
+import java.util.Iterator;
+
+public class NodeIteratorAdapter extends RangeIteratorAdapter<Node> implements NodeIterator {
+
+ public NodeIteratorAdapter(Iterator<Node> iterator, long size) {
+ super(iterator, size);
+ }
+
+ public NodeIteratorAdapter(Iterator<Node> iterator) {
+ super(iterator);
+ }
+
+ public NodeIteratorAdapter(Collection<Node> nodes) {
+ super(nodes);
+ }
+
+ @Override
+ public Node nextNode() {
+ return next();
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/NodeIteratorAdapter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/NodeIteratorAdapter.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/PropertyIteratorAdapter.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/PropertyIteratorAdapter.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/PropertyIteratorAdapter.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/PropertyIteratorAdapter.java Thu Dec 8 18:18:42 2011
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.utils;
+
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import java.util.Collection;
+import java.util.Iterator;
+
+public class PropertyIteratorAdapter extends RangeIteratorAdapter<Property> implements PropertyIterator{
+
+ public PropertyIteratorAdapter(Iterator<Property> propertyIterator, long size) {
+ super(propertyIterator, size);
+ }
+
+ public PropertyIteratorAdapter(Iterator<Property> propertyIterator) {
+ super(propertyIterator);
+ }
+
+ public PropertyIteratorAdapter(Collection<Property> properties) {
+ super(properties);
+ }
+
+ @Override
+ public Property nextProperty() {
+ return next();
+ }
+}
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/PropertyIteratorAdapter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/PropertyIteratorAdapter.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL