Repository: johnzon Updated Branches: refs/heads/master 60525af05 -> b0af96e6d
JOHNZON-94 ignoring null and true/false serialization to ensure == works for these values Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/b0af96e6 Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/b0af96e6 Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/b0af96e6 Branch: refs/heads/master Commit: b0af96e6d819adf7a28782ebc535894bd27345da Parents: 60525af Author: Romain manni-Bucau <[email protected]> Authored: Fri Aug 26 18:22:22 2016 +0200 Committer: Romain manni-Bucau <[email protected]> Committed: Fri Aug 26 18:22:22 2016 +0200 ---------------------------------------------------------------------- .../johnzon/core/JsonArrayBuilderImpl.java | 2 +- .../org/apache/johnzon/core/JsonArrayImpl.java | 11 ++- .../johnzon/core/JsonObjectBuilderImpl.java | 13 ++- .../org/apache/johnzon/core/JsonObjectImpl.java | 9 +- .../org/apache/johnzon/core/JsonReaderImpl.java | 6 +- .../johnzon/core/SerializablePrimitives.java | 97 -------------------- .../apache/johnzon/core/SerializableValue.java | 56 +++++++++++ .../apache/johnzon/core/SerializationTest.java | 24 +++-- 8 files changed, 92 insertions(+), 126 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java index ea46072..913c22a 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java @@ -76,7 +76,7 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable { @Override public JsonArrayBuilder add(final boolean value) { - addValue(value ? SerializablePrimitives.TRUE : SerializablePrimitives.FALSE); + addValue(value ? JsonValue.TRUE : JsonValue.FALSE); return this; } http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java index 6906645..cfb563d 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java @@ -23,6 +23,7 @@ import javax.json.JsonNumber; import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; +import java.io.ObjectStreamException; import java.io.Serializable; import java.util.AbstractList; import java.util.Iterator; @@ -118,9 +119,9 @@ class JsonArrayImpl extends AbstractList<JsonValue> implements JsonArray, Serial public boolean getBoolean(final int index) { final JsonValue val = value(index, JsonValue.class); - if (SerializablePrimitives.TRUE.equals(val)) { + if (JsonValue.TRUE.equals(val)) { return true; - } else if (SerializablePrimitives.FALSE.equals(val)) { + } else if (JsonValue.FALSE.equals(val)) { return false; } else { throw new ClassCastException(); @@ -143,7 +144,7 @@ class JsonArrayImpl extends AbstractList<JsonValue> implements JsonArray, Serial } final JsonValue val = get(index); - return SerializablePrimitives.TRUE.equals(val) || !SerializablePrimitives.FALSE.equals(val) && defaultValue; + return JsonValue.TRUE.equals(val) || !JsonValue.FALSE.equals(val) && defaultValue; } @Override @@ -201,4 +202,8 @@ class JsonArrayImpl extends AbstractList<JsonValue> implements JsonArray, Serial public int size() { return unmodifieableBackingList.size(); } + + private Object writeReplace() throws ObjectStreamException { + return new SerializableValue(toString()); + } } http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java index 2a260f3..d625383 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java @@ -18,6 +18,10 @@ */ package org.apache.johnzon.core; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; +import javax.json.JsonValue; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; @@ -25,11 +29,6 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import javax.json.JsonArrayBuilder; -import javax.json.JsonObject; -import javax.json.JsonObjectBuilder; -import javax.json.JsonValue; - class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable { private Map<String, JsonValue> tmpMap; @@ -77,13 +76,13 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable { @Override public JsonObjectBuilder add(final String name, final boolean value) { - putValue(name, value ? SerializablePrimitives.TRUE : SerializablePrimitives.FALSE); + putValue(name, value ? JsonValue.TRUE : JsonValue.FALSE); return this; } @Override public JsonObjectBuilder addNull(final String name) { - putValue(name, SerializablePrimitives.NULL); + putValue(name, JsonValue.NULL); return this; } http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java index ef8b84d..98c38da 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java @@ -23,6 +23,7 @@ import javax.json.JsonNumber; import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; +import java.io.ObjectStreamException; import java.io.Serializable; import java.util.AbstractMap; import java.util.Iterator; @@ -108,14 +109,14 @@ final class JsonObjectImpl extends AbstractMap<String, JsonValue> implements Jso @Override public boolean getBoolean(final String name) { - return SerializablePrimitives.TRUE.equals(value(name, JsonValue.class)); + return JsonValue.TRUE.equals(value(name, JsonValue.class)); } @Override public boolean getBoolean(final String name, final boolean defaultValue) { final Object v = unmodifieableBackingMap.get(name); if (v != null) { - return SerializablePrimitives.TRUE.equals(v) || !SerializablePrimitives.FALSE.equals(v) && defaultValue; + return JsonValue.TRUE.equals(v) || !JsonValue.FALSE.equals(v) && defaultValue; } else { return defaultValue; } @@ -176,4 +177,8 @@ final class JsonObjectImpl extends AbstractMap<String, JsonValue> implements Jso public Set<java.util.Map.Entry<String, JsonValue>> entrySet() { return unmodifieableBackingMap.entrySet(); } + + private Object writeReplace() throws ObjectStreamException { + return new SerializableValue(toString()); + } } http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java index 2632c9a..b0107ee 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java @@ -79,19 +79,19 @@ public class JsonReaderImpl implements JsonReader { throw new JsonParsingException("Expected end of file", parser.getLocation()); } close(); - return SerializablePrimitives.FALSE; + return JsonValue.FALSE; case VALUE_TRUE: if (parser.hasNext()) { throw new JsonParsingException("Expected end of file", parser.getLocation()); } close(); - return SerializablePrimitives.TRUE; + return JsonValue.TRUE; case VALUE_NULL: if (parser.hasNext()) { throw new JsonParsingException("Expected end of file", parser.getLocation()); } close(); - return SerializablePrimitives.NULL; + return JsonValue.NULL; case VALUE_NUMBER: if (parser.hasNext()) { throw new JsonParsingException("Expected end of file", parser.getLocation()); http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/main/java/org/apache/johnzon/core/SerializablePrimitives.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/SerializablePrimitives.java b/johnzon-core/src/main/java/org/apache/johnzon/core/SerializablePrimitives.java deleted file mode 100644 index c046f85..0000000 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/SerializablePrimitives.java +++ /dev/null @@ -1,97 +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.johnzon.core; - -import javax.json.JsonValue; -import java.io.InvalidObjectException; -import java.io.ObjectStreamException; -import java.io.Serializable; - -public final class SerializablePrimitives { - private SerializablePrimitives() { - // no-op - } - - public static final JsonValue NULL = new SerializableJsonValue(JsonValue.NULL); - public static final JsonValue TRUE = new SerializableJsonValue(JsonValue.TRUE); - public static final JsonValue FALSE = new SerializableJsonValue(JsonValue.FALSE); - - private static final class SerializableJsonValue implements JsonValue, Serializable { - private final JsonValue delegate; - - SerializableJsonValue(final JsonValue value) { - delegate = value; - } - - @Override - public ValueType getValueType() { - return delegate.getValueType(); - } - - @Override - public String toString() { - return delegate.toString(); - } - - @Override - public boolean equals(final Object o) { - if (this == o || o == delegate) { - return true; - } - if (o == null) { - return false; - } - if (SerializableJsonValue.class.isInstance(o)) { - return SerializableJsonValue.class.cast(o).delegate.equals(delegate); - } - return JsonValue.class.isInstance(o) && o.equals(delegate); - - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - private Object writeReplace() throws ObjectStreamException { - return new SerializationReplacement(delegate.toString()); - } - } - - private static final class SerializationReplacement implements Serializable { - private final String value; - - private SerializationReplacement(final String value) { - this.value = value; - } - - private Object readResolve() throws ObjectStreamException { - if ("null".equals(value)) { - return NULL; - } - if ("true".equals(value)) { - return TRUE; - } - if ("false".equals(value)) { - return FALSE; - } - throw new InvalidObjectException("Unknown " + value); - } - } -} http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/main/java/org/apache/johnzon/core/SerializableValue.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/SerializableValue.java b/johnzon-core/src/main/java/org/apache/johnzon/core/SerializableValue.java new file mode 100644 index 0000000..76b3ec6 --- /dev/null +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/SerializableValue.java @@ -0,0 +1,56 @@ +/* + * 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.johnzon.core; + +import javax.json.JsonReader; +import javax.json.JsonReaderFactory; +import javax.json.spi.JsonProvider; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.io.StringReader; +import java.util.Collections; +import java.util.concurrent.atomic.AtomicReference; + +public class SerializableValue implements Serializable { + private static final AtomicReference<JsonReaderFactory> FACTORY_ATOMIC_REFERENCE = new AtomicReference<JsonReaderFactory>(); + + private final String value; + + SerializableValue(final String value) { + this.value = value; + } + + private Object readResolve() throws ObjectStreamException { + final JsonReader parser = factory().createReader(new StringReader(value)); + try { + return parser.read(); + } finally { + parser.close(); + } + } + + private static JsonReaderFactory factory() { // avoid to create too much instances of provider or factories, not needed + JsonReaderFactory factory = FACTORY_ATOMIC_REFERENCE.get(); + if (factory == null) { + FACTORY_ATOMIC_REFERENCE.compareAndSet(null, JsonProvider.provider().createReaderFactory(Collections.<String, Object>emptyMap())); + factory = FACTORY_ATOMIC_REFERENCE.get(); + } + return factory; + } +} http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0af96e6/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java index b80aae7..383dae9 100644 --- a/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java +++ b/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java @@ -31,11 +31,11 @@ import java.io.ObjectOutputStream; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; @@ -81,38 +81,36 @@ public class SerializationTest { public void jsonObject() throws IOException, ClassNotFoundException { final Map<String, JsonValue> map = new LinkedHashMap<String, JsonValue>(); map.put("test", new JsonStringImpl("val")); + map.put("test2", JsonValue.TRUE); final JsonObject source = new JsonObjectImpl(Collections.unmodifiableMap(map)); final JsonObject serialization = serialDeser(source); assertNotSame(source, serialization); assertTrue(serialization.containsKey("test")); assertEquals("val", serialization.getString("test")); - assertEquals(1, serialization.size()); + assertEquals(true, serialization.getBoolean("test2")); + assertEquals(2, serialization.size()); } @Test public void jsonArray() throws IOException, ClassNotFoundException { final List<JsonValue> list = new ArrayList<JsonValue>(); list.add(new JsonStringImpl("test")); + list.add(JsonValue.TRUE); // not ser but we should be able to handle that final JsonArray source = new JsonArrayImpl(Collections.unmodifiableList(list)); final JsonArray serialization = serialDeser(source); assertNotSame(source, serialization); - assertEquals(1, serialization.size()); - assertEquals("test", JsonString.class.cast(serialization.iterator().next()).getString()); - } - - @Test - public void jsonPrimitives() throws IOException, ClassNotFoundException { // NOTE: spec jar primitives are not serializable - for (final JsonValue v : asList(SerializablePrimitives.FALSE, SerializablePrimitives.TRUE, SerializablePrimitives.NULL)) { - assertEquals(v, serialDeser(v)); - } + assertEquals(2, serialization.size()); + final Iterator<JsonValue> iterator = serialization.iterator(); + assertEquals("test", JsonString.class.cast(iterator.next()).getString()); + assertEquals(JsonValue.TRUE, iterator.next()); } @Test public void primitiveInObject() throws IOException, ClassNotFoundException { assertTrue(serialDeser(JsonProviderImpl.provider().createObjectBuilder() .add("bool", true) - .build() - .getBoolean("bool"))); + .build()) + .getBoolean("bool")); } private static <T> T serialDeser(final T instance) throws IOException, ClassNotFoundException {
