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());
+            }
+        }
     }
 }

Reply via email to