Repository: incubator-ignite Updated Branches: refs/heads/ignite-961-javax-json [created] debed8a5b
#ignite-961-javax-json: start implementing. Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/debed8a5 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/debed8a5 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/debed8a5 Branch: refs/heads/ignite-961-javax-json Commit: debed8a5bb18179846c819447b8eca93fde9e1bf Parents: 6a61819 Author: ivasilinets <ivasilin...@gridgain.com> Authored: Wed Jul 15 18:08:00 2015 +0300 Committer: ivasilinets <ivasilin...@gridgain.com> Committed: Wed Jul 15 18:08:00 2015 +0300 ---------------------------------------------------------------------- modules/core/pom.xml | 12 +- .../org/apache/ignite/json/JSONCacheObject.java | 3 + .../json/javax/json/JsonArrayBuilderImpl.java | 140 ++++++ .../ignite/json/javax/json/JsonArrayImpl.java | 136 +++++ .../json/javax/json/JsonGeneratorImpl.java | 500 +++++++++++++++++++ .../json/javax/json/JsonLocationImpl.java | 60 +++ .../ignite/json/javax/json/JsonNumberImpl.java | 116 +++++ .../json/javax/json/JsonObjectBuilderImpl.java | 150 ++++++ .../ignite/json/javax/json/JsonObjectImpl.java | 120 +++++ .../ignite/json/javax/json/JsonParserImpl.java | 85 ++++ .../json/javax/json/JsonProviderImpl.java | 130 +++++ .../ignite/json/javax/json/JsonStringImpl.java | 71 +++ .../ignite/json/javax/json/JsonToken.java | 431 ++++++++++++++++ .../ignite/internal/NodeJsIgniteSelfTest.java | 6 + 14 files changed, 1959 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/pom.xml ---------------------------------------------------------------------- diff --git a/modules/core/pom.xml b/modules/core/pom.xml index 5ac49ae..88ecdbc 100644 --- a/modules/core/pom.xml +++ b/modules/core/pom.xml @@ -24,6 +24,7 @@ <modelVersion>4.0.0</modelVersion> <parent> + <groupId>org.apache.ignite</groupId> <artifactId>ignite-parent</artifactId> <version>1</version> @@ -39,7 +40,16 @@ <artifactId>cache-api</artifactId> <version>1.0.0</version> </dependency> - + <dependency> + <groupId>javax.json</groupId> + <artifactId>javax.json-api</artifactId> + <version>1.0</version> + </dependency> + <dependency> + <groupId>org.glassfish</groupId> + <artifactId>javax.json</artifactId> + <version>1.0.4</version> + </dependency> <dependency> <groupId>mx4j</groupId> <artifactId>mx4j-tools</artifactId> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/JSONCacheObject.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/JSONCacheObject.java b/modules/core/src/main/java/org/apache/ignite/json/JSONCacheObject.java index 0eb5f28..fe96833 100644 --- a/modules/core/src/main/java/org/apache/ignite/json/JSONCacheObject.java +++ b/modules/core/src/main/java/org/apache/ignite/json/JSONCacheObject.java @@ -17,6 +17,9 @@ package org.apache.ignite.json; +import com.github.pgelinas.jackson.javax.json.*; +import jdk.nashorn.internal.parser.*; + import java.util.*; /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayBuilderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayBuilderImpl.java new file mode 100644 index 0000000..613c5c2 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayBuilderImpl.java @@ -0,0 +1,140 @@ +/* + * 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.ignite.json.javax.json; + +import org.apache.ignite.internal.util.typedef.internal.*; + +import javax.json.*; +import java.math.*; +import java.util.*; + +/** + * Json array builder. + */ +public class JsonArrayBuilderImpl implements JsonArrayBuilder { + /** Json array list. */ + private List<JsonValue> jsonList = new ArrayList<>(); + + /** Object buffer. */ + private final JsonProviderImpl.ObjectsQueue buf; + + /** + * @param buf Object buffer. + */ + public JsonArrayBuilderImpl(JsonProviderImpl.ObjectsQueue buf) { + this.buf = buf; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(JsonValue val) { + A.notNull(val, "value"); + + jsonList.add(val); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(String val) { + A.notNull(val, "value"); + + jsonList.add(new JsonStringImpl(val)); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(BigDecimal val) { + A.notNull(val, "value"); + + jsonList.add(new JsonNumberImpl(val)); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(BigInteger val) { + A.notNull(val, "value"); + + //TODO: optimize for value + jsonList.add(new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(int val) { + //TODO: optimize for value + jsonList.add(new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(long val) { + //TODO: optimize for value + jsonList.add(new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(double val) { + //TODO: optimize for value + jsonList.add(new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(boolean val) { + jsonList.add(val ? JsonValue.TRUE : JsonValue.FALSE); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder addNull() { + jsonList.add(JsonValue.NULL); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(JsonObjectBuilder bld) { + A.notNull(bld, "value"); + + jsonList.add(bld.build()); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder add(JsonArrayBuilder bld) { + A.notNull(bld, "value"); + + jsonList.add(bld.build()); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonArray build() { + return new JsonArrayImpl(jsonList, buf); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayImpl.java new file mode 100644 index 0000000..190947a --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonArrayImpl.java @@ -0,0 +1,136 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.*; +import java.util.*; + +/** + * Implementation of JsonArray + */ +public class JsonArrayImpl extends ArrayList<JsonValue> implements JsonArray { + /** Values for getValueAs. */ + private List<JsonValue> val; + + /** Object buffer. */ + private final JsonProviderImpl.ObjectsQueue buf; + + /** + * @param val List json values. + */ + public JsonArrayImpl(List<JsonValue> val, JsonProviderImpl.ObjectsQueue buf) { + super(val); + + this.buf = buf; + } + + /** {@inheritDoc} */ + @Override public JsonObject getJsonObject(int idx) { + return (JsonObject)get(idx); + } + + /** {@inheritDoc} */ + @Override public JsonArray getJsonArray(int idx) { + return (JsonArray)get(idx); + } + + /** {@inheritDoc} */ + @Override public JsonNumber getJsonNumber(int idx) { + return (JsonNumber)get(idx); + } + + /** {@inheritDoc} */ + @Override public JsonString getJsonString(int idx) { + return (JsonString)get(idx); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public <T extends JsonValue> List<T> getValuesAs(Class<T> clazz) { + if (val == null) { + val = new ArrayList(this.size()); + + for (int i = 0; i < size(); ++i) + val.add(get(i)); + + val = Collections.unmodifiableList(val); + } + return (List<T>) val; + } + + /** {@inheritDoc} */ + @Override public String getString(int idx) { + return getJsonString(idx).getString(); + } + + /** {@inheritDoc} */ + @Override public String getString(int idx, String dfltVal) { + try { + return getString(idx); + } + catch (Exception e) { + return dfltVal; + } + } + + /** {@inheritDoc} */ + @Override public int getInt(int idx) { + return getJsonNumber(idx).intValue(); + } + + /** {@inheritDoc} */ + @Override public int getInt(int idx, int dfltVal) { + try { + return getInt(idx); + } catch (Exception e) { + return dfltVal; + } + } + + /** {@inheritDoc} */ + @Override public boolean getBoolean(int idx) { + JsonValue val = get(idx); + + if (val.equals(JsonValue.TRUE)) + return true; + + if (val.equals(JsonValue.FALSE)) + return false; + + throw new ClassCastException(); + } + + /** {@inheritDoc} */ + @Override public boolean getBoolean(int idx, boolean dfltVal) { + try { + return getBoolean(idx); + } catch (Exception e) { + return dfltVal; + } + } + + /** {@inheritDoc} */ + @Override public boolean isNull(int idx) { + return get(idx).equals(JsonValue.NULL); + } + + /** {@inheritDoc} */ + @Override public ValueType getValueType() { + return ValueType.ARRAY; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonGeneratorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonGeneratorImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonGeneratorImpl.java new file mode 100644 index 0000000..175a002 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonGeneratorImpl.java @@ -0,0 +1,500 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.*; +import javax.json.stream.*; +import java.io.*; +import java.math.*; +import java.util.*; + +/** + * Json generator implementation. + */ +public class JsonGeneratorImpl implements JsonGenerator { + /** Writer. */ + private final BufferedWriter writer; + + private LinkedList<Element> ctx = new LinkedList(); + + /** + * @param writer Writer. + */ + public JsonGeneratorImpl(Writer writer) { + this.writer = new BufferedWriter(writer); + + ctx.push(new Element(Context.NONE, true)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator writeStartObject() { + try { + if (ctx.getLast().context() == Context.OBJECT || + (ctx.getLast().context() == Context.NONE && !ctx.getLast().isFirst())) + throw new JsonGenerationException("No name for object field."); + + writeComma(); + writer.write('{'); + + ctx.addLast(new Element(Context.OBJECT, true)); + + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** {@inheritDoc} */ + @Override public JsonGenerator writeStartObject(String name) { + try { + if (ctx.getLast().context() != Context.OBJECT) + throw new JsonGenerationException("Object with name in not object scope."); + + writeComma(); + writeString(name); + writer.write(":"); + writer.write('{'); + + ctx.addLast(new Element(Context.OBJECT, true)); + + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** {@inheritDoc} */ + @Override public JsonGenerator writeStartArray() { + try { + if (ctx.getLast().context() == Context.OBJECT || + (ctx.getLast().context() == Context.NONE && !ctx.getLast().isFirst())) + throw new JsonGenerationException("Array in object scope."); + + writeComma(); + writer.write("["); + + ctx.addLast(new Element(Context.ARRAY, true)); + + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** {@inheritDoc} */ + @Override public JsonGenerator writeStartArray(String name) { + try { + if (ctx.getLast().context() != Context.OBJECT) + throw new JsonGenerationException("Array with name in not object scope."); + + writeComma(); + writeString(name); + writer.write(":"); + writer.write('['); + + ctx.addLast(new Element(Context.ARRAY, true)); + + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, JsonValue val) { + if (ctx.getLast().context() != Context.OBJECT) + throw new JsonGenerationException("Json value with name in not object scope."); + + try { + switch (val.getValueType()) { + case ARRAY: { + JsonArray arr = (JsonArray) val; + + writeStartArray(name); + + for (JsonValue el : arr) + write(el); + + writeEnd(); + + break; + } + + case OBJECT: { + JsonObject o = (JsonObject) val; + + writeStartObject(name); + + for (Map.Entry<String, JsonValue> member : o.entrySet()) + write(member.getKey(), member.getValue()); + + writeEnd(); + + break; + } + + case STRING: { + JsonString str = (JsonString) val; + + write(name, str.getString()); + + break; + } + + case NUMBER: { + JsonNumber n = (JsonNumber) val; + + writeComma(); + writeString(name); + writer.write(":"); + writeString(n.toString()); + + break; + } + case TRUE: { + write(name, true); + + break; + } + + case FALSE: { + write(name, false); + + break; + } + + case NULL: { + writeNull(name); + + break; + } + } + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, String val) { + return writeSimpleField(name, val); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, BigInteger val) { + return writeSimpleField(name, String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, BigDecimal val) { + return writeSimpleField(name, String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, int val) { + return writeSimpleField(name, String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, long val) { + return writeSimpleField(name, String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, double val) { + return writeSimpleField(name, String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String name, boolean val) { + return writeSimpleField(name, String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator writeNull(String name) { + return writeSimpleField(name, "null"); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator writeEnd() { + if (ctx.getLast().context() == Context.NONE) + throw new JsonGenerationException("Cannot call writeEnd in none context."); + + try { + if (ctx.getLast().context() == Context.ARRAY) + writer.write("]"); + + if (ctx.getLast().context() == Context.OBJECT) + writer.write("}"); + + ctx.removeLast(); + + return this; + } + catch(IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(JsonValue val) { + if (ctx.getLast().context() != Context.ARRAY) + throw new JsonGenerationException("Json value without name in not array scope."); + + try { + switch (val.getValueType()) { + case ARRAY: { + JsonArray arr = (JsonArray) val; + + writeStartArray(); + + for (JsonValue el : arr) + write(el); + + writeEnd(); + + break; + } + + case OBJECT: { + JsonObject o = (JsonObject) val; + + writeStartObject(); + + for (Map.Entry<String, JsonValue> member : o.entrySet()) + write(member.getKey(), member.getValue()); + + writeEnd(); + + break; + } + + case STRING: { + JsonString str = (JsonString) val; + + write(str.getString()); + + break; + } + + case NUMBER: { + JsonNumber n = (JsonNumber) val; + + writeComma(); + writeString(n.toString()); + + break; + } + case TRUE: { + write(true); + + break; + } + + case FALSE: { + write(false); + + break; + } + + case NULL: { + writeNull(); + + break; + } + } + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(String val) { + return writeSimpleArrayElement(val); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(BigDecimal val) { + return writeSimpleArrayElement(String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(BigInteger val) { + return writeSimpleArrayElement(String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(int val) { + return writeSimpleArrayElement(String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(long val) { + return writeSimpleArrayElement(String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(double val) { + return writeSimpleArrayElement(String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator write(boolean val) { + return writeSimpleArrayElement(String.valueOf(val)); + } + + /** {@inheritDoc} */ + @Override public JsonGenerator writeNull() { + return writeSimpleArrayElement("null"); + } + + /** {@inheritDoc} */ + @Override public void close() { + try { + writer.close(); + } + catch (IOException e) { + throw new JsonException("Could not close writer.", e); + } + } + + /** {@inheritDoc} */ + @Override public void flush() { + try { + writer.flush(); + } + catch (IOException e) { + throw new JsonException("Could not flush buffer to writer.", e); + } + } + + /** + * Write comma if object is not first. + * + * @throws IOException If failed. + */ + private void writeComma() throws IOException{ + if (!ctx.getLast().isFirst()) + writer.write(","); + + ctx.getLast().isFirst = false; + } + + /** + * @param name Field name. + * @param val Field value. + */ + private JsonGenerator writeSimpleField(String name, String val) { + if (ctx.getLast().context() != Context.OBJECT) + throw new JsonGenerationException("String with name in not object scope."); + + try { + writeComma(); + writeString(name); + writer.write(":"); + writeString(val); + + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + + /** + * @param val Field value. + */ + private JsonGenerator writeSimpleArrayElement(String val) { + if (ctx.getLast().context() != Context.ARRAY) + throw new JsonGenerationException("String without name in not array scope."); + + try { + writeComma(); + writeString(val); + + return this; + } + catch (IOException e) { + throw new JsonException("Writer fails.", e); + } + } + + /** + * @param str String to write. + * @throws IOException If failed. + * //TODO: escape string. + */ + private void writeString(String str) throws IOException { + writer.write(str); + } + + /** + * Generator element. + */ + private static class Element { + /** Context. */ + private Context ctx; + + /** First element flag. */ + private boolean isFirst; + + /** + * @param ctx Context. + * @param isFirst First element flag. + */ + public Element(Context ctx, boolean isFirst) { + this.ctx = ctx; + this.isFirst = isFirst; + } + + /** + * @return First element flag. + */ + public boolean isFirst() { + return isFirst; + } + + /** + * @return Context. + */ + public Context context() { + return ctx; + } + } + /** + * Context for writer. + */ + private enum Context { + /** Writing object. */ + OBJECT, + + /** Writing array. */ + ARRAY, + + /** Not in object or in array. */ + NONE + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonLocationImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonLocationImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonLocationImpl.java new file mode 100644 index 0000000..4b7842d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonLocationImpl.java @@ -0,0 +1,60 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.stream.*; + +/** + * Json location implementation. + */ +public class JsonLocationImpl implements JsonLocation { + /** Column number. */ + private final long col; + + /** Line number. */ + private final long line; + + /** Stream offset. */ + private final long off; + + /** + * @param line Line number. + * @param col Column number. + * @param streamOff Stream offset. + */ + JsonLocationImpl(long line, long col, long streamOff) { + this.line = line; + this.col = col; + this.off = streamOff; + } + + /** {@inheritDoc} */ + @Override public long getLineNumber() { + return line; + } + + /** {@inheritDoc} */ + @Override public long getColumnNumber() { + return col; + } + + /** {@inheritDoc} */ + @Override public long getStreamOffset() { + return off; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonNumberImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonNumberImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonNumberImpl.java new file mode 100644 index 0000000..dedb00d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonNumberImpl.java @@ -0,0 +1,116 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.*; +import java.math.*; + +/** + * Json number implementation. + * //TODO: optimize for int, long, double... + */ +public class JsonNumberImpl implements JsonNumber { + /** Value. */ + private final BigDecimal val; + + /** + * @param val Value. + */ + public JsonNumberImpl(BigDecimal val){ + this.val = val; + } + + /** {@inheritDoc} */ + @Override public boolean isIntegral() { + if (val == null) + return false; + + return val.scale() == 0; + } + + /** {@inheritDoc} */ + @Override public int intValue() { + return val.intValue(); + } + + /** {@inheritDoc} */ + @Override public int intValueExact() { + return val.intValueExact(); + } + + /** {@inheritDoc} */ + @Override public long longValue() { + return val.longValue(); + } + + /** {@inheritDoc} */ + @Override public long longValueExact() { + return val.longValueExact(); + } + + /** {@inheritDoc} */ + @Override public BigInteger bigIntegerValue() { + return val.toBigInteger(); + } + + /** {@inheritDoc} */ + @Override public BigInteger bigIntegerValueExact() { + return val.toBigIntegerExact(); + } + + /** {@inheritDoc} */ + @Override public double doubleValue() { + return val.doubleValue(); + } + + /** {@inheritDoc} */ + @Override public BigDecimal bigDecimalValue() { + return val; + } + + /** {@inheritDoc} */ + @Override public ValueType getValueType() { + return ValueType.NUMBER; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return val.toString(); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + if (val == null) + return 0; + + return val.hashCode(); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object obj) { + if (obj == null || !(obj instanceof JsonNumberImpl)) + return false; + + BigDecimal val0 = ((JsonNumberImpl)obj).val; + + if (val == null) + return val0 == null; + + return val.equals(val0); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectBuilderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectBuilderImpl.java new file mode 100644 index 0000000..0743a54 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectBuilderImpl.java @@ -0,0 +1,150 @@ +/* + * 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.ignite.json.javax.json; + +import org.apache.ignite.internal.util.typedef.internal.*; + +import javax.json.*; +import java.math.*; +import java.util.*; + +/** + * Json object builder implementation. + */ +public class JsonObjectBuilderImpl implements JsonObjectBuilder { + /** Json object map. */ + private Map<String, JsonValue> jsonMap = new HashMap<>(); + + private final JsonProviderImpl.ObjectsQueue buf; + + /** + * @param buf Object buffer. + */ + public JsonObjectBuilderImpl(JsonProviderImpl.ObjectsQueue buf) { + this.buf = buf; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, JsonValue val) { + A.notNull(name, "key", val, "value"); + + jsonMap.put(name, val); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, String val) { + A.notNull(name, "key", val, "value"); + + jsonMap.put(name, new JsonStringImpl(val)); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, BigInteger val) { + A.notNull(name, "key", val, "value"); + + //TODO: optimize for value + jsonMap.put(name, new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, BigDecimal val) { + A.notNull(name, "key", val, "value"); + + //TODO: optimize for value + jsonMap.put(name, new JsonNumberImpl(val)); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, int val) { + A.notNull(name, "key"); + + //TODO: optimize for value + jsonMap.put(name, new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, long val) { + A.notNull(name, "key"); + + //TODO: optimize for value + jsonMap.put(name, new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, double val) { + A.notNull(name, "key"); + + //TODO: optimize for value + jsonMap.put(name, new JsonNumberImpl(new BigDecimal(val))); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, boolean val) { + A.notNull(name, "key"); + + jsonMap.put(name, val ? JsonValue.TRUE : JsonValue.FALSE); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder addNull(String name) { + A.notNull(name, "key"); + + jsonMap.put(name, JsonValue.NULL); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, JsonObjectBuilder bld) { + A.notNull(name, "key", bld, "value"); + + jsonMap.put(name, bld.build()); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder add(String name, JsonArrayBuilder bld) { + A.notNull(name, "key", bld, "value"); + + jsonMap.put(name, bld.build()); + + return this; + } + + /** {@inheritDoc} */ + @Override public JsonObject build() { + return new JsonObjectImpl(jsonMap, buf); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectImpl.java new file mode 100644 index 0000000..03b6427 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonObjectImpl.java @@ -0,0 +1,120 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.*; +import java.util.*; + +/** + * JsonObject implementation. + */ +public class JsonObjectImpl extends HashMap<String, JsonValue> implements JsonObject { + /** Object buffer. */ + private final JsonProviderImpl.ObjectsQueue buf; + + /** + * @param val Map to store. + */ + public JsonObjectImpl(Map<String, JsonValue> val, JsonProviderImpl.ObjectsQueue buf) { + super(val); + this.buf = buf; + } + + /** {@inheritDoc} */ + @Override public JsonArray getJsonArray(String name) { + return (JsonArray)get(name); + } + + /** {@inheritDoc} */ + @Override public JsonObject getJsonObject(String name) { + return (JsonObject)get(name); + } + + /** {@inheritDoc} */ + @Override public JsonNumber getJsonNumber(String name) { + return (JsonNumber)get(name); + } + + /** {@inheritDoc} */ + @Override public JsonString getJsonString(String name) { + return (JsonString)get(name); + } + + /** {@inheritDoc} */ + @Override public String getString(String name) { + return getJsonString(name).getString(); + } + + /** {@inheritDoc} */ + @Override public String getString(String name, String dfltVal) { + try { + return getString(name); + } + catch (Exception e) { + return dfltVal; + } + } + + /** {@inheritDoc} */ + @Override public int getInt(String name) { + return getJsonNumber(name).intValue(); + } + + /** {@inheritDoc} */ + @Override public int getInt(String name, int dfltVal) { + try { + return getInt(name); + } + catch (Exception e) { + return dfltVal; + } + } + + /** {@inheritDoc} */ + @Override public boolean getBoolean(String name) { + JsonValue val = get(name); + + if (val.equals(JsonValue.TRUE)) + return true; + + if (val.equals(JsonValue.FALSE)) + return false; + + throw new ClassCastException(); + } + + /** {@inheritDoc} */ + @Override public boolean getBoolean(String name, boolean dfltVal) { + try { + return getBoolean(name); + } + catch (Exception e) { + return dfltVal; + } + } + + /** {@inheritDoc} */ + @Override public boolean isNull(String name) { + return get(name).equals(JsonValue.NULL); + } + + /** {@inheritDoc} */ + @Override public ValueType getValueType() { + return ValueType.OBJECT; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonParserImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonParserImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonParserImpl.java new file mode 100644 index 0000000..f77a79b --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonParserImpl.java @@ -0,0 +1,85 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.stream.*; +import java.io.*; +import java.math.*; + +/** + * Json parser implementation. + */ +public class JsonParserImpl implements JsonParser { + /** Reader. */ + private final Reader reader; + + /** Current buffer. */ + private char[] buf = new char[1024]; + + /** Position in buffer. */ + private int pos = 0; + + public JsonParserImpl(Reader reader) { + this.reader = reader; + } + + /** {@inheritDoc} */ + @Override public boolean hasNext() { + return false; + } + + /** {@inheritDoc} */ + @Override public Event next() { + return null; + } + + /** {@inheritDoc} */ + @Override public String getString() { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean isIntegralNumber() { + return false; + } + + /** {@inheritDoc} */ + @Override public int getInt() { + return 0; + } + + /** {@inheritDoc} */ + @Override public long getLong() { + return 0; + } + + /** {@inheritDoc} */ + @Override public BigDecimal getBigDecimal() { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonLocation getLocation() { + return null; + } + + /** {@inheritDoc} */ + @Override public void close() { + + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonProviderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonProviderImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonProviderImpl.java new file mode 100644 index 0000000..5cf9126 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonProviderImpl.java @@ -0,0 +1,130 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.*; +import javax.json.spi.*; +import javax.json.stream.*; +import java.io.*; +import java.util.*; +import java.util.concurrent.*; + +/** + * Json provider implementation. + */ +public class JsonProviderImpl extends JsonProvider { + /** Object queue. */ + private ObjectsQueue queue = new ObjectsQueue(); + + /** {@inheritDoc} */ + @Override public JsonParser createParser(Reader reader) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonParser createParser(InputStream in) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonParserFactory createParserFactory(Map<String, ?> config) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonGenerator createGenerator(Writer writer) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonGenerator createGenerator(OutputStream out) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonReader createReader(Reader reader) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonReader createReader(InputStream in) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonWriter createWriter(Writer writer) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonWriter createWriter(OutputStream out) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonWriterFactory createWriterFactory(Map<String, ?> config) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonReaderFactory createReaderFactory(Map<String, ?> config) { + return null; + } + + /** {@inheritDoc} */ + @Override public JsonObjectBuilder createObjectBuilder() { + return new JsonObjectBuilderImpl(queue); + } + + /** {@inheritDoc} */ + @Override public JsonArrayBuilder createArrayBuilder() { + return new JsonArrayBuilderImpl(queue); + } + + /** {@inheritDoc} */ + @Override public JsonBuilderFactory createBuilderFactory(Map<String, ?> config) { + return null; + } + + /** + * Provider objects queue. + */ + static class ObjectsQueue { + /** Object queue. */ + private ConcurrentLinkedQueue<char[]> queue = new ConcurrentLinkedQueue<>(); + + /** + * @return Poll object buffer from the queue. + */ + public char[] get() { + return queue.poll(); + } + + /** + * @param o Push object buffer to the queue. + */ + public void offer(char[] o) { + queue.offer(o); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonStringImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonStringImpl.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonStringImpl.java new file mode 100644 index 0000000..7e4d22c --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonStringImpl.java @@ -0,0 +1,71 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.*; + +/** + * Json string implementation. + */ +public class JsonStringImpl implements JsonString { + /** Value. */ + private final String val; + + /** + * @param val Value. + */ + public JsonStringImpl(String val) { + this.val = val; + } + + /** {@inheritDoc} */ + @Override public String getString() { + return val; + } + + /** {@inheritDoc} */ + @Override public CharSequence getChars() { + return val; + } + + /** {@inheritDoc} */ + @Override public ValueType getValueType() { + return ValueType.STRING; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + if (val == null) + return 0; + + return val.hashCode(); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object obj) { + if (obj == null || !(obj instanceof JsonString)) + return false; + + JsonString other = (JsonString)obj; + + if (val == null) + return other.getString() == null; + + return val.equals(other.getString()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonToken.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonToken.java b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonToken.java new file mode 100644 index 0000000..ef3aed0 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/json/javax/json/JsonToken.java @@ -0,0 +1,431 @@ +/* + * 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.ignite.json.javax.json; + +import javax.json.*; +import javax.json.stream.*; +import java.io.*; +import java.math.*; +import java.util.*; + +/** + * Created by GridGain on 15.07.2015. + */ +public class JsonToken { + /** Reader. */ + private final Reader reader; + + // Internal buffer that is used for parsing. + private char[] buf = new char[1024]; + + /** Read begin in buffer. */ + private int readBegin; + + /** Read end in buffer. */ + private int readEnd; + + /** Store value start. */ + private int storeBegin; + + /** Store value end. */ + private int storeEnd; + + /** Line number. */ + private long line = 1; + + /** Last line offset. */ + private long lastLineOff = 0; + + /** Buffer offset. */ + private long bufOff = 0; + + /** Flag for current number is negative. */ + private boolean minus; + + /** Current big decimal number. */ + private BigDecimal bd; + + enum JsonTokenEvent { + CURLYOPEN(JsonParser.Event.START_OBJECT, false), + SQUAREOPEN(JsonParser.Event.START_ARRAY, false), + COLON(null, false), + COMMA(null, false), + STRING(JsonParser.Event.VALUE_STRING, true), + NUMBER(JsonParser.Event.VALUE_NUMBER, true), + TRUE(JsonParser.Event.VALUE_TRUE, true), + FALSE(JsonParser.Event.VALUE_FALSE, true), + NULL(JsonParser.Event.VALUE_NULL, true), + CURLYCLOSE(JsonParser.Event.END_OBJECT, false), + SQUARECLOSE(JsonParser.Event.END_ARRAY, false), + EOF(null, false); + + private final JsonParser.Event event; + private final boolean value; + + JsonTokenEvent(JsonParser.Event event, boolean value) { + this.event = event; + this.value = value; + } + + JsonParser.Event getEvent() { + return event; + } + + boolean isValue() { + return value; + } + } + + JsonToken(Reader reader) { + this.reader = reader; + } + + private void readString() { + // when inPlace is true, no need to copy chars + boolean inPlace = true; + storeBegin = storeEnd = readBegin; + + do { + // Write unescaped char block within the current buffer + if (inPlace) { + int ch; + while(readBegin < readEnd && ((ch=buf[readBegin]) >= 0x20) && ch != '\\') { + if (ch == '"') { + storeEnd = readBegin++; // ++ to consume quote char + return; // Got the entire string + } + readBegin++; // consume unescaped char + } + storeEnd = readBegin; + } + + // string may be crossing buffer boundaries and may contain + // escaped characters. + int ch = read(); + if (ch >= 0x20 && ch != 0x22 && ch != 0x5c) { + if (!inPlace) { + buf[storeEnd] = (char)ch; + } + storeEnd++; + continue; + } + switch (ch) { + case '\\': + inPlace = false; // Now onwards need to copy chars + unescape(); + break; + case '"': + return; + default: + throw unexpectedChar(ch); + } + } while (true); + } + + // Reads a number char. If the char is within the buffer, directly + // reads from the buffer. Otherwise, uses read() which takes care + // of resizing, filling up the buf, adjusting the pointers + private int readNumberChar() { + if (readBegin < readEnd) { + return buf[readBegin++]; + } else { + storeEnd = readBegin; + return read(); + } + } + + private void readNumber(int ch) { + storeBegin = storeEnd = readBegin-1; + // sign + if (ch == '-') { + this.minus = true; + ch = readNumberChar(); + if (ch < '0' || ch >'9') { + throw unexpectedChar(ch); + } + } + + // int + if (ch == '0') { + ch = readNumberChar(); + } else { + do { + ch = readNumberChar(); + } while (ch >= '0' && ch <= '9'); + } + + // frac + if (ch == '.') { + this.fracOrExp = true; + int count = 0; + do { + ch = readNumberChar(); + count++; + } while (ch >= '0' && ch <= '9'); + if (count == 1) { + throw unexpectedChar(ch); + } + } + + readBegin--; + storeEnd = readBegin; + } + + private void readTrue() { + int ch1 = read(); + if (ch1 != 'r') { + throw expectedChar(ch1, 'r'); + } + int ch2 = read(); + if (ch2 != 'u') { + throw expectedChar(ch2, 'u'); + } + int ch3 = read(); + if (ch3 != 'e') { + throw expectedChar(ch3, 'e'); + } + } + + private void readFalse() { + int ch1 = read(); + if (ch1 != 'a') { + throw expectedChar(ch1, 'a'); + } + int ch2 = read(); + if (ch2 != 'l') { + throw expectedChar(ch2, 'l'); + } + int ch3 = read(); + if (ch3 != 's') { + throw expectedChar(ch3, 's'); + } + int ch4 = read(); + if (ch4 != 'e') { + throw expectedChar(ch4, 'e'); + } + } + + private void readNull() { + int ch1 = read(); + if (ch1 != 'u') { + throw expectedChar(ch1, 'u'); + } + int ch2 = read(); + if (ch2 != 'l') { + throw expectedChar(ch2, 'l'); + } + int ch3 = read(); + if (ch3 != 'l') { + throw expectedChar(ch3, 'l'); + } + } + + /* + * Could be optimized if the parser uses separate methods to match colon + * etc (that would avoid the switch statement cost in certain cases) + */ + JsonTokenEvent nextToken() { + reset(); + int ch = read(); + + // whitespace + while (ch == 0x20 || ch == 0x09 || ch == 0x0a || ch == 0x0d) { + if (ch == '\r') { + ++line; + ch = read(); + if (ch == '\n') { + lastLineOff = bufOff +readBegin; + } else { + lastLineOff = bufOff +readBegin-1; + continue; + } + } else if (ch == '\n') { + ++line; + lastLineOff = bufOff +readBegin; + } + ch = read(); + } + + switch (ch) { + case '"': + readString(); + return JsonTokenEvent.STRING; + case '{': + return JsonTokenEvent.CURLYOPEN; + case '[': + return JsonTokenEvent.SQUAREOPEN; + case ':': + return JsonTokenEvent.COLON; + case ',': + return JsonTokenEvent.COMMA; + case 't': + readTrue(); + return JsonTokenEvent.TRUE; + case 'f': + readFalse(); + return JsonTokenEvent.FALSE; + case 'n': + readNull(); + return JsonTokenEvent.NULL; + case ']': + return JsonTokenEvent.SQUARECLOSE; + case '}': + return JsonTokenEvent.CURLYCLOSE; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + readNumber(ch); + return JsonTokenEvent.NUMBER; + case -1: + return JsonTokenEvent.EOF; + default: + throw unexpectedChar(ch); + } + } + + // Gives the location of the last char. Used for + // JsonParsingException.getLocation + JsonLocation getLastCharLocation() { + // Already read the char, so subtracting -1 + return new JsonLocationImpl(line, bufOff +readBegin- lastLineOff, bufOff +readBegin-1); + } + + // Gives the parser location. Used for JsonParser.getLocation + JsonLocation getLocation() { + return new JsonLocationImpl(line, bufOff +readBegin- lastLineOff +1, bufOff +readBegin); + } + + private int read() { + try { + if (readBegin == readEnd) { // need to fill the buffer + int len = fillBuf(); + if (len == -1) { + return -1; + } + assert len != 0; + readBegin = storeEnd; + readEnd = readBegin+len; + } + return buf[readBegin++]; + } catch (IOException ioe) { + throw new JsonException("Reader failed", ioe); + } + } + + private int fillBuf() throws IOException { + if (storeEnd != 0) { + int storeLen = storeEnd-storeBegin; + if (storeLen > 0) { + // there is some store data + if (storeLen == buf.length) { + // buffer is full, double the capacity + char[] doubleBuf = Arrays.copyOf(buf, 2 * buf.length); + bufferPool.recycle(buf); + buf = doubleBuf; + } else { + // Left shift all the stored data to make space + System.arraycopy(buf, storeBegin, buf, 0, storeLen); + storeEnd = storeLen; + storeBegin = 0; + bufOff += readBegin-storeEnd; + } + } else { + storeBegin = storeEnd = 0; + bufOff += readBegin; + } + } else { + bufOff += readBegin; + } + // Fill the rest of the buf + return reader.read(buf, storeEnd, buf.length-storeEnd); + } + + // state associated with the current token is no more valid + private void reset() { + if (storeEnd != 0) { + storeBegin = 0; + storeEnd = 0; + bd = null; + minus = false; + fracOrExp = false; + } + } + + String getValue() { + return new String(buf, storeBegin, storeEnd-storeBegin); + } + + BigDecimal getBigDecimal() { + if (bd == null) { + bd = new BigDecimal(buf, storeBegin, storeEnd-storeBegin); + } + return bd; + } + + int getInt() { + // no need to create BigDecimal for common integer values (1-9 digits) + int storeLen = storeEnd-storeBegin; + if (!fracOrExp && (storeLen <= 9 || (minus && storeLen == 10))) { + int num = 0; + int i = minus ? 1 : 0; + for(; i < storeLen; i++) { + num = num * 10 + (buf[storeBegin+i] - '0'); + } + return minus ? -num : num; + } else { + return getBigDecimal().intValue(); + } + } + + // returns true for common integer values (1-9 digits). + // So there are cases it will return false even though the number is int + boolean isDefinitelyInt() { + int storeLen = storeEnd-storeBegin; + return !fracOrExp && (storeLen <= 9 || (minus && storeLen == 10)); + } + + boolean isIntegral() { + return !fracOrExp || getBigDecimal().scale() == 0; + } + + @Override + public void close() throws IOException { + reader.close(); + bufferPool.recycle(buf); + } + + private JsonParsingException unexpectedChar(int ch) { + JsonLocation location = getLastCharLocation(); + return new JsonParsingException( + JsonMessages.TOKENIZER_UNEXPECTED_CHAR(ch, location), location); + } + + private JsonParsingException expectedChar(int unexpected, char expected) { + JsonLocation location = getLastCharLocation(); + return new JsonParsingException( + JsonMessages.TOKENIZER_EXPECTED_CHAR(unexpected, location, expected), location); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/debed8a5/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsIgniteSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsIgniteSelfTest.java b/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsIgniteSelfTest.java index dcb0aa4..4365881 100644 --- a/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsIgniteSelfTest.java +++ b/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsIgniteSelfTest.java @@ -17,6 +17,8 @@ package org.apache.ignite.internal; +import java.util.*; + /** * Test for node js ignite. */ @@ -42,6 +44,10 @@ public class NodeJsIgniteSelfTest extends NodeJsAbstractTest { * @throws Exception If failed. */ public void testIgniteVersion() throws Exception { + Map<Object, Object> map = new HashMap<>(); + String b = (String)map.get("a"); + System.out.println("B=" + b); + System.out.println("Equal = " + b.equals(null)); runJsScript("testIgniteVersion"); }