This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git
The following commit(s) were added to refs/heads/master by this push:
new 25fd020 use jsonp as base for jsonb and not johnzon internals
25fd020 is described below
commit 25fd0201c2bd7b10c0278ceccf7b623141bed224
Author: Romain Manni-Bucau <[email protected]>
AuthorDate: Wed Jun 26 17:37:04 2019 +0200
use jsonp as base for jsonb and not johnzon internals
---
.../org/apache/johnzon/jsonb/JohnzonBuilder.java | 54 ++++--
.../org/apache/johnzon/jsonb/JsonbAccessMode.java | 32 ++--
.../serializer/JohnzonDeserializationContext.java | 185 ++++++++++++++++++++-
3 files changed, 230 insertions(+), 41 deletions(-)
diff --git
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index 4e0b0b5..7cc2a91 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -68,6 +68,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.stream.Stream;
+import javax.json.JsonBuilderFactory;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
@@ -130,7 +131,10 @@ public class JohnzonBuilder implements JsonbBuilder {
if (jsonp != null) {
builder.setGeneratorFactory(jsonp.createGeneratorFactory(generatorConfig()));
builder.setReaderFactory(jsonp.createReaderFactory(readerConfig()));
+ } else {
+ jsonp = JsonProvider.provider();
}
+ final Supplier<JsonBuilderFactory> builderFactorySupplier =
createJsonBuilderFactory();
final Supplier<JsonParserFactory> parserFactoryProvider =
createJsonParserFactory();
if (config == null) {
@@ -198,14 +202,13 @@ public class JohnzonBuilder implements JsonbBuilder {
propertyNamingStrategy, orderValue, visibilityStrategy,
!namingStrategyValue.orElse("").equals(PropertyNamingStrategy.CASE_INSENSITIVE),
defaultConverters,
- factory, parserFactoryProvider,
+ factory, jsonp, builderFactorySupplier,
parserFactoryProvider,
config.getProperty("johnzon.accessModeDelegate")
.map(this::toAccessMode)
.orElseGet(() -> new
FieldAndMethodAccessMode(true, true, false)),
config.getProperty("johnzon.failOnMissingCreatorValues")
.map(it -> String.class.isInstance(it) ?
Boolean.parseBoolean(it.toString()) : Boolean.class.cast(it))
- .orElse(true) /*spec 1.0 requirement*/,
- bufferProvider));
+ .orElse(true) /*spec 1.0 requirement*/));
builder.setAccessMode(accessMode);
// user adapters
@@ -301,11 +304,12 @@ public class JohnzonBuilder implements JsonbBuilder {
throw new IllegalArgumentException("We only support
deserializer on Class for now");
}
// TODO: support PT in ObjectConverter (list)
+ final JsonBuilderFactory builderFactory =
builderFactorySupplier.get();
builder.addObjectConverter(
Class.class.cast(args[0]), (ObjectConverter.Reader)
(jsonObject, targetType, parser) ->
d.deserialize(
JsonValueParserAdapter.createFor(jsonObject, parserFactoryProvider),
- new
JohnzonDeserializationContext(parser, bufferProvider), targetType));
+ new
JohnzonDeserializationContext(parser, builderFactory, jsonp), targetType));
});
});
@@ -349,23 +353,19 @@ public class JohnzonBuilder implements JsonbBuilder {
}
private Supplier<JsonParserFactory> createJsonParserFactory() {
- return new Supplier<JsonParserFactory>() { // thread safety is not
mandatory
- private final AtomicReference<JsonParserFactory> ref = new
AtomicReference<>();
-
+ return new Lazy<JsonParserFactory>() { // thread safety is not
mandatory
@Override
- public JsonParserFactory get() {
- JsonParserFactory factory = ref.get();
- if (factory == null) {
- factory = doCreate();
- if (!ref.compareAndSet(null, factory)) {
- factory = ref.get();
- }
- }
- return factory;
+ protected JsonParserFactory doCreate() {
+ return jsonp.createParserFactory(emptyMap());
}
+ };
+ }
- private JsonParserFactory doCreate() {
- return (jsonp == null ? JsonProvider.provider() :
jsonp).createParserFactory(emptyMap());
+ private Supplier<JsonBuilderFactory> createJsonBuilderFactory() {
+ return new Lazy<JsonBuilderFactory>() { // thread safety is not
mandatory
+ @Override
+ protected JsonBuilderFactory doCreate() {
+ return jsonp.createBuilderFactory(emptyMap());
}
};
}
@@ -775,4 +775,22 @@ public class JohnzonBuilder implements JsonbBuilder {
config.getProperty(AbstractJsonFactory.BUFFER_STRATEGY).ifPresent(b ->
map.put(AbstractJsonFactory.BUFFER_STRATEGY, b));
return map;
}
+
+ private static abstract class Lazy<T> implements Supplier<T> {
+ private final AtomicReference<T> ref = new AtomicReference<>();
+
+ @Override
+ public T get() {
+ T factory = ref.get();
+ if (factory == null) {
+ factory = doCreate();
+ if (!ref.compareAndSet(null, factory)) {
+ factory = ref.get();
+ }
+ }
+ return factory;
+ }
+
+ protected abstract T doCreate();
+ }
}
diff --git
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
index e515818..bf34b52 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
@@ -61,6 +61,7 @@ import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Stream;
+import javax.json.JsonBuilderFactory;
import javax.json.JsonValue;
import javax.json.bind.JsonbException;
import javax.json.bind.adapter.JsonbAdapter;
@@ -79,9 +80,9 @@ import javax.json.bind.config.PropertyOrderStrategy;
import javax.json.bind.config.PropertyVisibilityStrategy;
import javax.json.bind.serializer.JsonbDeserializer;
import javax.json.bind.serializer.JsonbSerializer;
+import javax.json.spi.JsonProvider;
import javax.json.stream.JsonParserFactory;
-import org.apache.johnzon.core.BufferStrategy;
import org.apache.johnzon.core.Types;
import org.apache.johnzon.jsonb.converter.JohnzonJsonbAdapter;
import org.apache.johnzon.jsonb.converter.JsonbDateConverter;
@@ -120,7 +121,9 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
private final Map<AdapterKey, Adapter<?, ?>> defaultConverters;
private final JohnzonAdapterFactory factory;
private final Collection<JohnzonAdapterFactory.Instance<?>> toRelease =
new ArrayList<>();
+ private final JsonProvider jsonProvider;
private final Supplier<JsonParserFactory> parserFactory;
+ private final Supplier<JsonBuilderFactory> builderFactory;
private final ConcurrentMap<Class<?>, ParsingCacheEntry> parsingCache =
new ConcurrentHashMap<>();
private final BaseAccessMode partialDelegate = new BaseAccessMode(false,
false) {
@Override
@@ -133,16 +136,16 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
throw new UnsupportedOperationException();
}
};
- private final BufferStrategy.BufferProvider<char[]> bufferProvider;
private boolean failOnMissingCreatorValues;
private final Types types = new Types();
public JsonbAccessMode(final PropertyNamingStrategy
propertyNamingStrategy, final String orderValue,
final PropertyVisibilityStrategy
visibilityStrategy, final boolean caseSensitive,
final Map<AdapterKey, Adapter<?, ?>>
defaultConverters, final JohnzonAdapterFactory factory,
- final Supplier<JsonParserFactory> parserFactory,
final AccessMode delegate,
- final boolean failOnMissingCreatorValues,
- final BufferStrategy.BufferProvider<char[]>
bufferProvider) {
+ final JsonProvider jsonProvider, final
Supplier<JsonBuilderFactory> builderFactory,
+ final Supplier<JsonParserFactory> parserFactory,
+ final AccessMode delegate,
+ final boolean failOnMissingCreatorValues) {
this.naming = propertyNamingStrategy;
this.order = orderValue;
this.visibility = visibilityStrategy;
@@ -150,9 +153,10 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
this.delegate = delegate;
this.defaultConverters = defaultConverters;
this.factory = factory;
+ this.builderFactory = builderFactory;
+ this.jsonProvider = jsonProvider;
this.parserFactory = parserFactory;
this.failOnMissingCreatorValues = failOnMissingCreatorValues;
- this.bufferProvider = bufferProvider;
}
@Override
@@ -516,7 +520,7 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
writer = finalWriter::write;
}
- final ReaderConverters converters = new
ReaderConverters(initialWriter, bufferProvider);
+ final ReaderConverters converters = new
ReaderConverters(initialWriter);
final JsonbProperty property =
initialWriter.getAnnotation(JsonbProperty.class);
final JsonbNillable nillable =
initialWriter.getClassOrPackageAnnotation(JsonbNillable.class);
final boolean isNillable = nillable != null || (property != null
&& property.nillable());
@@ -617,7 +621,7 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
private ParsingCacheEntry getClassEntry(final Class<?> clazz) {
ParsingCacheEntry cache = parsingCache.get(clazz);
if (cache == null) {
- cache = new ParsingCacheEntry(new ClassDecoratedType(clazz),
types, bufferProvider);
+ cache = new ParsingCacheEntry(new ClassDecoratedType(clazz),
types);
parsingCache.putIfAbsent(clazz, cache);
}
return cache;
@@ -724,8 +728,7 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
private Adapter<?, ?> converter;
private ObjectConverter.Reader reader;
- ReaderConverters(final DecoratedType annotationHolder,
- final BufferStrategy.BufferProvider<char[]>
bufferProvider) {
+ ReaderConverters(final DecoratedType annotationHolder) {
final JsonbTypeDeserializer deserializer =
annotationHolder.getAnnotation(JsonbTypeDeserializer.class);
final JsonbTypeAdapter adapter =
annotationHolder.getAnnotation(JsonbTypeAdapter.class);
final JsonbDateFormat dateFormat =
annotationHolder.getAnnotation(JsonbDateFormat.class);
@@ -743,6 +746,7 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
final ParameterizedType pt =
types.findParameterizedType(value, JsonbDeserializer.class);
final Class<?> mappedType = types.findParamType(pt,
JsonbDeserializer.class);
toRelease.add(instance);
+ final JsonBuilderFactory builderFactoryInstance =
builderFactory.get();
reader = new ObjectConverter.Reader() {
private final ConcurrentMap<Type, BiFunction<JsonValue,
MappingParser, Object>> impl =
new ConcurrentHashMap<>();
@@ -784,7 +788,8 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
final MappingParser parser, final
JsonbDeserializer jsonbDeserializer) {
return jsonbDeserializer.deserialize(
JsonValueParserAdapter.createFor(jsonValue,
parserFactory),
- new JohnzonDeserializationContext(parser,
bufferProvider), targetType);
+ new JohnzonDeserializationContext(parser,
builderFactoryInstance, jsonProvider),
+ targetType);
}
};
} else if (johnzonConverter != null) {
@@ -876,9 +881,8 @@ public class JsonbAccessMode implements AccessMode,
Closeable {
private final ReaderConverters readers;
private final WriterConverters writers;
- ParsingCacheEntry(final DecoratedType type, final Types types,
- final BufferStrategy.BufferProvider<char[]>
bufferProvider) {
- readers = new ReaderConverters(type, bufferProvider);
+ ParsingCacheEntry(final DecoratedType type, final Types types) {
+ readers = new ReaderConverters(type);
writers = new WriterConverters(type, types);
}
}
diff --git
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/serializer/JohnzonDeserializationContext.java
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/serializer/JohnzonDeserializationContext.java
index 4c426e4..3620f4f 100644
---
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/serializer/JohnzonDeserializationContext.java
+++
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/serializer/JohnzonDeserializationContext.java
@@ -18,22 +18,32 @@
*/
package org.apache.johnzon.jsonb.serializer;
-import org.apache.johnzon.core.BufferStrategy;
-import org.apache.johnzon.core.JsonReaderImpl;
-import org.apache.johnzon.mapper.MappingParser;
+import java.lang.reflect.Type;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonBuilderFactory;
+import javax.json.JsonNumber;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
import javax.json.JsonValue;
import javax.json.bind.serializer.DeserializationContext;
+import javax.json.spi.JsonProvider;
import javax.json.stream.JsonParser;
-import java.lang.reflect.Type;
+import javax.json.stream.JsonParsingException;
+
+import org.apache.johnzon.mapper.MappingParser;
public class JohnzonDeserializationContext implements DeserializationContext {
private final MappingParser runtime;
- private final BufferStrategy.BufferProvider<char[]> bufferProvider;
+ private final JsonBuilderFactory builderFactory;
+ private final JsonProvider jsonp;
- public JohnzonDeserializationContext(final MappingParser runtime, final
BufferStrategy.BufferProvider<char[]> bufferProvider) {
+ public JohnzonDeserializationContext(final MappingParser runtime,
+ final JsonBuilderFactory
builderFactory,
+ final JsonProvider jsonp) {
this.runtime = runtime;
- this.bufferProvider = bufferProvider;
+ this.builderFactory = builderFactory;
+ this.jsonp = jsonp;
}
@Override
@@ -46,7 +56,164 @@ public class JohnzonDeserializationContext implements
DeserializationContext {
return runtime.readObject(read(parser), type);
}
- private JsonValue read(final JsonParser parser) { // TODO: use jsonp 1.1
and not johnzon internals
- return new JsonReaderImpl(parser, true, bufferProvider).readValue();
+ private JsonValue read(final JsonParser parser) {
+ final JsonParser.Event next = parser.next();
+ switch (next) {
+ case START_OBJECT:
+ final JsonObjectBuilder objectBuilder =
builderFactory.createObjectBuilder();
+ parseObject(parser, objectBuilder);
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file",
parser.getLocation());
+ }
+ return objectBuilder.build();
+ case START_ARRAY:
+ final JsonArrayBuilder arrayBuilder =
builderFactory.createArrayBuilder();
+ parseArray(parser, arrayBuilder);
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file",
parser.getLocation());
+ }
+ return arrayBuilder.build();
+ case VALUE_STRING:
+ final JsonString string =
jsonp.createValue(parser.getString());
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file",
parser.getLocation());
+ }
+ return string;
+ case VALUE_FALSE:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file",
parser.getLocation());
+ }
+ return JsonValue.FALSE;
+ case VALUE_TRUE:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file",
parser.getLocation());
+ }
+ return JsonValue.TRUE;
+ case VALUE_NULL:
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file",
parser.getLocation());
+ }
+ return JsonValue.NULL;
+ case VALUE_NUMBER:
+ final JsonNumber number =
jsonp.createValue(parser.getBigDecimal());
+ if (parser.hasNext()) {
+ throw new JsonParsingException("Expected end of file",
parser.getLocation());
+ }
+ return number;
+ default:
+ throw new JsonParsingException("Unknown structure: " + next,
parser.getLocation());
+ }
+ }
+
+ private void parseObject(final JsonParser parser, final JsonObjectBuilder
builder) {
+ String key = null;
+ while (parser.hasNext()) {
+ final JsonParser.Event next = parser.next();
+ switch (next) {
+ case KEY_NAME:
+ key = parser.getString();
+ break;
+
+ case VALUE_STRING:
+ builder.add(key, jsonp.createValue(parser.getString()));
+ break;
+
+ case START_OBJECT:
+ final JsonObjectBuilder subObject =
builderFactory.createObjectBuilder();
+ parseObject(parser, subObject);
+ builder.add(key, subObject);
+ break;
+
+ case START_ARRAY:
+ final JsonArrayBuilder subArray =
builderFactory.createArrayBuilder();
+ parseArray(parser, subArray);
+ builder.add(key, subArray);
+ break;
+
+ case VALUE_NUMBER:
+ if (parser.isIntegralNumber()) {
+ builder.add(key, jsonp.createValue(parser.getLong()));
+ } else {
+ builder.add(key,
jsonp.createValue(parser.getBigDecimal()));
+ }
+ break;
+
+ case VALUE_NULL:
+ builder.addNull(key);
+ break;
+
+ case VALUE_TRUE:
+ builder.add(key, true);
+ break;
+
+ case VALUE_FALSE:
+ builder.add(key, false);
+ break;
+
+ case END_OBJECT:
+ return;
+
+ case END_ARRAY:
+ throw new JsonParsingException("']', shouldn't occur",
parser.getLocation());
+
+ default:
+ throw new JsonParsingException(next.name() + ", shouldn't
occur", parser.getLocation());
+ }
+ }
+ }
+
+ private void parseArray(final JsonParser parser, final JsonArrayBuilder
builder) {
+ while (parser.hasNext()) {
+ final JsonParser.Event next = parser.next();
+ switch (next) {
+ case VALUE_STRING:
+ builder.add(jsonp.createValue(parser.getString()));
+ break;
+
+ case VALUE_NUMBER:
+ if (parser.isIntegralNumber()) {
+ builder.add(jsonp.createValue(parser.getLong()));
+ } else {
+ builder.add(jsonp.createValue(parser.getBigDecimal()));
+ }
+ break;
+
+ case START_OBJECT:
+ final JsonObjectBuilder subObject =
builderFactory.createObjectBuilder();
+ parseObject(parser, subObject);
+ builder.add(subObject);
+ break;
+
+ case START_ARRAY:
+ final JsonArrayBuilder subArray =
builderFactory.createArrayBuilder();
+ parseArray(parser, subArray);
+ builder.add(subArray);
+ break;
+
+ case END_ARRAY:
+ return;
+
+ case VALUE_NULL:
+ builder.addNull();
+ break;
+
+ case VALUE_TRUE:
+ builder.add(true);
+ break;
+
+ case VALUE_FALSE:
+ builder.add(false);
+ break;
+
+ case KEY_NAME:
+ throw new JsonParsingException("array doesn't have keys",
parser.getLocation());
+
+ case END_OBJECT:
+ throw new JsonParsingException("'}', shouldn't occur",
parser.getLocation());
+
+ default:
+ throw new JsonParsingException(next.name() + ", shouldn't
occur", parser.getLocation());
+ }
+ }
}
}