You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2015/12/08 10:49:59 UTC
incubator-johnzon git commit: simple value handling
Repository: incubator-johnzon
Updated Branches:
refs/heads/master 55536f3ae -> a2d5d6023
simple value handling
Project: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/commit/a2d5d602
Tree: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/tree/a2d5d602
Diff: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/diff/a2d5d602
Branch: refs/heads/master
Commit: a2d5d6023df38c648c3e06194ae43c593cf8ed4f
Parents: 55536f3
Author: Romain Manni-Bucau <rm...@gmail.com>
Authored: Tue Dec 8 10:50:49 2015 +0100
Committer: Romain Manni-Bucau <rm...@gmail.com>
Committed: Tue Dec 8 10:50:49 2015 +0100
----------------------------------------------------------------------
.../org/apache/johnzon/core/JsonReaderImpl.java | 41 ++++-
.../johnzon/core/JsonStreamParserImpl.java | 16 +-
.../org/apache/johnzon/core/JsonParserTest.java | 42 ++++++
.../apache/johnzon/core/JsonReaderImplTest.java | 32 ++++
.../org/apache/johnzon/jsonb/JohnsonJsonb.java | 149 ++++++++++++++++---
.../johnzon/jsonb/DefaultMappingTest.java | 112 +++++++-------
.../johnzon/mapper/JohnzonReaderHandler.java | 35 +++++
.../java/org/apache/johnzon/mapper/Mapper.java | 45 +++++-
.../apache/johnzon/mapper/ReaderHandler.java | 45 ++++++
.../johnzon/mapper/MapperEnhancedTest.java | 2 +-
.../org/apache/johnzon/mapper/MapperTest.java | 2 +-
11 files changed, 426 insertions(+), 95 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/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 bba027c..d4719b9 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
@@ -20,14 +20,16 @@ package org.apache.johnzon.core;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
+import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonReader;
import javax.json.JsonStructure;
+import javax.json.JsonValue;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParsingException;
-class JsonReaderImpl implements JsonReader {
+public class JsonReaderImpl implements JsonReader {
private final JsonParser parser;
private boolean closed = false;
@@ -37,7 +39,11 @@ class JsonReaderImpl implements JsonReader {
@Override
public JsonStructure read() {
+ return JsonStructure.class.cast(readValue());
+ }
+ //@Override
+ public JsonValue readValue() {
checkClosed();
if (!parser.hasNext()) {
@@ -61,11 +67,42 @@ class JsonReaderImpl implements JsonReader {
}
close();
return arrayBuilder.build();
+ case VALUE_STRING:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file", parser.getLocation());
+ }
+ final JsonStringImpl string = new JsonStringImpl(parser.getString());
+ close();
+ return string;
+ case VALUE_FALSE:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file", parser.getLocation());
+ }
+ close();
+ return JsonValue.FALSE;
+ case VALUE_TRUE:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file", parser.getLocation());
+ }
+ close();
+ return JsonValue.TRUE;
+ case VALUE_NULL:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file", parser.getLocation());
+ }
+ close();
+ return JsonValue.NULL;
+ case VALUE_NUMBER:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file", parser.getLocation());
+ }
+ final JsonNumber number = new JsonNumberImpl(parser.getBigDecimal());
+ close();
+ return number;
default:
close();
throw new JsonParsingException("Unknown structure: " + next, parser.getLocation());
}
-
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
index 89e5752..2f40a21 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
@@ -95,8 +95,8 @@ public class JsonStreamParserImpl implements JsonChars, JsonParser{
//minimal stack implementation
private static final class StructureElement {
- final StructureElement previous;
- final boolean isArray;
+ private final StructureElement previous;
+ private final boolean isArray;
StructureElement(final StructureElement previous, final boolean isArray) {
super();
@@ -174,7 +174,11 @@ public class JsonStreamParserImpl implements JsonChars, JsonParser{
@Override
public final boolean hasNext() {
- if (currentStructureElement != null || (previousEvent != END_ARRAY && previousEvent != END_OBJECT) || previousEvent == 0) {
+ if (currentStructureElement != null ||
+ (previousEvent != END_ARRAY && previousEvent != END_OBJECT &&
+ previousEvent != VALUE_STRING && previousEvent != VALUE_FALSE && previousEvent != VALUE_TRUE && previousEvent != VALUE_NULL && previousEvent != VALUE_NUMBER) ||
+ previousEvent == 0) {
+
return true;
}
@@ -648,7 +652,7 @@ public class JsonStreamParserImpl implements JsonChars, JsonParser{
} else { //Event is START_OBJECT OR START_ARRAY OR COMMA_EVENT
//must be a key if we are in an object, if not its a value
- if (currentStructureElement != null && currentStructureElement.isArray) {
+ if ((currentStructureElement != null && currentStructureElement.isArray) || currentStructureElement == null) {
return EVT_MAP[previousEvent = VALUE_STRING];
}
@@ -728,9 +732,9 @@ public class JsonStreamParserImpl implements JsonChars, JsonParser{
}
- endOfValueInBuffer = bufferPos;
+ endOfValueInBuffer = y == EOF && endOfValueInBuffer < 0 ? -1 : bufferPos;
- if (y == COMMA_CHAR || y == END_ARRAY_CHAR || y == END_OBJECT_CHAR || y == EOL || y == SPACE || y == TAB || y == CR) {
+ if (y == COMMA_CHAR || y == END_ARRAY_CHAR || y == END_OBJECT_CHAR || y == EOL || y == SPACE || y == TAB || y == CR || y == EOF) {
bufferPos--;//unread one char
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
index 0ffbd6d..e035789 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
@@ -1637,20 +1637,26 @@ public class JsonParserTest {
}
}
+ /*
@Test(expected=JsonParsingException.class)
public void rfc7159MustFailForLiteral() {
Json.createReader(new ByteArrayInputStream("null ".getBytes())).read();
}
+ */
+ /*
@Test(expected=JsonParsingException.class)
public void rfc7159MustFailForString() {
Json.createReader(new ByteArrayInputStream("\"hello\"".getBytes())).read();
}
+ */
+ /*
@Test(expected=JsonParsingException.class)
public void rfc7159MustFailForNumber() {
Json.createReader(new ByteArrayInputStream(" 12 ".getBytes())).read();
}
+ */
@Test(expected=JsonParsingException.class)
public void arrayFollowedByGarbage() {
@@ -1806,6 +1812,42 @@ public class JsonParserTest {
}
}
+ @Test
+ public void plainValues() {
+ { // string
+ final JsonParser string = Json.createParser(new StringReader("\"a\""));
+ assertTrue(string.hasNext());
+ assertEquals(Event.VALUE_STRING, string.next());
+ assertEquals("a", string.getString());
+ assertFalse(string.hasNext());
+ }
+ { // true
+ final JsonParser parser = Json.createParser(new StringReader("true"));
+ assertTrue(parser.hasNext());
+ assertEquals(Event.VALUE_TRUE, parser.next());
+ assertFalse(parser.hasNext());
+ }
+ { // false
+ final JsonParser parser = Json.createParser(new StringReader("false"));
+ assertTrue(parser.hasNext());
+ assertEquals(Event.VALUE_FALSE, parser.next());
+ assertFalse(parser.hasNext());
+ }
+ { // null
+ final JsonParser parser = Json.createParser(new StringReader("null"));
+ assertTrue(parser.hasNext());
+ assertEquals(Event.VALUE_NULL, parser.next());
+ assertFalse(parser.hasNext());
+ }
+ { // number
+ final JsonParser parser = Json.createParser(new StringReader("1234"));
+ assertTrue(parser.hasNext());
+ assertEquals(Event.VALUE_NUMBER, parser.next());
+ assertEquals(1234, parser.getInt());
+ assertFalse(parser.hasNext());
+ }
+ }
+
class AttemptingInputStream extends ByteArrayInputStream {
public AttemptingInputStream(byte[] buf) {
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
index 3dc13cc..e9d3d74 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
@@ -35,10 +35,13 @@ import java.util.Map;
import javax.json.Json;
import javax.json.JsonArray;
+import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonReaderFactory;
+import javax.json.JsonString;
import javax.json.JsonStructure;
+import javax.json.JsonValue;
import org.junit.Test;
@@ -526,4 +529,33 @@ public class JsonReaderImplTest {
}
}
}
+
+ @Test
+ public void simpleValues() {
+ { // string
+ final JsonValue value = JsonReaderImpl.class.cast(Json.createReader(new StringReader("\"a string\""))).readValue();
+ assertEquals(JsonValue.ValueType.STRING, value.getValueType());
+ assertEquals("a string", JsonString.class.cast(value).getString());
+ }
+ { // true
+ final JsonValue value = JsonReaderImpl.class.cast(Json.createReader(new StringReader("true"))).readValue();
+ assertEquals(JsonValue.ValueType.TRUE, value.getValueType());
+ assertEquals(JsonValue.TRUE, value);
+ }
+ { // false
+ final JsonValue value = JsonReaderImpl.class.cast(Json.createReader(new StringReader("false"))).readValue();
+ assertEquals(JsonValue.ValueType.FALSE, value.getValueType());
+ assertEquals(JsonValue.FALSE, value);
+ }
+ { // null
+ final JsonValue value = JsonReaderImpl.class.cast(Json.createReader(new StringReader("null"))).readValue();
+ assertEquals(JsonValue.ValueType.NULL, value.getValueType());
+ assertEquals(JsonValue.NULL, value);
+ }
+ { // number
+ final JsonValue value = JsonReaderImpl.class.cast(Json.createReader(new StringReader("1234.5"))).readValue();
+ assertEquals(JsonValue.ValueType.NUMBER, value.getValueType());
+ assertEquals(1234.5, JsonNumber.class.cast(value).doubleValue(), 0.);
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnsonJsonb.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnsonJsonb.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnsonJsonb.java
index ec5e960..7088372 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnsonJsonb.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnsonJsonb.java
@@ -37,7 +37,12 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.CharBuffer;
import java.util.Collection;
+import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
+// TODO: Optional handling for lists (and arrays)?
public class JohnsonJsonb implements Jsonb {
private final Mapper delegate;
@@ -53,12 +58,54 @@ public class JohnsonJsonb implements Jsonb {
} else if (Collection.class.isAssignableFrom(type)) {
return (T) delegate.readCollection(new StringReader(str), new JohnzonParameterizedType(type, Object.class));
}
- return delegate.readObject(str, type);
+ final Type mappingType = unwrapPrimitiveOptional(type);
+ final Object object = delegate.readObject(str, mappingType);
+ if (mappingType != type) {
+ return wrapPrimitiveOptional(object, type);
+ }
+ return (T) object;
} catch (final MapperException me) {
throw new JsonbException(me.getMessage(), me);
}
}
+ private <T> T wrapPrimitiveOptional(final Object object, final Type type) {
+ if (OptionalDouble.class == type) {
+ if (object == null) {
+ return (T) OptionalDouble.empty();
+ }
+ return (T) OptionalDouble.of(Number.class.cast(object).doubleValue());
+ } else if (OptionalInt.class == type) {
+ if (object == null) {
+ return (T) OptionalInt.empty();
+ }
+ return (T) OptionalInt.of(Number.class.cast(object).intValue());
+ } else if (OptionalLong.class == type) {
+ if (object == null) {
+ return (T) OptionalLong.empty();
+ }
+ return (T) OptionalLong.of(Number.class.cast(object).longValue());
+ }
+ // Optional
+ return (T) Optional.ofNullable(object);
+ }
+
+ private Type unwrapPrimitiveOptional(final Type type) {
+ if (OptionalDouble.class == type) {
+ return double.class;
+ } else if (OptionalInt.class == type) {
+ return int.class;
+ } else if (OptionalLong.class == type) {
+ return long.class;
+ } else if (ParameterizedType.class.isInstance(type)) {
+ final ParameterizedType pt = ParameterizedType.class.cast(type);
+ if (Optional.class == pt.getRawType()) {
+ return pt.getActualTypeArguments()[0];
+ }
+ }
+ return type;
+ }
+
@Override
public <T> T fromJson(final String str, final Type runtimeType) throws JsonbException {
try {
@@ -68,7 +115,12 @@ public class JohnsonJsonb implements Jsonb {
} else if (isCollection(runtimeType)) {
return (T) delegate.readCollection(new StringReader(str), ParameterizedType.class.cast(runtimeType));
}
- return delegate.readObject(str, runtimeType);
+ final Type mappingType = unwrapPrimitiveOptional(runtimeType);
+ final Object object = delegate.readObject(str, mappingType);
+ if (mappingType != runtimeType) {
+ return wrapPrimitiveOptional(object, runtimeType);
+ }
+ return (T) object;
} catch (final MapperException me) {
throw new JsonbException(me.getMessage(), me);
}
@@ -82,7 +134,12 @@ public class JohnsonJsonb implements Jsonb {
} else if (Collection.class.isAssignableFrom(type)) {
return (T) delegate.readCollection(toReader(readable), new JohnzonParameterizedType(type, Object.class));
}
- return delegate.readObject(toReader(readable), type);
+ final Type mappingType = unwrapPrimitiveOptional(type);
+ final Object object = delegate.readObject(toReader(readable), mappingType);
+ if (mappingType != type) {
+ return wrapPrimitiveOptional(object, type);
+ }
+ return (T) object;
} catch (final MapperException me) {
throw new JsonbException(me.getMessage(), me);
}
@@ -90,13 +147,22 @@ public class JohnsonJsonb implements Jsonb {
@Override
public <T> T fromJson(final Readable readable, final Type runtimeType) throws JsonbException {
- if (isArray(runtimeType)) {
- final Class<T> type = Class.class.cast(runtimeType);
- return delegate.readTypedArray(toReader(readable), type.getComponentType(), type);
- } else if (isCollection(runtimeType)) {
- return (T) delegate.readCollection(toReader(readable), ParameterizedType.class.cast(runtimeType));
+ try {
+ if (isArray(runtimeType)) {
+ final Class<T> type = Class.class.cast(runtimeType);
+ return delegate.readTypedArray(toReader(readable), type.getComponentType(), type);
+ } else if (isCollection(runtimeType)) {
+ return (T) delegate.readCollection(toReader(readable), ParameterizedType.class.cast(runtimeType));
+ }
+ final Type mappingType = unwrapPrimitiveOptional(runtimeType);
+ final Object object = delegate.readObject(toReader(readable), mappingType);
+ if (mappingType != runtimeType) {
+ return wrapPrimitiveOptional(object, runtimeType);
+ }
+ return (T) object;
+ } catch (final MapperException me) {
+ throw new JsonbException(me.getMessage(), me);
}
- return delegate.readObject(toReader(readable), runtimeType);
}
@Override
@@ -107,7 +173,12 @@ public class JohnsonJsonb implements Jsonb {
} else if (Collection.class.isAssignableFrom(type)) {
return (T) delegate.readCollection(stream, new JohnzonParameterizedType(type, Object.class));
}
- return delegate.readObject(stream, type);
+ final Type mappingType = unwrapPrimitiveOptional(type);
+ final Object object = delegate.readObject(stream, mappingType);
+ if (mappingType != type) {
+ return wrapPrimitiveOptional(object, type);
+ }
+ return (T) object;
} catch (final MapperException me) {
throw new JsonbException(me.getMessage(), me);
}
@@ -122,15 +193,25 @@ public class JohnsonJsonb implements Jsonb {
} else if (isCollection(runtimeType)) {
return (T) delegate.readCollection(stream, ParameterizedType.class.cast(runtimeType));
}
- return delegate.readObject(stream, runtimeType);
+
+ final Type mappingType = unwrapPrimitiveOptional(runtimeType);
+ final Object object = delegate.readObject(stream, mappingType);
+ if (mappingType != runtimeType) {
+ return wrapPrimitiveOptional(object, runtimeType);
+ }
+ return (T) object;
} catch (final MapperException me) {
throw new JsonbException(me.getMessage(), me);
}
}
@Override
- public String toJson(final Object object) throws JsonbException {
+ public String toJson(final Object inObject) throws JsonbException {
try {
+ final Object object = unwrapOptional(inObject);
+ if (object == null) {
+ return "null";
+ }
if (isArray(object.getClass())) {
return delegate.writeArrayAsString(toArray(object));
} else if (Collection.class.isInstance(object)) {
@@ -195,8 +276,9 @@ public class JohnsonJsonb implements Jsonb {
}
@Override
- public String toJson(final Object object, final Type runtimeType) throws JsonbException {
- if (isArray(runtimeType)) {
+ public String toJson(final Object inObject, final Type runtimeType) throws JsonbException {
+ final Object object = unwrapOptional(inObject);
+ if (object != null && isArray(runtimeType)) {
return delegate.writeArrayAsString((Object[]) object);
} else if (isCollection(runtimeType)) {
return delegate.writeArrayAsString(Collection.class.cast(object));
@@ -205,8 +287,9 @@ public class JohnsonJsonb implements Jsonb {
}
@Override
- public void toJson(final Object object, final Appendable appendable) throws JsonbException {
- if (isArray(object.getClass())) {
+ public void toJson(final Object inObject, final Appendable appendable) throws JsonbException {
+ final Object object = unwrapOptional(inObject);
+ if (object != null && isArray(object.getClass())) {
delegate.writeArray((Object[]) object, toWriter(appendable));
} else if (Collection.class.isInstance(object)) {
delegate.writeArray(Collection.class.cast(object), toWriter(appendable));
@@ -216,8 +299,9 @@ public class JohnsonJsonb implements Jsonb {
}
@Override
- public void toJson(final Object object, final Type runtimeType, final Appendable appendable) throws JsonbException {
- if (isArray(runtimeType)) {
+ public void toJson(final Object inObject, final Type runtimeType, final Appendable appendable) throws JsonbException {
+ final Object object = unwrapOptional(inObject);
+ if (object != null && isArray(runtimeType)) {
delegate.writeArray((Object[]) object, toWriter(appendable));
} else if (isCollection(runtimeType)) {
delegate.writeArray(Collection.class.cast(object), toWriter(appendable));
@@ -227,8 +311,9 @@ public class JohnsonJsonb implements Jsonb {
}
@Override
- public void toJson(final Object object, final OutputStream stream) throws JsonbException {
- if (isArray(object.getClass())) {
+ public void toJson(final Object inObject, final OutputStream stream) throws JsonbException {
+ final Object object = unwrapOptional(inObject);
+ if (object != null && isArray(object.getClass())) {
delegate.writeArray((Object[]) object, stream);
} else if (Collection.class.isInstance(object)) {
delegate.writeArray(Collection.class.cast(object), stream);
@@ -238,8 +323,9 @@ public class JohnsonJsonb implements Jsonb {
}
@Override
- public void toJson(final Object object, final Type runtimeType, final OutputStream stream) throws JsonbException {
- if (isArray(runtimeType)) {
+ public void toJson(final Object inObject, final Type runtimeType, final OutputStream stream) throws JsonbException {
+ final Object object = unwrapOptional(inObject);
+ if (object != null && isArray(runtimeType)) {
delegate.writeArray((Object[]) object, stream);
} else if (isCollection(runtimeType)) {
delegate.writeArray(Collection.class.cast(object), stream);
@@ -248,6 +334,25 @@ public class JohnsonJsonb implements Jsonb {
}
}
+ private Object unwrapOptional(final Object inObject) {
+ if (Optional.class.isInstance(inObject)) {
+ return Optional.class.cast(inObject).orElse(null);
+ }
+ if (OptionalInt.class.isInstance(inObject)) {
+ final OptionalInt optionalInt = OptionalInt.class.cast(inObject);
+ return optionalInt.isPresent() ? optionalInt.getAsInt() : null;
+ }
+ if (OptionalLong.class.isInstance(inObject)) {
+ final OptionalLong optionalLong = OptionalLong.class.cast(inObject);
+ return optionalLong.isPresent() ? optionalLong.getAsLong() : null;
+ }
+ if (OptionalDouble.class.isInstance(inObject)) {
+ final OptionalDouble optionalDouble = OptionalDouble.class.cast(inObject);
+ return optionalDouble.isPresent() ? optionalDouble.getAsDouble() : null;
+ }
+ return inObject;
+ }
+
private boolean isArray(final Type runtimeType) {
return Class.class.isInstance(runtimeType) && Class.class.cast(runtimeType).isArray();
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java
index 518f8c8..5c99371 100644
--- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java
@@ -18,6 +18,7 @@
*/
package org.apache.johnzon.jsonb;
+import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
import org.junit.Ignore;
import org.junit.Test;
@@ -46,6 +47,9 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -144,6 +148,55 @@ public class DefaultMappingTest {
fromJsonAccessors();
}
+ @Test
+ public void simpleValues() {
+ assertEquals("\"strValue\"", JSONB.toJson("\"strValue\""));
+ assertEquals("true", JSONB.toJson("true"));
+ assertEquals("false", JSONB.toJson("false"));
+ assertEquals("null", JSONB.toJson("null"));
+ assertEquals("strValue", JSONB.toJson(Optional.of("strValue")));
+ assertEquals("null", JSONB.toJson(Optional.ofNullable(null)));
+ assertEquals("null", JSONB.toJson(Optional.empty()));
+ assertEquals("1", JSONB.toJson(OptionalInt.of(1)));
+ assertEquals("null", JSONB.toJson(OptionalInt.empty()));
+ assertEquals("123", JSONB.toJson(OptionalLong.of(123)));
+ assertEquals("null", JSONB.toJson(OptionalLong.empty()));
+ assertEquals("1.2", JSONB.toJson(OptionalDouble.of(1.2)));
+ assertEquals("null", JSONB.toJson(OptionalDouble.empty()));
+
+ //Optional
+ Optional<String> stringValue = JSONB.fromJson("\"optionalString\"", new JohnzonParameterizedType(Optional.class, String.class));
+ assertTrue(stringValue.isPresent());
+ assertEquals("optionalString", stringValue.get());
+
+ Optional<String> nullStringValue = JSONB.fromJson("null", new JohnzonParameterizedType(Optional.class, String.class));
+ assertTrue(!nullStringValue.isPresent());
+
+ //OptionalInt
+ OptionalInt optionalInt = JSONB.fromJson("1", OptionalInt.class);
+ assertTrue(optionalInt.isPresent());
+ assertTrue(optionalInt.getAsInt() == 1);
+
+ OptionalInt emptyOptionalInt = JSONB.fromJson("null", OptionalInt.class);
+ assertTrue(!emptyOptionalInt.isPresent());
+
+ //OptionalLong
+ OptionalLong optionalLong = JSONB.fromJson("123", OptionalLong.class);
+ assertTrue(optionalLong.isPresent());
+ assertTrue(optionalLong.getAsLong() == 123L);
+
+ OptionalLong emptyOptionalLong = JSONB.fromJson("null", OptionalLong.class);
+ assertTrue(!emptyOptionalLong.isPresent());
+
+ //OptionalDouble
+ OptionalDouble optionalDouble = JSONB.fromJson("1.2", OptionalDouble.class);
+ assertTrue(optionalDouble.isPresent());
+ assertTrue(optionalDouble.getAsDouble() == 1.2);
+
+ OptionalDouble emptyOptionalDouble = JSONB.fromJson("null", OptionalDouble.class);
+ assertTrue(!emptyOptionalDouble.isPresent());
+ }
+
public static void fromJsonPrimitives() {
//String
String str = JSONB.fromJson("\"some_string\"", String.class);
@@ -308,7 +361,7 @@ public class DefaultMappingTest {
assertNotNull(JSONB.fromJson("[{\"value\":\"first\"},{\"value\":\"second\"}]", JsonArray.class));
//JsonValue
- // TBD assertNotNull(JSONB.fromJson("1", JsonValue.class));
+ assertNotNull(JSONB.fromJson("1", JsonValue.class));
}
public static void toJsonStructures() {
@@ -1079,29 +1132,6 @@ public class DefaultMappingTest {
}
public static void toJsonOptional() {
-
- //Optional
- /* TBD: direct mapping
- assertEquals("\"strValue\"", JSONB.toJson(Optional.of("strValue")));
-
-
- assertEquals("null", JSONB.toJson(Optional.ofNullable(null)));
-
- assertEquals("null", JSONB.toJson(Optional.empty()));
-
- //OptionalInt
- assertEquals("1", JSONB.toJson(OptionalInt.of(1)));
- assertEquals("null", JSONB.toJson(OptionalInt.empty()));
-
- //OptionalLong
- assertEquals("123", JSONB.toJson(OptionalLong.of(123)));
- assertEquals("null", JSONB.toJson(OptionalLong.empty()));
-
- //OptionalDouble
- assertEquals("1.2", JSONB.toJson(OptionalDouble.of(1.2)));
- assertEquals("null", JSONB.toJson(OptionalDouble.empty()));
- */
-
final OptionalClass object = new OptionalClass();
object.optionalField = Optional.of("test");
assertEquals("{\"optionalField\":\"test\"}", JSONB.toJson(object));
@@ -1118,40 +1148,6 @@ public class DefaultMappingTest {
}
public static void fromJsonOptional() {
- /* TBD
- //Optional
- Optional<String> stringValue = JSONB.fromJson("\"optionalString\"", Optional.class);
- assertTrue(stringValue.isPresent());
- assertEquals("optionalString", stringValue.get());
-
- Optional<String> nullStringValue = JSONB.fromJson("null", Optional.class);
- assertTrue(!nullStringValue.isPresent());
-
- //OptionalInt
- OptionalInt optionalInt = JSONB.fromJson("1", OptionalInt.class);
- assertTrue(optionalInt.isPresent());
- assertTrue(optionalInt.getAsInt() == 1);
-
- OptionalInt emptyOptionalInt = JSONB.fromJson("null", OptionalInt.class);
- assertTrue(!emptyOptionalInt.isPresent());
-
- //OptionalLong
- OptionalLong optionalLong = JSONB.fromJson("123", OptionalLong.class);
- assertTrue(optionalLong.isPresent());
- assertTrue(optionalLong.getAsLong() == 123L);
-
- OptionalLong emptyOptionalLong = JSONB.fromJson("null", OptionalLong.class);
- assertTrue(!emptyOptionalLong.isPresent());
-
- //OptionalDouble
- OptionalDouble optionalDouble = JSONB.fromJson("1.2", OptionalDouble.class);
- assertTrue(optionalDouble.isPresent());
- assertTrue(optionalDouble.getAsDouble() == 1.2);
-
- OptionalDouble emptyOptionalDouble = JSONB.fromJson("null", OptionalDouble.class);
- assertTrue(!emptyOptionalDouble.isPresent());
- */
-
OptionalClass optionalClass = JSONB.fromJson("{\"optionalField\":\"value\"}", OptionalClass.class);
assertTrue(optionalClass.optionalField.isPresent());
assertEquals("value", optionalClass.optionalField.get());
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/JohnzonReaderHandler.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/JohnzonReaderHandler.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/JohnzonReaderHandler.java
new file mode 100644
index 0000000..3aeec4d
--- /dev/null
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/JohnzonReaderHandler.java
@@ -0,0 +1,35 @@
+/*
+ * 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.mapper;
+
+import org.apache.johnzon.core.JsonReaderImpl;
+
+import javax.json.JsonReader;
+import javax.json.JsonValue;
+
+// just for classloading
+public class JohnzonReaderHandler {
+ private JohnzonReaderHandler() {
+ // no-op
+ }
+
+ public static JsonValue read(final JsonReader reader) {
+ return JsonReaderImpl.class.cast(reader).readValue();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
index ac3e6b3..ea83813 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
@@ -95,6 +95,7 @@ public class Mapper {
protected final boolean treatByteArrayAsBase64;
protected final boolean treatByteArrayAsBase64URL;
protected final Charset encoding;
+ protected final ReaderHandler readerHandler;
// CHECKSTYLE:OFF
public Mapper(final JsonReaderFactory readerFactory, final JsonGeneratorFactory generatorFactory,
@@ -113,6 +114,7 @@ public class Mapper {
this.treatByteArrayAsBase64 = treatByteArrayAsBase64;
this.treatByteArrayAsBase64URL = treatByteArrayAsBase64URL;
this.encoding = encoding;
+ this.readerHandler = ReaderHandler.create(readerFactory);
}
private static JsonGenerator writePrimitives(final JsonGenerator generator, final Object value) {
@@ -294,9 +296,9 @@ public class Mapper {
}
public void writeObject(final Object object, final Writer stream) {
- if (JsonValue.class.isInstance(object)) {
+ if (JsonValue.class.isInstance(object) || String.class.isInstance(object) || Number.class.isInstance(object) || object == null) {
try {
- stream.write(object.toString());
+ stream.write(String.valueOf(object));
} catch (final IOException e) {
throw new MapperException(e);
} finally {
@@ -555,11 +557,44 @@ public class Mapper {
private <T> T mapObject(final Type clazz, final JsonReader reader) {
try {
- final JsonObject object = reader.readObject();
- if (JsonStructure.class == clazz || JsonObject.class == clazz) {
+ final JsonValue object = readerHandler.read(reader);
+ if (JsonStructure.class == clazz || JsonObject.class == clazz || JsonValue.class == clazz) {
return (T) object;
}
- return (T) buildObject(clazz, object);
+ if (JsonObject.class.isInstance(object)) {
+ return (T) buildObject(clazz, JsonObject.class.cast(object));
+ }
+ if (JsonString.class.isInstance(object) && clazz == String.class) {
+ return (T) JsonString.class.cast(object).getString();
+ }
+ if (JsonNumber.class.isInstance(object)) {
+ final JsonNumber number = JsonNumber.class.cast(object);
+ if (clazz == int.class || clazz == Integer.class) {
+ return (T) Integer.valueOf(number.intValue());
+ }
+ if (clazz == long.class || clazz == Long.class) {
+ return (T) Long.valueOf(number.longValue());
+ }
+ if (clazz == double.class || clazz == Double.class) {
+ return (T) Double.valueOf(number.doubleValue());
+ }
+ if (clazz == BigDecimal.class) {
+ return (T) number.bigDecimalValue();
+ }
+ if (clazz == BigInteger.class) {
+ return (T) number.bigIntegerValue();
+ }
+ }
+ if (JsonValue.NULL == object) {
+ return null;
+ }
+ if (JsonValue.TRUE == object && (Boolean.class == clazz || boolean.class == clazz)) {
+ return (T) Boolean.TRUE;
+ }
+ if (JsonValue.FALSE == object && (Boolean.class == clazz || boolean.class == clazz)) {
+ return (T) Boolean.FALSE;
+ }
+ throw new IllegalArgumentException("Unsupported " + object + " for type " + clazz);
} catch (final Exception e) {
throw new MapperException(e);
} finally {
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ReaderHandler.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ReaderHandler.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ReaderHandler.java
new file mode 100644
index 0000000..42e272e
--- /dev/null
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ReaderHandler.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.mapper;
+
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonValue;
+
+public class ReaderHandler {
+ private final boolean johnzon;
+
+ private ReaderHandler(final boolean johnzon) {
+ this.johnzon = johnzon;
+ }
+
+ public static ReaderHandler create(final JsonReaderFactory readerFactory) {
+ if (readerFactory.getClass().getName().equals("org.apache.johnzon.core.JsonReaderFactoryImpl")) {
+ return new ReaderHandler(true);
+ }
+ return new ReaderHandler(false);
+ }
+
+ public JsonValue read(final JsonReader reader) {
+ if (johnzon) {
+ return JohnzonReaderHandler.read(reader);
+ }
+ return reader.read();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperEnhancedTest.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperEnhancedTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperEnhancedTest.java
index 30bbee5..8073136 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperEnhancedTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperEnhancedTest.java
@@ -46,7 +46,7 @@ public class MapperEnhancedTest {
public void writeNull() {
final StringWriter sw = new StringWriter();
new MapperBuilder().build().writeObject(null, sw);
- assertEquals("{}", sw.toString());
+ assertEquals("null", sw.toString());
}
@Test
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/a2d5d602/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
index d992725..b5c70a7 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
@@ -59,7 +59,7 @@ public class MapperTest {
public void writeEmptyObject() {
final StringWriter writer = new StringWriter();
new MapperBuilder().build().writeObject(null, writer);
- assertEquals("{}", writer.toString());
+ assertEquals("null", writer.toString());
}
@Test