ignite-961 JSON API implemented
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2560c885 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2560c885 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2560c885 Branch: refs/heads/ignite-961 Commit: 2560c8852b4b2bc9d36691f49d216fcafccca32e Parents: 1367eb9 Author: agura <[email protected]> Authored: Fri Feb 19 19:01:16 2016 +0300 Committer: agura <[email protected]> Committed: Fri Feb 19 19:01:16 2016 +0300 ---------------------------------------------------------------------- .../ignite/internal/IgniteComponentType.java | 3 +- .../binary/builder/BinaryObjectBuilderImpl.java | 7 + .../binary/builder/BinaryValueWithType.java | 26 + .../processors/cache/CacheObjectContext.java | 5 +- .../json/IgniteJsonNoopProcessor.java | 5 + .../processors/json/IgniteJsonProcessor.java | 5 + .../processors/query/GridQueryProcessor.java | 66 +- .../processors/rest/GridRestProcessor.java | 13 +- .../processors/json/IgniteJsonArray.java | 374 ++++++++- .../processors/json/IgniteJsonArrayBuilder.java | 88 +- .../processors/json/IgniteJsonGenerator.java | 3 +- .../processors/json/IgniteJsonLocation.java | 2 +- .../json/IgniteJsonMessageFactory.java | 37 - .../processors/json/IgniteJsonNumber.java | 2 +- .../processors/json/IgniteJsonObject.java | 208 ++++- .../json/IgniteJsonObjectBuilder.java | 92 ++- .../json/IgniteJsonProcessorImpl.java | 40 +- .../processors/json/IgniteJsonProvider.java | 13 +- .../processors/json/IgniteJsonString.java | 2 +- .../processors/json/IgniteJsonUtils.java | 58 ++ .../processors/json/JsonCacheObject.java | 127 --- .../java/org/apache/ignite/json/IgniteJson.java | 3 +- .../json/IgniteJsonArrayBuilderSelfTest.java | 145 ++++ .../json/IgniteJsonArraySelfTest.java | 807 +++++++++++++++++++ .../processors/json/IgniteJsonCacheTest.java | 62 +- .../json/IgniteJsonObjectBuilderSelfTest.java | 147 ++++ .../json/IgniteJsonObjectSelfTest.java | 637 +++++++++++++++ .../ignite/testsuites/IgniteJsonTestSuite.java | 48 ++ .../ignite/internal/NodeJsComputeSelfTest.java | 2 +- .../ignite/internal/NodeJsSqlQuerySelfTest.java | 2 +- modules/nodejs/src/test/js/test-compute.js | 3 - 31 files changed, 2686 insertions(+), 346 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java index d15a2b2..8c750f4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java @@ -88,8 +88,7 @@ public enum IgniteComponentType { JSON( "org.apache.ignite.internal.processors.json.IgniteJsonNoopProcessor", "org.apache.ignite.internal.processors.json.IgniteJsonProcessorImpl", - "ignite-json", - "org.apache.ignite.internal.processors.json.IgniteJsonMessageFactory" + "ignite-json" ); /** No-op class name. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java index 9043a8b..512fcc0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java @@ -394,6 +394,13 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { } /** + * @return Map of assigned values. + */ + public Map<String, Object> assignedVals() { + return assignedVals; + } + + /** * Get field position and length. * * @param footerPos Field position inside the footer (absolute). http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java index c5a3e0a..b32954d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java @@ -71,6 +71,32 @@ class BinaryValueWithType implements BinaryLazyValue { } /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + BinaryValueWithType that = (BinaryValueWithType)o; + + if (type != that.type) + return false; + + return val != null ? val.equals(that.val) : that.val == null; + + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = (int)type; + + res = 31 * res + (val != null ? val.hashCode() : 0); + + return res; + } + + /** {@inheritDoc} */ @Override public String toString() { return S.toString(BinaryValueWithType.class, this); } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java index 6e56942..51da04b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java @@ -231,8 +231,6 @@ import org.apache.ignite.internal.util.typedef.F; * @return Unwrapped object. */ private Object unwrapBinary(Object o, boolean keepBinary, boolean cpy) { - if (kernalCtx.json().jsonObject(o)) - return ((CacheObject)o).value(this, cpy); if (o instanceof Map.Entry) { Map.Entry entry = (Map.Entry)o; @@ -255,6 +253,9 @@ import org.apache.ignite.internal.util.typedef.F; else if (o instanceof CacheObject) { CacheObject co = (CacheObject)o; + if (kernalCtx.json().jsonObject(co)) + return kernalCtx.json().value(co); + if (!keepBinary || co.isPlatformType()) return unwrapBinary(co.value(this, cpy), keepBinary, cpy); } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java index ff1762d..9bd81c4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java @@ -64,4 +64,9 @@ public class IgniteJsonNoopProcessor extends GridProcessorAdapter implements Ign @Override public Object field(Object obj, String fieldName) { return null; } + + /** {@inheritDoc} */ + @Override public Object value(Object obj) { + return null; + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java index 0c36307..59985f3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java @@ -68,4 +68,9 @@ public interface IgniteJsonProcessor extends GridProcessor { * @return Field value. */ public Object field(Object obj, String fieldName); + + /** + * @param obj Object. + */ + public Object value(Object obj); } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java index b75b132..91ad01d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java @@ -144,10 +144,6 @@ public class GridQueryProcessor extends GridProcessorAdapter { /** */ private final GridQueryIndexing idx; - /** */ - // TODO IGNITE-961 - private TypeId jsonTypeId; - /** * @param ctx Kernal context. */ @@ -279,14 +275,6 @@ public class GridQueryProcessor extends GridProcessorAdapter { if (valCls != null) altTypeId = new TypeId(ccfg.getName(), valCls); } - else if (ctx.json().jsonType(desc.keyClass()) || ctx.json().jsonType(desc.valueClass())) { - // TODO IGNITE-961 - // processJsonMeta(meta, desc); - - typeId = new TypeId(ccfg.getName(), valCls); - - jsonTypeId = typeId; - } else { processClassMeta(qryEntity, desc, coCtx); @@ -676,47 +664,39 @@ public class GridQueryProcessor extends GridProcessorAdapter { TypeDescriptor desc; - // TODO IGNITE-961 - if (ctx.json().jsonObject(val) && jsonTypeId != null) { - desc = types.get(jsonTypeId); - - assert desc != null && desc.registered() : desc; - } - else { - Class<?> valCls = null; + Class<?> valCls = null; - TypeId id; + TypeId id; - boolean binaryVal = ctx.cacheObjects().isBinaryObject(val); + boolean binaryVal = ctx.cacheObjects().isBinaryObject(val); - if (binaryVal) { - int typeId = ctx.cacheObjects().typeId(val); + if (binaryVal) { + int typeId = ctx.cacheObjects().typeId(val); - id = new TypeId(space, typeId); - } - else { - valCls = val.value(coctx, false).getClass(); + id = new TypeId(space, typeId); + } + else { + valCls = val.value(coctx, false).getClass(); - id = new TypeId(space, valCls); - } + id = new TypeId(space, valCls); + } - desc = types.get(id); + desc = types.get(id); - if (desc == null || !desc.registered()) - return; + if (desc == null || !desc.registered()) + return; - if (!binaryVal && !desc.valueClass().isAssignableFrom(valCls)) - throw new IgniteCheckedException("Failed to update index due to class name conflict" + - "(multiple classes with same simple name are stored in the same cache) " + - "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']'); + if (!binaryVal && !desc.valueClass().isAssignableFrom(valCls)) + throw new IgniteCheckedException("Failed to update index due to class name conflict" + + "(multiple classes with same simple name are stored in the same cache) " + + "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']'); - if (!ctx.cacheObjects().isBinaryObject(key)) { - Class<?> keyCls = key.value(coctx, false).getClass(); + if (!ctx.cacheObjects().isBinaryObject(key)) { + Class<?> keyCls = key.value(coctx, false).getClass(); - if (!desc.keyClass().isAssignableFrom(keyCls)) - throw new IgniteCheckedException("Failed to update index, incorrect key class [expCls=" + - desc.keyClass().getName() + ", actualCls=" + keyCls.getName() + "]"); - } + if (!desc.keyClass().isAssignableFrom(keyCls)) + throw new IgniteCheckedException("Failed to update index, incorrect key class [expCls=" + + desc.keyClass().getName() + ", actualCls=" + keyCls.getName() + "]"); } idx.store(space, desc, key, val, ver, expirationTime); http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index 0e5d078..e85ce9f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -445,6 +445,7 @@ public class GridRestProcessor extends GridProcessorAdapter { addHandler(new DataStructuresCommandHandler(ctx)); addHandler(new QueryCommandHandler(ctx)); addHandler(new GridLogCommandHandler(ctx)); + addHandler(new IgniteScriptingCommandHandler(ctx)); // Start protocols. startTcpProtocol(); @@ -469,7 +470,10 @@ public class GridRestProcessor extends GridProcessorAdapter { } } } + } + /** {@inheritDoc} */ + @Override public void onKernalStart() throws IgniteCheckedException { if (isRestEnabled()) { for (GridRestProtocol proto : protos) proto.onKernalStart(); @@ -482,15 +486,6 @@ public class GridRestProcessor extends GridProcessorAdapter { if (log.isDebugEnabled()) log.debug("REST processor started."); - - // Register handlers. - addHandler(new GridCacheCommandHandler(ctx)); - addHandler(new GridTaskCommandHandler(ctx)); - addHandler(new GridTopologyCommandHandler(ctx)); - addHandler(new GridVersionNameCommandHandler(ctx)); - addHandler(new DataStructuresCommandHandler(ctx)); - addHandler(new QueryCommandHandler(ctx)); - addHandler(new IgniteScriptingCommandHandler(ctx)); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java index 2f568ec..420c472 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java @@ -18,31 +18,44 @@ package org.apache.ignite.internal.processors.json; import java.io.Serializable; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import javax.json.JsonArray; import javax.json.JsonNumber; +import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; +import org.apache.ignite.internal.util.typedef.internal.A; +import org.jetbrains.annotations.NotNull; + +import static org.apache.ignite.internal.processors.json.IgniteJsonUtils.toJsonValue; /** * Implementation of JsonArray */ -public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray, Serializable { +public class IgniteJsonArray implements JsonArray, Serializable { + /** Empty array. */ + private static final Object[] EMPTY_ARR = new Object[0]; + /** Values for getValueAs. */ - private List<JsonValue> val; + private List<Object> list; /** * @param val List json values. */ - public IgniteJsonArray(List<JsonValue> val) { - super(val); + public IgniteJsonArray(List<Object> val) { + this.list = Collections.unmodifiableList(val); } /** {@inheritDoc} */ - @Override public IgniteJsonObject getJsonObject(int idx) { - return (IgniteJsonObject)get(idx); + @Override public JsonObject getJsonObject(int idx) { + return (JsonObject)get(idx); } /** {@inheritDoc} */ @@ -63,15 +76,7 @@ public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray, /** {@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; + return toJsonValueList(list); } /** {@inheritDoc} */ @@ -107,10 +112,10 @@ public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray, @Override public boolean getBoolean(int idx) { JsonValue val = get(idx); - if (val.equals(JsonValue.TRUE)) + if (val == JsonValue.TRUE) return true; - if (val.equals(JsonValue.FALSE)) + if (val == JsonValue.FALSE) return false; throw new ClassCastException(); @@ -118,20 +123,345 @@ public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray, /** {@inheritDoc} */ @Override public boolean getBoolean(int idx, boolean dfltVal) { - try { - return getBoolean(idx); - } catch (Exception e) { + if (idx >= list.size()) return dfltVal; - } + + JsonValue val = get(idx); + + if (val == JsonValue.TRUE) + return true; + + if (val == JsonValue.FALSE) + return false; + + return dfltVal; } /** {@inheritDoc} */ @Override public boolean isNull(int idx) { - return get(idx).equals(JsonValue.NULL); + return get(idx) == JsonValue.NULL; } /** {@inheritDoc} */ @Override public ValueType getValueType() { return ValueType.ARRAY; } + + /** {@inheritDoc} */ + @Override public int size() { + return list.size(); + } + + /** {@inheritDoc} */ + @Override public boolean isEmpty() { + return list.isEmpty(); + } + + /** {@inheritDoc} */ + @Override public boolean contains(Object obj) { + return indexOf(obj) > -1; + } + + /** + * @param val {@code JsonNumber} instance. + */ + private int indexOf(JsonNumber val, boolean last) { + for (int i = last ? list.size() - 1 : 0; + (last && i > 0) || i < list.size(); i += last ? -1 : 1) { + Object obj = list.get(i); + + if (obj instanceof Number && + (obj instanceof Integer && obj.equals(val.intValue()) || + obj instanceof Long && obj.equals(val.longValue()) || + obj instanceof Double && obj.equals(val.doubleValue()) || + obj instanceof BigInteger && obj.equals(val.bigIntegerValue()) || + obj instanceof BigDecimal && obj.equals(val.bigDecimalValue()))) + return i; + } + + return -1; + } + + /** {@inheritDoc} */ + @NotNull @Override public Iterator<JsonValue> iterator() { + return new ImmutableIterator(); + } + + /** {@inheritDoc} */ + @NotNull @Override public Object[] toArray() { + return toArray(EMPTY_ARR); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @NotNull @Override public <T> T[] toArray(T[] arr) { + arr = (T[])new Object[list.size()]; + + for (int i = 0; i < list.size(); i++) + arr[i] = (T)toJsonValue(list.get(i)); + + return arr; + } + + /** {@inheritDoc} */ + @Override public boolean add(JsonValue val) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean containsAll(Collection<?> col) { + for (Object e : col) { + if (!contains(e)) + return false; + } + + return true; + } + + /** {@inheritDoc} */ + @Override public boolean addAll(Collection<? extends JsonValue> c) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean addAll(int idx, Collection<? extends JsonValue> c) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean removeAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean retainAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void clear() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public JsonValue get(int idx) { + Object val = list.get(idx); + + return val == null ? JsonValue.NULL : toJsonValue(val); + } + + /** {@inheritDoc} */ + @Override public JsonValue set(int idx, JsonValue element) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void add(int idx, JsonValue element) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public JsonValue remove(int idx) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public int indexOf(Object obj) { + A.notNull(obj, "obj"); + + JsonValue val = (JsonValue)obj; + + JsonValue.ValueType valType = val.getValueType(); + + switch (valType) { + case ARRAY: + return list.indexOf(((IgniteJsonArray)val).list()); + + case OBJECT: + return list.indexOf(((IgniteJsonObject)val).binaryObject()); + + case STRING: + return list.indexOf(((JsonString)val).getString()); + + case NUMBER: + return indexOf((JsonNumber)val, false); + + case TRUE: + return list.indexOf(Boolean.TRUE); + + case FALSE: + return list.indexOf(Boolean.FALSE); + + case NULL: + return list.indexOf(null); + + default: + throw new IllegalArgumentException("Unknown value type " + valType); + } + } + + /** {@inheritDoc} */ + @Override public int lastIndexOf(Object obj) { + A.notNull(obj, "obj"); + + JsonValue val = (JsonValue)obj; + + JsonValue.ValueType valType = val.getValueType(); + + switch (valType) { + case ARRAY: + return list.lastIndexOf(((IgniteJsonArray)val).list()); + + case OBJECT: + return list.lastIndexOf(((IgniteJsonObject)val).binaryObject()); + + case STRING: + return list.lastIndexOf(((JsonString)val).getString()); + + case NUMBER: + return indexOf((JsonNumber)val, true); + + case TRUE: + return list.lastIndexOf(Boolean.TRUE); + + case FALSE: + return list.lastIndexOf(Boolean.FALSE); + + case NULL: + return list.lastIndexOf(null); + + default: + throw new IllegalArgumentException("Unknown value type " + valType); + } + } + + /** {@inheritDoc} */ + @NotNull @Override public ListIterator<JsonValue> listIterator() { + return new ImmutableIterator(); + } + + /** {@inheritDoc} */ + @NotNull @Override public ListIterator<JsonValue> listIterator(int idx) { + return new ImmutableIterator(idx); + } + + /** {@inheritDoc} */ + @NotNull @Override public List<JsonValue> subList(int fromIdx, int toIdx) { + return toJsonValueList(list.subList(fromIdx, toIdx)); + } + + /** + * Returns backing list. + * + * @return Backing list. + */ + List<Object> list() { + return list; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + IgniteJsonArray arr = (IgniteJsonArray)o; + + return list.equals(arr.list); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return list.hashCode(); + } + + /** + * @param l Object list. + */ + @SuppressWarnings("unchecked") + private static <T> List<T> toJsonValueList(List<Object> l) { + if (l.isEmpty()) + return Collections.emptyList(); + + List<T> res = new ArrayList<>(); + + for (Object val : l) + res.add((T)toJsonValue(val)); + + return Collections.unmodifiableList(res); + } + + /** + * Immutable list iterator. + */ + private class ImmutableIterator implements ListIterator<JsonValue> { + /** Backing list iterator. */ + final ListIterator<Object> it; + + /** + * Default constructor. + */ + public ImmutableIterator() { + this(0); + } + + /** + * @param idx Index. + */ + public ImmutableIterator(int idx) { + it = list.listIterator(idx); + } + + /** {@inheritDoc} */ + @Override public boolean hasNext() { + return it.hasNext(); + } + + /** {@inheritDoc} */ + @Override public JsonValue next() { + return toJsonValue(it.next()); + } + + /** {@inheritDoc} */ + @Override public boolean hasPrevious() { + return it.hasPrevious(); + } + + /** {@inheritDoc} */ + @Override public JsonValue previous() { + return toJsonValue(it.previous()); + } + + /** {@inheritDoc} */ + @Override public int nextIndex() { + return it.nextIndex(); + } + + /** {@inheritDoc} */ + @Override public int previousIndex() { + return it.previousIndex(); + } + + /** {@inheritDoc} */ + @Override public void remove() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void set(JsonValue val) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void add(JsonValue val) { + throw new UnsupportedOperationException(); + } + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java index 8da9da2..772bb65 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java @@ -23,7 +23,9 @@ import java.util.ArrayList; import java.util.List; import javax.json.JsonArray; import javax.json.JsonArrayBuilder; +import javax.json.JsonNumber; import javax.json.JsonObjectBuilder; +import javax.json.JsonString; import javax.json.JsonValue; import org.apache.ignite.internal.util.typedef.internal.A; @@ -31,104 +33,144 @@ import org.apache.ignite.internal.util.typedef.internal.A; * Json array builder. */ public class IgniteJsonArrayBuilder implements JsonArrayBuilder { - /** Json array list. */ - private List<JsonValue> jsonList = new ArrayList<>(); + /** Values list. */ + private List<Object> list = new ArrayList<>(); /** {@inheritDoc} */ @Override public JsonArrayBuilder add(JsonValue val) { A.notNull(val, "value"); - jsonList.add(val); + JsonValue.ValueType valType = val.getValueType(); + + switch (valType) { + case ARRAY: + list.add(((IgniteJsonArray)val).list()); + + break; + + case OBJECT: + list.add(((IgniteJsonObject)val).binaryObject()); + + break; + case STRING: + list.add(((JsonString)val).getString()); + + break; + case NUMBER: + //TODO: Optimize for value + list.add(((JsonNumber)val).bigDecimalValue()); + + break; + case TRUE: + list.add(true); + + break; + case FALSE: + list.add(false); + + break; + case NULL: + list.add(null); + + break; + default: + throw new IllegalArgumentException("Unknown value type " + valType); + } return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(String val) { - A.notNull(val, "value"); + A.notNull(val, "val"); - jsonList.add(new IgniteJsonString(val)); + list.add(val); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(BigDecimal val) { - A.notNull(val, "value"); + A.notNull(val, "val"); - jsonList.add(new IgniteJsonNumber(val)); + list.add(val); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(BigInteger val) { - A.notNull(val, "value"); + A.notNull(val, "val"); - //TODO: optimize for value - jsonList.add(new IgniteJsonNumber(new BigDecimal(val))); + list.add(val); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(int val) { - //TODO: optimize for value - jsonList.add(new IgniteJsonNumber(new BigDecimal(val))); + list.add(val); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(long val) { - //TODO: optimize for value - jsonList.add(new IgniteJsonNumber(new BigDecimal(val))); + list.add(val); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(double val) { - //TODO: optimize for value - jsonList.add(new IgniteJsonNumber(new BigDecimal(val))); + list.add(val); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(boolean val) { - jsonList.add(val ? JsonValue.TRUE : JsonValue.FALSE); + list.add(val); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder addNull() { - jsonList.add(JsonValue.NULL); + list.add(null); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(JsonObjectBuilder bld) { - A.notNull(bld, "value"); + A.notNull(bld, "bld"); - jsonList.add(bld.build()); + list.add(((IgniteJsonObject)bld.build()).binaryObject()); return this; } /** {@inheritDoc} */ @Override public JsonArrayBuilder add(JsonArrayBuilder bld) { - A.notNull(bld, "value"); + A.notNull(bld, "bld"); - jsonList.add(bld.build()); + list.add(((IgniteJsonArrayBuilder)bld).list()); return this; } /** {@inheritDoc} */ @Override public JsonArray build() { - return new IgniteJsonArray(jsonList); + return new IgniteJsonArray(list); + } + + /** + * Returns backing objects list. + * + * @return backing objects list. + */ + List<Object> list() { + return list; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java index f432887..4298fe4 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java @@ -39,7 +39,8 @@ public class IgniteJsonGenerator implements JsonGenerator { /** Writer. */ private final BufferedWriter writer; - private LinkedList<Element> ctx = new LinkedList(); + /** Context. */ + private LinkedList<Element> ctx = new LinkedList<>(); /** * @param writer Writer. http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java index 791aa91..fa364e8 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java @@ -20,7 +20,7 @@ package org.apache.ignite.internal.processors.json; import javax.json.stream.JsonLocation; /** - * Json location implementation. + * JSON location implementation. */ public class IgniteJsonLocation implements JsonLocation { /** Column number. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java deleted file mode 100644 index 0186064..0000000 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.internal.processors.json; - -import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.plugin.extensions.communication.MessageFactory; -import org.jetbrains.annotations.Nullable; - -/** - * - */ -public class IgniteJsonMessageFactory implements MessageFactory { - /** {@inheritDoc} */ - @Nullable @Override public Message create(byte type) { - switch (type) { - case -23: - return new JsonCacheObject(); - } - - return null; - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java index 566d4a8..b12001c 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java @@ -23,7 +23,7 @@ import java.math.BigInteger; import javax.json.JsonNumber; /** - * Json number implementation. + * JSON number implementation. * * TODO IGNITE-962: optimize for int, long, double. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java index b14e346..39b4a7c 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java @@ -18,22 +18,49 @@ package org.apache.ignite.internal.processors.json; import java.io.Serializable; -import java.util.HashMap; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import javax.json.JsonArray; import javax.json.JsonNumber; +import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.internal.util.typedef.internal.A; +import org.jetbrains.annotations.NotNull; + +import static org.apache.ignite.internal.processors.json.IgniteJsonUtils.toJsonValue; /** * IgniteJsonObject implementation. */ -public class IgniteJsonObject extends HashMap<String, JsonValue> implements javax.json.JsonObject, Serializable { +public class IgniteJsonObject implements javax.json.JsonObject, Serializable { + /** Bin object. */ + private final BinaryObject binObj; + + /** Size. */ + private int size; + /** - * @param val Map to store. + * @param binObj Binary object. */ - public IgniteJsonObject(Map<String, JsonValue> val) { - super(val); + public IgniteJsonObject(BinaryObject binObj) { + this(binObj, -1); + } + + /** + * @param binObj Binary object. + * @param size Size. + */ + public IgniteJsonObject(BinaryObject binObj, int size) { + this.binObj = binObj; + this.size = size; } /** {@inheritDoc} */ @@ -43,7 +70,7 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java /** {@inheritDoc} */ @Override public javax.json.JsonObject getJsonObject(String name) { - return (javax.json.JsonObject)get(name); + return (JsonObject)get(name); } /** {@inheritDoc} */ @@ -90,10 +117,13 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java @Override public boolean getBoolean(String name) { JsonValue val = get(name); - if (val.equals(JsonValue.TRUE)) + if (val == null) + throw new NullPointerException(); + + if (val == JsonValue.TRUE) return true; - if (val.equals(JsonValue.FALSE)) + if (val == JsonValue.FALSE) return false; throw new ClassCastException(); @@ -101,17 +131,25 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java /** {@inheritDoc} */ @Override public boolean getBoolean(String name, boolean dfltVal) { - try { - return getBoolean(name); - } - catch (Exception e) { - return dfltVal; - } + JsonValue val = get(name); + + if (val == JsonValue.TRUE) + return true; + + if (val == JsonValue.FALSE) + return false; + + return dfltVal; } /** {@inheritDoc} */ @Override public boolean isNull(String name) { - return get(name).equals(JsonValue.NULL); + JsonValue val = get(name); + + if (val == null) + throw new NullPointerException(); + + return val == JsonValue.NULL; } /** {@inheritDoc} */ @@ -119,16 +157,148 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java return ValueType.OBJECT; } - /** {@inheritDoc}*/ + /** {@inheritDoc} */ + @Override public int size() { + if (size == -1) { + for (String field : binObj.type().fieldNames()) { + if (binObj.hasField(field)) + size++; + } + + size++; + } + + return size; + } + + /** {@inheritDoc} */ + @Override public boolean isEmpty() { + return size() == 0; + } + + /** {@inheritDoc} */ + @Override public boolean containsKey(Object key) { + A.notNull(key, "key"); + + return binObj.hasField((String)key); + } + + /** {@inheritDoc} */ + @Override public boolean containsValue(Object val) { + A.notNull(val, "val"); + + JsonValue val0 = (JsonValue)val; + + for (String key : binObj.type().fieldNames()) { + Object field = binObj.field(key); + + if (field == null && val0 == JsonValue.NULL && binObj.hasField(key) || + field != null && toJsonValue(field).equals(val)) + return true; + } + + return false; + } + + /** {@inheritDoc} */ + @Override public JsonValue get(Object key) { + A.notNull(key, "key"); + + Object val = binObj.field((String)key); + + if (val == null) + return binObj.hasField((String)key) ? JsonValue.NULL : null; + + return toJsonValue(val); + } + + /** {@inheritDoc} */ + @Override public JsonValue put(String key, JsonValue val) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public JsonValue remove(Object key) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void putAll(Map<? extends String, ? extends JsonValue> m) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void clear() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + //TODO: Preserve iteration order. See JsonObject#keySet javadoc. + @NotNull @Override public Set<String> keySet() { + if (isEmpty()) + return Collections.emptySet(); + + Set<String> keys = new HashSet<>(); + + for (String name : binObj.type().fieldNames()) { + if (binObj.hasField(name)) + keys.add(name); + } + + return Collections.unmodifiableSet(keys); + } + + /** {@inheritDoc} */ + //TODO: Preserve iteration order. See JsonObject#values javadoc. + @NotNull @Override public Collection<JsonValue> values() { + if (isEmpty()) + return Collections.emptyList(); + + List<JsonValue> vals = new ArrayList<>(); + + for (String name : binObj.type().fieldNames()) { + if (binObj.hasField(name)) + vals.add(toJsonValue(binObj.field(name))); + } + + return Collections.unmodifiableList(vals); + } + + /** {@inheritDoc} */ + //TODO: Preserve iteration order. See JsonObject#entrySet javadoc. + @NotNull @Override public Set<Entry<String, JsonValue>> entrySet() { + if (isEmpty()) + return Collections.emptySet(); + + Set<Entry<String, JsonValue>> entries = new HashSet<>(); + + for (String name : binObj.type().fieldNames()) { + if (binObj.hasField(name)) + entries.add(new AbstractMap.SimpleImmutableEntry<>(name, toJsonValue(binObj.field(name)))); + } + + return Collections.unmodifiableSet(entries); + } + + /** + * Returns backing {@link BinaryObject} instance. + * + * @return Backing {@link BinaryObject} instance. + */ + BinaryObject binaryObject() { + return binObj; + } + + /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (o == null || !(o instanceof IgniteJsonObject)) return false; - return super.equals(o); + return binObj.equals(((IgniteJsonObject)o).binObj); } - /** {@inheritDoc}*/ + /** {@inheritDoc} */ @Override public int hashCode() { - return super.hashCode(); + return binObj.hashCode(); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java index 784b291..f6fa26a 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java @@ -19,25 +19,70 @@ package org.apache.ignite.internal.processors.json; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.HashMap; import java.util.Map; import javax.json.JsonArrayBuilder; +import javax.json.JsonNumber; +import javax.json.JsonObject; import javax.json.JsonObjectBuilder; +import javax.json.JsonString; import javax.json.JsonValue; +import org.apache.ignite.binary.BinaryObjectBuilder; +import org.apache.ignite.internal.IgniteKernal; +import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl; import org.apache.ignite.internal.util.typedef.internal.A; /** * JSON object builder implementation. */ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { - /** JSON object map. */ - private Map<String, JsonValue> jsonMap = new HashMap<>(); + /** Binary object builder. */ + private final BinaryObjectBuilder binObjBuilder; + + /** + * @param kernal Kernal. + */ + public IgniteJsonObjectBuilder(IgniteKernal kernal) { + this.binObjBuilder = kernal.binary().builder(JsonObject.class.getName()); + } /** {@inheritDoc} */ @Override public JsonObjectBuilder add(String name, JsonValue val) { A.notNull(name, "name", val, "val"); - jsonMap.put(name, val); + JsonValue.ValueType valType = val.getValueType(); + + switch (valType) { + case ARRAY: + binObjBuilder.setField(name, ((IgniteJsonArray)val).list(), Object.class); + + break; + case OBJECT: + binObjBuilder.setField(name, ((IgniteJsonObject)val).binaryObject(), Object.class); + + break; + case STRING: + add(name, ((JsonString)val).getString()); + + break; + case NUMBER: + add(name, ((JsonNumber)val).bigDecimalValue()); + + break; + case TRUE: + add(name, true); + + break; + case FALSE: + add(name, false); + + break; + case NULL: + addNull(name); + + break; + default: + throw new IllegalArgumentException("Unknown value type " + valType); + } return this; } @@ -46,7 +91,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, String val) { A.notNull(name, "name", val, "val"); - jsonMap.put(name, new IgniteJsonString(val)); + binObjBuilder.setField(name, val, Object.class); return this; } @@ -55,8 +100,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, BigInteger val) { A.notNull(name, "name", val, "val"); - //TODO: optimize for value - jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val))); + binObjBuilder.setField(name, val, Object.class); return this; } @@ -65,8 +109,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, BigDecimal val) { A.notNull(name, "name", val, "val"); - //TODO: optimize for value - jsonMap.put(name, new IgniteJsonNumber(val)); + binObjBuilder.setField(name, val, Object.class); return this; } @@ -75,8 +118,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, int val) { A.notNull(name, "name"); - //TODO: optimize for value - jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val))); + binObjBuilder.setField(name, val, Object.class); return this; } @@ -85,8 +127,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, long val) { A.notNull(name, "name"); - //TODO: optimize for value - jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val))); + binObjBuilder.setField(name, val, Object.class); return this; } @@ -95,8 +136,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, double val) { A.notNull(name, "name"); - //TODO: optimize for value - jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val))); + binObjBuilder.setField(name, val, Object.class); return this; } @@ -105,7 +145,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, boolean val) { A.notNull(name, "name"); - jsonMap.put(name, val ? JsonValue.TRUE : JsonValue.FALSE); + binObjBuilder.setField(name, val, Object.class); return this; } @@ -114,7 +154,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder addNull(String name) { A.notNull(name, "name"); - jsonMap.put(name, JsonValue.NULL); + binObjBuilder.setField(name, null, Object.class); return this; } @@ -123,7 +163,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, JsonObjectBuilder builder) { A.notNull(name, "name", builder, "builder"); - jsonMap.put(name, builder.build()); + binObjBuilder.setField(name, ((IgniteJsonObject)builder.build()).binaryObject(), Object.class); return this; } @@ -132,13 +172,25 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder { @Override public JsonObjectBuilder add(String name, JsonArrayBuilder builder) { A.notNull(name, "name", builder, "builder"); - jsonMap.put(name, builder.build()); + binObjBuilder.setField(name, ((IgniteJsonArrayBuilder)builder).list(), Object.class); return this; } /** {@inheritDoc} */ @Override public javax.json.JsonObject build() { - return new IgniteJsonObject(jsonMap); + //TODO: user defined hashCode() + int h = 0; + + Map<String, Object> assignedVals = ((BinaryObjectBuilderImpl)binObjBuilder).assignedVals(); + + if (assignedVals != null) { + for (Map.Entry<String, Object> e : assignedVals.entrySet()) + h += e.getKey().hashCode() ^ e.getValue().hashCode(); + } + + binObjBuilder.hashCode(h); + + return new IgniteJsonObject(binObjBuilder.build(), assignedVals == null ? 0 : assignedVals.size()); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java index 1f599bb..292b648 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java @@ -22,6 +22,7 @@ import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; import org.apache.ignite.IgniteException; +import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.processors.GridProcessorAdapter; import org.apache.ignite.internal.processors.cache.CacheObject; @@ -30,7 +31,7 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.jetbrains.annotations.Nullable; /** - * + * Ignite JSON objects processor. */ public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements IgniteJsonProcessor { /** @@ -42,8 +43,13 @@ public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements Ign /** {@inheritDoc} */ @Override public KeyCacheObject toCacheKeyObject(CacheObjectContext ctx, Object obj, boolean userObj) { - if (obj instanceof JsonObject) - return new JsonCacheObject((JsonObject)obj); + if (obj instanceof JsonObject) { + IgniteJsonObject jsonObj = (IgniteJsonObject)obj; + + BinaryObject binObj = jsonObj.binaryObject(); + + return ctx.processor().toCacheKeyObject(ctx, binObj, userObj); + } return null; } @@ -52,8 +58,13 @@ public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements Ign @Nullable @Override public CacheObject toCacheObject(CacheObjectContext ctx, @Nullable Object obj, boolean userObj) { - if (obj instanceof JsonObject) - return new JsonCacheObject((JsonObject)obj); + if (obj instanceof JsonObject) { + IgniteJsonObject jsonObj = (IgniteJsonObject)obj; + + BinaryObject binObj = jsonObj.binaryObject(); + + return ctx.processor().toCacheObject(ctx, binObj, userObj); + } return null; } @@ -65,23 +76,26 @@ public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements Ign /** {@inheritDoc} */ @Override public boolean jsonObject(Object obj) { - return obj instanceof JsonCacheObject || obj instanceof JsonObject; + return obj instanceof JsonObject || obj instanceof BinaryObject && + ((BinaryObject)obj).type().typeName().equals(JsonObject.class.getName()); } /** {@inheritDoc} */ @Override public boolean hasField(Object obj, String fieldName) { - if (obj instanceof JsonObject) - return ((JsonObject)obj).containsKey(fieldName); - - return ((JsonCacheObject)obj).hasField(fieldName); + return ((JsonObject)obj).containsKey(fieldName); } /** {@inheritDoc} */ @Override public Object field(Object obj, String fieldName) { - if (obj instanceof JsonObject) - return value((JsonObject) obj, fieldName); + return value((JsonObject) obj, fieldName); + } - return ((JsonCacheObject)obj).field(fieldName); + /** {@inheritDoc} */ + @Override public Object value(Object obj) { + if (obj instanceof BinaryObject) + return new IgniteJsonObject((BinaryObject)obj); + + return null; } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java index 8734ec3..f022628 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java @@ -34,11 +34,22 @@ import javax.json.stream.JsonGenerator; import javax.json.stream.JsonGeneratorFactory; import javax.json.stream.JsonParser; import javax.json.stream.JsonParserFactory; +import org.apache.ignite.internal.IgniteKernal; /** * JSON provider implementation. */ public class IgniteJsonProvider extends JsonProvider { + /** Kernal. */ + private final IgniteKernal kernal; + + /** + * @param kernal Kernal. + */ + public IgniteJsonProvider(IgniteKernal kernal) { + this.kernal = kernal; + } + /** {@inheritDoc} */ @Override public JsonParser createParser(Reader reader) { return null; @@ -101,7 +112,7 @@ public class IgniteJsonProvider extends JsonProvider { /** {@inheritDoc} */ @Override public JsonObjectBuilder createObjectBuilder() { - return new IgniteJsonObjectBuilder(); + return new IgniteJsonObjectBuilder(kernal); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java index 96744d5..657ab4e 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java @@ -21,7 +21,7 @@ import java.io.Serializable; import javax.json.JsonString; /** - * Json string implementation. + * JSON string implementation. */ public class IgniteJsonString implements JsonString, Serializable { /** Value. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java new file mode 100644 index 0000000..cf6d84a --- /dev/null +++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java @@ -0,0 +1,58 @@ +/* + * 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.internal.processors.json; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; +import javax.json.JsonValue; +import org.apache.ignite.binary.BinaryObject; + +/** + * JSON related utils. + */ +public class IgniteJsonUtils { + /** + * @param val Value. + */ + public static JsonValue toJsonValue(Object val) { + if (val == null) + return JsonValue.NULL; + else if (val instanceof Integer) + return new IgniteJsonNumber(new BigDecimal((Integer)val)); + else if (val instanceof Long) + return new IgniteJsonNumber(new BigDecimal((Long)val)); + else if (val instanceof Double) + return new IgniteJsonNumber(new BigDecimal((Double)val)); + else if (val instanceof BigInteger) + return new IgniteJsonNumber(new BigDecimal((BigInteger)val)); + else if (val instanceof BigDecimal) + return new IgniteJsonNumber((BigDecimal)val); + else if (val instanceof String) + return new IgniteJsonString((String)val); + else if (val instanceof Boolean) + return (Boolean)val ? JsonValue.TRUE : JsonValue.FALSE; + else if (val instanceof BinaryObject) + return new IgniteJsonObject((BinaryObject)val); + else if (val instanceof List) + return new IgniteJsonArray((List<Object>)val); + else + throw new IllegalArgumentException("Unknown value type: " + val.getClass().getName()); + } + +} http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java deleted file mode 100644 index 977472e..0000000 --- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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.internal.processors.json; - -import javax.json.JsonObject; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.CacheObjectAdapter; -import org.apache.ignite.internal.processors.cache.CacheObjectContext; -import org.apache.ignite.internal.processors.cache.KeyCacheObject; -import org.jetbrains.annotations.Nullable; - -/** - * TODO IGNITE-961 - */ -public class JsonCacheObject extends CacheObjectAdapter implements KeyCacheObject { - /** - * - */ - public JsonCacheObject() { - // No-op. - } - - /** - * @param obj Object. - */ - public JsonCacheObject(JsonObject obj) { - this.val = obj; - } - - /** {@inheritDoc} */ - @Override public boolean isPlatformType() { - // TODO IGNITE-961 - return false; - } - - /** {@inheritDoc} */ - @Override public byte cacheObjectType() { - // TODO IGNITE-961 - return 10; - } - - /** {@inheritDoc} */ - @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) { - return (T)val; - } - - /** {@inheritDoc} */ - @Override public byte[] valueBytes(CacheObjectContext ctx) throws IgniteCheckedException { - return valBytes; - } - - /** {@inheritDoc} */ - @Override public CacheObject prepareForCache(CacheObjectContext ctx) { - return this; - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectContext ctx, ClassLoader ldr) throws IgniteCheckedException { - assert val != null || valBytes != null; - - if (val == null) - val = ctx.processor().unmarshal(ctx, valBytes, ldr); - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectContext ctx) throws IgniteCheckedException { - if (valBytes == null) - valBytes = ctx.processor().marshal(ctx, val); - } - - /** {@inheritDoc} */ - @Override public boolean internal() { - return false; - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return -23; - } - - /** - * @param fieldName Field name. - * @return {@code True} if has field. - */ - boolean hasField(String fieldName) { - return ((IgniteJsonObject)val).containsKey(fieldName); - } - - /** - * @param fieldName Field name. - * @return Field value. - */ - Object field(String fieldName) { - return IgniteJsonProcessorImpl.value((JsonObject)val, fieldName); - } - - /** {@inheritDoc}*/ - @Override public int hashCode() { - // TODO IGNITE-961 - return val.hashCode(); - } - - /** {@inheritDoc}*/ - @Override public boolean equals(Object obj) { - // TODO IGNITE-961 - if (obj == null || !(obj instanceof JsonCacheObject)) - return false; - - return val.equals(((JsonCacheObject)obj).val); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java ---------------------------------------------------------------------- diff --git a/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java b/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java index 983dc44..0515da6 100644 --- a/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java +++ b/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java @@ -19,6 +19,7 @@ package org.apache.ignite.json; import javax.json.spi.JsonProvider; import org.apache.ignite.Ignite; +import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.processors.json.IgniteJsonProvider; /** @@ -30,6 +31,6 @@ public class IgniteJson { * @return Ignite JSON API provider. */ public static JsonProvider jsonProvider(Ignite ignite) { - return new IgniteJsonProvider(); + return new IgniteJsonProvider((IgniteKernal)ignite); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java b/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java new file mode 100644 index 0000000..4cbb839 --- /dev/null +++ b/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java @@ -0,0 +1,145 @@ +/* + * 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.internal.processors.json; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.json.JsonValue; +import javax.json.spi.JsonProvider; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.json.IgniteJson; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Tests for {@link IgniteJsonArrayBuilder} implementation. + */ +public class IgniteJsonArrayBuilderSelfTest extends GridCommonAbstractTest { + /** JSON provider. */ + private static JsonProvider json; + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + json = IgniteJson.jsonProvider(startGrid()); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + stopAllGrids(); + } + + /** + * @throws Exception If failed. + */ + public void testAddJavaObjects() throws Exception { + JsonArray arr = json.createArrayBuilder() + .add(true) + .add(false) + .add(1) + .add(1L) + .add(1.0) + .add(new BigInteger("1")) + .add(new BigDecimal(1)) + .add("string") + .build(); + + List<Object> list = ((IgniteJsonArray)arr).list(); + + assertEquals(JsonValue.TRUE, arr.get(0)); + assertEquals(Boolean.TRUE, list.get(0)); + + assertEquals(JsonValue.FALSE, arr.get(1)); + assertEquals(Boolean.FALSE, list.get(1)); + + assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(2)); + assertEquals(1, list.get(2)); + + assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(3)); + assertEquals(1L, list.get(3)); + + assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(4)); + assertEquals(1.0, (Double)list.get(4), 0); + + assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(5)); + assertEquals(new BigInteger("1"), list.get(5)); + + assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(6)); + assertEquals(new BigDecimal(1), list.get(6)); + + assertEquals(new IgniteJsonString("string"), arr.get(7)); + assertEquals("string", list.get(7)); + } + + /** + * @throws Exception If failed. + */ + public void testAddJsonObjects() throws Exception { + JsonArray arr = json.createArrayBuilder() + .addNull() + .add(JsonValue.NULL) + .add(JsonValue.TRUE) + .add(JsonValue.FALSE) + .add(new IgniteJsonNumber(new BigDecimal(1))) + .add(new IgniteJsonString("string")) + .add(json.createArrayBuilder().add(1).add(2).build()) + .add(json.createArrayBuilder().add(1).add(2)) + .add(json.createObjectBuilder().add("k1", 1).add("k2", 2).build()) + .add(json.createObjectBuilder().add("k1", 1).add("k2", 2)) + .build(); + + List<Object> list = ((IgniteJsonArray)arr).list(); + + assertEquals(JsonValue.NULL, arr.get(0)); + assertNull(list.get(0)); + + assertEquals(JsonValue.NULL, arr.get(1)); + assertNull(list.get(1)); + + assertEquals(JsonValue.TRUE, arr.get(2)); + assertEquals(Boolean.TRUE, list.get(2)); + + assertEquals(JsonValue.FALSE, arr.get(3)); + assertEquals(Boolean.FALSE, list.get(3)); + + assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(4)); + assertEquals(new BigDecimal(1), list.get(4)); + + assertEquals(new IgniteJsonString("string"), arr.get(5)); + assertEquals("string", list.get(5)); + + assertEquals(json.createArrayBuilder().add(1).add(2).build(), arr.get(6)); + assertEqualsCollections(F.asList(1, 2), (List)list.get(6)); + + assertEquals(json.createArrayBuilder().add(1).add(2).build(), arr.get(7)); + assertEqualsCollections(F.asList(1, 2), (List)list.get(7)); + + JsonObject obj0 = json.createObjectBuilder().add("k1", 1).add("k2", 2).build(); + assertEquals(obj0, arr.get(8)); + assertEquals(((IgniteJsonObject)obj0).binaryObject(), list.get(8)); + + JsonObject obj1 = json.createObjectBuilder().add("k1", 1).add("k2", 2).build(); + assertEquals(obj1, arr.get(9)); + assertEquals(((IgniteJsonObject)obj1).binaryObject(), list.get(9)); + } +} \ No newline at end of file
