You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ml...@apache.org on 2018/05/06 14:05:54 UTC

polygene-java git commit: less memory consumption in json (de)serializer [Forced Update!]

Repository: polygene-java
Updated Branches:
  refs/heads/json-revisited 6b569234b -> f8e98b96c (forced update)


less memory consumption in json (de)serializer


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/f8e98b96
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/f8e98b96
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/f8e98b96

Branch: refs/heads/json-revisited
Commit: f8e98b96cba0170d5cf05b3f5f72bc2cca2e6013
Parents: 98b50f2
Author: tbml <ti...@adleritech.com>
Authored: Fri May 4 17:41:32 2018 +0200
Committer: tbml <ti...@adleritech.com>
Committed: Sun May 6 16:04:55 2018 +0200

----------------------------------------------------------------------
 .../javaxjson/JavaxJsonAdapters.java            |   8 +-
 .../javaxjson/JavaxJsonDeserializer.java        | 114 ++++++-------------
 .../javaxjson/JavaxJsonFactories.java           |   8 +-
 .../javaxjson/JavaxJsonSerializer.java          |   5 +-
 dependencies.gradle                             |   2 +-
 5 files changed, 55 insertions(+), 82 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/f8e98b96/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
index dccf388..8f52391 100644
--- a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
@@ -135,7 +135,13 @@ public interface JavaxJsonAdapters
             @Override
             public String deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserialize )
             {
-                return JavaxJson.asString( json );
+                switch (json.getValueType()) {
+                    case NULL:
+                        return null;
+                    default:
+                        return JavaxJson.asString(json);
+                }
+
             }
         }
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/f8e98b96/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
index ad647a4..3ccc884 100644
--- a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
@@ -17,11 +17,7 @@
  */
 package org.apache.polygene.serialization.javaxjson;
 
-import java.io.BufferedReader;
-import java.io.IOException;
 import java.io.Reader;
-import java.io.StringReader;
-import java.io.UncheckedIOException;
 import java.lang.reflect.Array;
 import java.util.AbstractMap;
 import java.util.ArrayList;
@@ -31,17 +27,15 @@ import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Scanner;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import javax.json.JsonArray;
 import javax.json.JsonObject;
 import javax.json.JsonReader;
-import javax.json.JsonString;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
-import javax.json.stream.JsonParser;
-import javax.json.stream.JsonParsingException;
 import org.apache.polygene.api.association.AssociationDescriptor;
 import org.apache.polygene.api.composite.CompositeDescriptor;
 import org.apache.polygene.api.composite.StatefulAssociationCompositeDescriptor;
@@ -68,7 +62,6 @@ import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Collections.unmodifiableList;
 import static java.util.Collections.unmodifiableMap;
 import static java.util.Collections.unmodifiableSet;
-import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toCollection;
 import static org.apache.polygene.api.util.Collectors.toMapWithNullValues;
 import static org.apache.polygene.serialization.javaxjson.JavaxJson.asString;
@@ -92,88 +85,35 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer
     private ServiceDescriptor descriptor;
 
     private JavaxJsonSettings settings;
-    private JsonString emptyJsonString;
 
     @Override
     public void initialize() throws Exception
     {
         settings = JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) );
-        emptyJsonString = jsonFactories.builderFactory().createObjectBuilder().add( "s", "" ).build()
-                                       .getJsonString( "s" );
     }
 
-    @Override
-    public <T> T deserialize( ModuleDescriptor module, ValueType valueType, Reader state )
+    @SuppressWarnings("unchecked")
+    public <T> T deserialize(ModuleDescriptor module, ValueType valueType, Reader state)
     {
-        // JSR-353 Does not allow reading "out of structure" values
-        // See https://www.jcp.org/en/jsr/detail?id=353
-        // And commented JsonReader#readValue() method in the javax.json API
-        // BUT, it will be part of the JsonReader contract in the next version
-        // See https://www.jcp.org/en/jsr/detail?id=374
-        // Implementation by provider is optional though, so we'll always need a default implementation here.
-        // Fortunately, JsonParser has new methods allowing to read structures while parsing so it will be easy to do.
-        // In the meantime, a poor man's implementation reading the json into memory will do.
-        // TODO Revisit values out of structure JSON deserialization when JSR-374 is out
-        String stateString;
-        try( BufferedReader buffer = new BufferedReader( state ) )
-        {
-            stateString = buffer.lines().collect( joining( "\n" ) );
-        }
-        catch( IOException ex )
-        {
-            throw new UncheckedIOException( ex );
-        }
-        // We want plain Strings, BigDecimals, BigIntegers to be deserialized even when unquoted
-        Function<String, T> plainValueFunction = string ->
-        {
-            String poorMans = "{\"value\":" + string + "}";
-            JsonObject poorMansJson = jsonFactories.readerFactory()
-                                                   .createReader( new StringReader( poorMans ) )
-                                                   .readObject();
-            JsonValue value = poorMansJson.get( "value" );
-            return fromJson( module, valueType, value );
-        };
-        Function<String, T> outOfStructureFunction = string ->
+        Converter<Object> converter = converters.converterFor(valueType);
+        if (converter != null)
         {
-            // Is this an unquoted plain value?
-            try
-            {
-                return plainValueFunction.apply( '"' + string + '"' );
-            }
-            catch( JsonParsingException ex )
-            {
-                return plainValueFunction.apply( string );
-            }
-        };
-        try( JsonParser parser = jsonFactories.parserFactory().createParser( new StringReader( stateString ) ) )
-        {
-            if( parser.hasNext() )
-            {
-                JsonParser.Event e = parser.next();
-                switch( e )
-                {
-                    case VALUE_NULL:
-                        return null;
-                    case START_ARRAY:
-                    case START_OBJECT:
-                        // JSON Structure
-                        try( JsonReader reader = jsonFactories.readerFactory()
-                                                              .createReader( new StringReader( stateString ) ) )
-                        {
-                            return fromJson( module, valueType, reader.read() );
-                        }
-                    default:
-                        // JSON Value out of structure
-                        return outOfStructureFunction.apply( stateString );
-                }
+            String stateString = readString(state);
+            if (isJsonNull(stateString)) {
+                return null;
+            } else {
+                return (T) converter.fromString(stateString);
             }
         }
-        catch( JsonParsingException ex )
-        {
-            return outOfStructureFunction.apply( stateString );
+
+        JavaxJsonAdapter<?> adapter = adapters.adapterFor(valueType);
+        if (adapter != null) {
+            return (T) adapter.deserialize(readJsonString(state), (jsonValue, type) -> doDeserialize(module, type, jsonValue));
+        }
+
+        try (JsonReader reader = jsonFactories.readerFactory().createReader(state)) {
+            return fromJson(module, valueType, reader.readValue());
         }
-        // Empty state string?
-        return fromJson( module, valueType, emptyJsonString );
     }
 
     @Override
@@ -182,6 +122,24 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer
         return doDeserialize( module, valueType, state );
     }
 
+    private JsonValue readJsonString(Reader reader) {
+        String str = readString(reader);
+        if (isJsonNull(str)) {
+            return JsonValue.NULL;
+        } else {
+            return jsonFactories.provider().createValue(str);
+        }
+    }
+
+    private boolean isJsonNull(String str) {
+        return "null".equals(str);
+    }
+
+    private String readString(Reader reader) {
+        Scanner scanner = new Scanner(reader).useDelimiter("\\A");
+        return scanner.hasNext() ? scanner.next() : "";
+    }
+
     @SuppressWarnings( "unchecked" )
     private <T> T doDeserialize( ModuleDescriptor module, ValueType valueType, JsonValue json )
     {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/f8e98b96/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonFactories.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonFactories.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonFactories.java
index 0a790f2..eb54c97 100644
--- a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonFactories.java
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonFactories.java
@@ -50,6 +50,7 @@ public interface JavaxJsonFactories
 
     JsonWriterFactory writerFactory();
 
+    JsonProvider provider();
     /**
      * Creates a {@link JsonString} with the {@link Object#toString()} result on the given object.
      *
@@ -111,6 +112,7 @@ public interface JavaxJsonFactories
         private JsonGeneratorFactory generatorFactory;
         private JsonBuilderFactory builderFactory;
         private JsonWriterFactory writerFactory;
+        private JsonProvider jsonProvider;
 
         @Override
         public void initialize() throws Exception
@@ -118,7 +120,6 @@ public interface JavaxJsonFactories
             JavaxJsonSettings settings = JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) );
 
             String jsonProviderClassName = settings.getJsonProviderClassName();
-            JsonProvider jsonProvider;
             if( jsonProviderClassName == null )
             {
                 jsonProvider = JsonProvider.provider();
@@ -251,5 +252,10 @@ public interface JavaxJsonFactories
             }
             return job;
         }
+
+        @Override
+        public JsonProvider provider() {
+            return jsonProvider;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/f8e98b96/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
index 17286f8..053c1d2 100644
--- a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
@@ -32,6 +32,7 @@ import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonString;
 import javax.json.JsonValue;
+import javax.json.JsonWriter;
 import org.apache.polygene.api.PolygeneAPI;
 import org.apache.polygene.api.association.AssociationStateHolder;
 import org.apache.polygene.api.common.Optional;
@@ -98,7 +99,9 @@ public class JavaxJsonSerializer extends AbstractTextSerializer
             }
             else
             {
-                writer.write( jsonValue.toString() );
+                try (JsonWriter w = jsonFactories.writerFactory().createWriter(writer)) {
+                    w.write(jsonValue);
+                }
             }
         }
         catch( IOException ex )

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/f8e98b96/dependencies.gradle
----------------------------------------------------------------------
diff --git a/dependencies.gradle b/dependencies.gradle
index bac7a6e..1b0f73e 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -65,7 +65,7 @@ def jcloudsVersion = '2.0.2'
 def jdbmVersion = '2.4'
 def jedisVersion = '2.9.0'
 def jettyVersion = '9.2.17.v20160517' // 9.3.x Tests fail!
-def johnzonVersion = '1.1.1'
+def johnzonVersion = '1.1.7'
 def jooqVersion = '3.10.6'
 def kotlinVersion = '1.2.31'
 def leveldbVersion = '0.9'