You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2017/04/02 17:11:49 UTC

[1/3] polygene-java git commit: Do not constrain XmlDeserializer input to Document, use Node instead

Repository: polygene-java
Updated Branches:
  refs/heads/serialization-3.0 8953566e1 -> c9639a390


Do not constrain XmlDeserializer input to Document, use Node instead

This gives users of the XmlDeserializer service more freedom as to where
they get the XML state from.


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

Branch: refs/heads/serialization-3.0
Commit: d6e1b0ef0f48188177ae5e97e6bbaa33f766fb3f
Parents: 8953566
Author: Paul Merlin <pa...@apache.org>
Authored: Sun Apr 2 15:26:34 2017 +0200
Committer: Paul Merlin <pa...@apache.org>
Committed: Sun Apr 2 15:31:20 2017 +0200

----------------------------------------------------------------------
 .../spi/serialization/XmlDeserializer.java      | 21 ++++++++++----------
 .../spi/serialization/XmlSerializer.java        |  2 +-
 .../javaxxml/JavaxXmlDeserializer.java          |  3 +--
 3 files changed, 13 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/d6e1b0ef/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
index f61e533..3d42828 100644
--- a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
@@ -33,57 +33,58 @@ import org.apache.polygene.spi.module.ModuleSpi;
 import org.w3c.dom.Document;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
+import org.w3c.dom.Node;
 
 /**
  * {@literal javax.xml} deserializer.
  */
 public interface XmlDeserializer extends Deserializer
 {
-    <T> T fromXml( ModuleDescriptor module, ValueType valueType, Document state );
+    <T> T fromXml( ModuleDescriptor module, ValueType valueType, Node state );
 
-    default <T> Function<Document, T> fromXmlFunction( ModuleDescriptor module, ValueType valueType )
+    default <T> Function<Node, T> fromXmlFunction( ModuleDescriptor module, ValueType valueType )
     {
         return state -> fromXml( module, valueType, state );
     }
 
-    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType valueType, Stream<Document> states )
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType valueType, Stream<Node> states )
     {
         return states.map( fromXmlFunction( module, valueType ) );
     }
 
-    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType valueType, Iterable<Document> states )
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType valueType, Iterable<Node> states )
     {
         return fromXmlEach( module, valueType, StreamSupport.stream( states.spliterator(), false ) );
     }
 
-    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType valueType, Document... states )
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType valueType, Node... states )
     {
         return fromXmlEach( module, valueType, Stream.of( states ) );
     }
 
-    default <T> T fromXml( ModuleDescriptor module, Class<T> type, Document state )
+    default <T> T fromXml( ModuleDescriptor module, Class<T> type, Node state )
     {
         // TODO Remove (ModuleSpi) cast
         ValueType valueType = ( (ModuleSpi) module.instance() ).valueTypeFactory().valueTypeOf( module, type );
         return fromXml( module, valueType, state );
     }
 
-    default <T> Function<Document, T> fromXml( ModuleDescriptor module, Class<T> type )
+    default <T> Function<Node, T> fromXml( ModuleDescriptor module, Class<T> type )
     {
         return state -> fromXml( module, type, state );
     }
 
-    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> valueType, Stream<Document> states )
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> valueType, Stream<Node> states )
     {
         return states.map( fromXml( module, valueType ) );
     }
 
-    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> valueType, Iterable<Document> states )
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> valueType, Iterable<Node> states )
     {
         return fromXmlEach( module, valueType, StreamSupport.stream( states.spliterator(), false ) );
     }
 
-    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> valueType, Document... states )
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> valueType, Node... states )
     {
         return fromXmlEach( module, valueType, Stream.of( states ) );
     }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/d6e1b0ef/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
index afffe5f..6e1b7dc 100644
--- a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
@@ -96,7 +96,7 @@ public interface XmlSerializer extends Serializer
         }
         try
         {
-            // We want plain Strings to be serialized without quotes
+            // We want plain text nodes to be serialized without surrounding elements
             if( xmlDocument.getNodeType() == Node.TEXT_NODE )
             {
                 writer.write( xmlDocument.getNodeValue() );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/d6e1b0ef/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
index 8c6bc7b..5caed72 100644
--- a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
+++ b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
@@ -53,7 +53,6 @@ import org.apache.polygene.api.value.ValueBuilder;
 import org.apache.polygene.api.value.ValueDescriptor;
 import org.apache.polygene.spi.serialization.AbstractTextDeserializer;
 import org.apache.polygene.spi.serialization.XmlDeserializer;
-import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -77,7 +76,7 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
     private ServiceDescriptor descriptor;
 
     @Override
-    public <T> T fromXml( ModuleDescriptor module, ValueType valueType, Document state )
+    public <T> T fromXml( ModuleDescriptor module, ValueType valueType, Node state )
     {
         Optional<Element> stateElement = JavaxXml.firstChildElementNamed( state, getSettings().getRootTagName() );
         if( stateElement.isPresent() )


[2/3] polygene-java git commit: XML Serialization enhancements

Posted by pa...@apache.org.
XML Serialization enhancements

Reuse XML factories and transformers for performance reasons.
Allow to explicitly set XML factories implementation during assembly.
Normalize XML when deserializing for lenient parsing.
Adds coverage with hand crafted XML documents.


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

Branch: refs/heads/serialization-3.0
Commit: 6552f23014b632c4b775734071aa013305a97974
Parents: d6e1b0e
Author: Paul Merlin <pa...@apache.org>
Authored: Sun Apr 2 16:48:25 2017 +0200
Committer: Paul Merlin <pa...@apache.org>
Committed: Sun Apr 2 17:58:20 2017 +0200

----------------------------------------------------------------------
 .../spi/serialization/XmlDeserializer.java      |  24 ---
 .../spi/serialization/XmlSerializer.java        |  45 ------
 .../javaxxml/JavaxXmlDeserializer.java          |  66 +++++++--
 .../javaxxml/JavaxXmlFactories.java             |  74 ++++++++++
 .../javaxxml/JavaxXmlSerializer.java            |  77 ++++++++--
 .../javaxxml/JavaxXmlSettings.java              |  24 +++
 .../javaxxml/deserializer-normalization.xsl     |   9 ++
 .../javaxxml/HandCraftedXmlTest.java            | 146 +++++++++++++++++++
 ...JavaxXmlValueCompositeSerializationTest.java |   1 -
 9 files changed, 371 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
index 3d42828..4ea4fe1 100644
--- a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
@@ -17,22 +17,13 @@
  */
 package org.apache.polygene.spi.serialization;
 
-import java.io.IOException;
-import java.io.Reader;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 import org.apache.polygene.api.serialization.Deserializer;
-import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.type.ValueType;
 import org.apache.polygene.spi.module.ModuleSpi;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
 import org.w3c.dom.Node;
 
 /**
@@ -88,19 +79,4 @@ public interface XmlDeserializer extends Deserializer
     {
         return fromXmlEach( module, valueType, Stream.of( states ) );
     }
-
-    @Override
-    default <T> T deserialize( ModuleDescriptor module, ValueType valueType, Reader state )
-    {
-        try
-        {
-            DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-            Document doc = docBuilder.parse( new InputSource( state ) );
-            return fromXml( module, valueType, doc );
-        }
-        catch( SAXException | IOException | ParserConfigurationException ex )
-        {
-            throw new SerializationException( "Unable to read XML document", ex );
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
index 6e1b7dc..007f731 100644
--- a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
@@ -17,23 +17,12 @@
  */
 package org.apache.polygene.spi.serialization;
 
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.io.Writer;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 import org.apache.polygene.api.common.Optional;
-import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.serialization.Serializer;
 import org.w3c.dom.Document;
-import org.w3c.dom.Node;
 
 /**
  * {@literal javax.xml} serializer.
@@ -86,38 +75,4 @@ public interface XmlSerializer extends Serializer
     {
         return toXmlEach( Options.DEFAULT, Stream.of( objects ) );
     }
-
-    default void serialize( Options options, Writer writer, @Optional Object object )
-    {
-        Document xmlDocument = toXml( options, object );
-        if( xmlDocument == null )
-        {
-            return;
-        }
-        try
-        {
-            // We want plain text nodes to be serialized without surrounding elements
-            if( xmlDocument.getNodeType() == Node.TEXT_NODE )
-            {
-                writer.write( xmlDocument.getNodeValue() );
-            }
-            else
-            {
-                Transformer transformer = TransformerFactory.newInstance().newTransformer();
-                transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
-                transformer.setOutputProperty( OutputKeys.VERSION, "1.1" );
-                transformer.setOutputProperty( OutputKeys.STANDALONE, "yes" );
-                transformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
-                transformer.transform( new DOMSource( xmlDocument ), new StreamResult( writer ) );
-            }
-        }
-        catch( IOException ex )
-        {
-            throw new UncheckedIOException( ex );
-        }
-        catch( TransformerException ex )
-        {
-            throw new SerializationException( "Unable to transform XML Document to String", ex );
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
index 5caed72..69a9068 100644
--- a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
+++ b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
@@ -17,6 +17,8 @@
  */
 package org.apache.polygene.serialization.javaxxml;
 
+import java.io.InputStream;
+import java.io.Reader;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Base64;
@@ -33,10 +35,16 @@ import java.util.function.Predicate;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamSource;
 import org.apache.polygene.api.association.AssociationDescriptor;
 import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Initializable;
 import org.apache.polygene.api.property.PropertyDescriptor;
 import org.apache.polygene.api.serialization.Converter;
 import org.apache.polygene.api.serialization.Converters;
@@ -62,11 +70,15 @@ import static java.util.Collections.unmodifiableMap;
 import static java.util.Collections.unmodifiableSet;
 import static org.apache.polygene.api.util.Collectors.toMapWithNullValues;
 
-public class JavaxXmlDeserializer extends AbstractTextDeserializer implements XmlDeserializer
+public class JavaxXmlDeserializer extends AbstractTextDeserializer
+    implements XmlDeserializer, Initializable
 {
     private static final String NULL_ELEMENT_NAME = "null";
 
     @This
+    private JavaxXmlFactories xmlFactories;
+
+    @This
     private Converters converters;
 
     @This
@@ -75,10 +87,45 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
     @Uses
     private ServiceDescriptor descriptor;
 
+    private JavaxXmlSettings settings;
+
+    private Transformer normalizingTransformer;
+
+    @Override
+    public void initialize() throws Exception
+    {
+        settings = JavaxXmlSettings.orDefault( descriptor.metaInfo( JavaxXmlSettings.class ) );
+
+        String xslPath = "/org/apache/polygene/serialization/javaxxml/deserializer-normalization.xsl";
+        InputStream xsltStream = getClass().getResourceAsStream( xslPath );
+        normalizingTransformer = xmlFactories.transformerFactory()
+                                             .newTransformer( new StreamSource( xsltStream ) );
+        normalizingTransformer.setOutputProperty( OutputKeys.METHOD, "xml" );
+        normalizingTransformer.setOutputProperty( OutputKeys.VERSION, "1.1" );
+        normalizingTransformer.setOutputProperty( OutputKeys.STANDALONE, "yes" );
+        normalizingTransformer.setOutputProperty( OutputKeys.ENCODING, UTF_8.name() );
+    }
+
+    @Override
+    public <T> T deserialize( ModuleDescriptor module, ValueType valueType, Reader state )
+    {
+        try
+        {
+            DOMResult domResult = new DOMResult();
+            normalizingTransformer.transform( new StreamSource( state ), domResult );
+            Node node = domResult.getNode();
+            return fromXml( module, valueType, node );
+        }
+        catch( TransformerException ex )
+        {
+            throw new SerializationException( "Unable to read XML document", ex );
+        }
+    }
+
     @Override
     public <T> T fromXml( ModuleDescriptor module, ValueType valueType, Node state )
     {
-        Optional<Element> stateElement = JavaxXml.firstChildElementNamed( state, getSettings().getRootTagName() );
+        Optional<Element> stateElement = JavaxXml.firstChildElementNamed( state, settings.getRootTagName() );
         if( stateElement.isPresent() )
         {
             Optional<Node> stateNode = JavaxXml.firstStateChildNode( stateElement.get() );
@@ -139,7 +186,7 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
             ValueDescriptor descriptor = module.valueDescriptor( typeInfo.get() );
             if( descriptor == null )
             {
-                String typeInfoName = getSettings().getTypeInfoTagName();
+                String typeInfoName = settings.getTypeInfoTagName();
                 throw new SerializationException(
                     typeInfoName + ": " + typeInfo.get() + " could not be resolved while deserializing " + xml );
             }
@@ -252,7 +299,7 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
             .childElements( xml )
             .map( element ->
                   {
-                      if( getSettings().getCollectionElementTagName().equals( element.getTagName() ) )
+                      if( settings.getCollectionElementTagName().equals( element.getTagName() ) )
                       {
                           return doDeserialize( module, collectionType.collectedType(),
                                                 JavaxXml.firstStateChildNode( element ).get() );
@@ -269,7 +316,7 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
         {
             return new LinkedHashMap<>();
         }
-        Predicate<Element> complexMapping = element -> getSettings().getMapEntryTagName().equals( element.getTagName() )
+        Predicate<Element> complexMapping = element -> settings.getMapEntryTagName().equals( element.getTagName() )
                                                        && JavaxXml.firstChildElementNamed( element, "key" )
                                                                   .isPresent();
         // This allows deserializing mixed simple/complex mappings for a given map
@@ -309,7 +356,7 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
                 return deserializeValueComposite( valueDescriptor.module(), valueDescriptor.valueType(), xml );
             }
         }
-        if( xml.getNodeType() == Node.CDATA_SECTION_NODE )
+        if( xml.getNodeType() == Node.CDATA_SECTION_NODE || xml.getNodeType() == Node.TEXT_NODE )
         {
             byte[] bytes = Base64.getDecoder().decode( xml.getNodeValue().getBytes( UTF_8 ) );
             return deserializeJava( bytes );
@@ -323,16 +370,11 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
         {
             return Optional.empty();
         }
-        String typeInfo = ( (Element) xml ).getAttribute( getSettings().getTypeInfoTagName() );
+        String typeInfo = ( (Element) xml ).getAttribute( settings.getTypeInfoTagName() );
         if( typeInfo.isEmpty() )
         {
             return Optional.empty();
         }
         return Optional.of( typeInfo );
     }
-
-    private JavaxXmlSettings getSettings()
-    {
-        return JavaxXmlSettings.orDefault( descriptor.metaInfo( JavaxXmlSettings.class ) );
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlFactories.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlFactories.java b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlFactories.java
new file mode 100644
index 0000000..f3a7f80
--- /dev/null
+++ b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlFactories.java
@@ -0,0 +1,74 @@
+/*
+ *  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.polygene.serialization.javaxxml;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.TransformerFactory;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Initializable;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.service.ServiceDescriptor;
+
+@Mixins( JavaxXmlFactories.Mixin.class )
+public interface JavaxXmlFactories
+{
+    DocumentBuilderFactory documentBuilderFactory();
+
+    TransformerFactory transformerFactory();
+
+    class Mixin implements JavaxXmlFactories, Initializable
+    {
+        @Uses
+        private ServiceDescriptor descriptor;
+
+        private DocumentBuilderFactory documentBuilderFactory;
+        private TransformerFactory transformerFactory;
+
+        @Override
+        public void initialize()
+        {
+            JavaxXmlSettings settings = JavaxXmlSettings.orDefault( descriptor.metaInfo( JavaxXmlSettings.class ) );
+
+            String documentBuilderFactoryClassName = settings.getDocumentBuilderFactoryClassName();
+            documentBuilderFactory = documentBuilderFactoryClassName == null
+                                     ? DocumentBuilderFactory.newInstance()
+                                     : DocumentBuilderFactory.newInstance( documentBuilderFactoryClassName,
+                                                                           getClass().getClassLoader() );
+            documentBuilderFactory.setNamespaceAware( false );
+            documentBuilderFactory.setIgnoringComments( true );
+
+            String transformerFactoryClassName = settings.getTransformerFactoryClassName();
+            transformerFactory = transformerFactoryClassName == null
+                                 ? TransformerFactory.newInstance()
+                                 : TransformerFactory.newInstance( transformerFactoryClassName,
+                                                                   getClass().getClassLoader() );
+        }
+
+        @Override
+        public DocumentBuilderFactory documentBuilderFactory()
+        {
+            return documentBuilderFactory;
+        }
+
+        @Override
+        public TransformerFactory transformerFactory()
+        {
+            return transformerFactory;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
index 3c49699..44fd7b0 100644
--- a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
+++ b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
@@ -17,19 +17,28 @@
  */
 package org.apache.polygene.serialization.javaxxml;
 
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.io.Writer;
 import java.util.Base64;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
 import org.apache.polygene.api.PolygeneAPI;
 import org.apache.polygene.api.association.AssociationStateHolder;
+import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.composite.CompositeInstance;
 import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Initializable;
 import org.apache.polygene.api.serialization.Converter;
 import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.serialization.SerializationException;
@@ -54,11 +63,15 @@ import static org.apache.polygene.api.util.Collectors.toMap;
 /**
  * XML Serializer.
  */
-public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSerializer
+public class JavaxXmlSerializer extends AbstractTextSerializer
+    implements XmlSerializer, Initializable
 {
     private static final String NULL_ELEMENT_NAME = "null";
 
     @This
+    private JavaxXmlFactories xmlFactories;
+
+    @This
     private Converters converters;
 
     @This
@@ -67,6 +80,51 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
     @Uses
     private ServiceDescriptor descriptor;
 
+    private JavaxXmlSettings settings;
+
+    private Transformer toStringTransformer;
+
+    @Override
+    public void initialize() throws Exception
+    {
+        settings = JavaxXmlSettings.orDefault( descriptor.metaInfo( JavaxXmlSettings.class ) );
+        toStringTransformer = xmlFactories.transformerFactory().newTransformer();
+        toStringTransformer.setOutputProperty( OutputKeys.METHOD, "xml" );
+        toStringTransformer.setOutputProperty( OutputKeys.VERSION, "1.1" );
+        toStringTransformer.setOutputProperty( OutputKeys.STANDALONE, "yes" );
+        toStringTransformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
+    }
+
+    @Override
+    public void serialize( Options options, Writer writer, @Optional Object object )
+    {
+        Document xmlDocument = toXml( options, object );
+        if( xmlDocument == null )
+        {
+            return;
+        }
+        try
+        {
+            // We want plain text nodes to be serialized without surrounding elements
+            if( xmlDocument.getNodeType() == Node.TEXT_NODE )
+            {
+                writer.write( xmlDocument.getNodeValue() );
+            }
+            else
+            {
+                toStringTransformer.transform( new DOMSource( xmlDocument ), new StreamResult( writer ) );
+            }
+        }
+        catch( IOException ex )
+        {
+            throw new UncheckedIOException( ex );
+        }
+        catch( TransformerException ex )
+        {
+            throw new SerializationException( "Unable to transform XML Document to String", ex );
+        }
+    }
+
     @Override
     public <T> Function<T, Document> toXmlFunction( Options options )
     {
@@ -77,10 +135,10 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
     {
         try
         {
-            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+            Document doc = xmlFactories.documentBuilderFactory().newDocumentBuilder().newDocument();
             doc.setXmlVersion( "1.1" );
             doc.setXmlStandalone( true );
-            Element stateElement = doc.createElement( getSettings().getRootTagName() );
+            Element stateElement = doc.createElement( settings.getRootTagName() );
             Node node = doSerialize( doc, options, object, true );
             stateElement.appendChild( node );
             doc.appendChild( stateElement );
@@ -146,7 +204,7 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
         AssociationStateHolder state = (AssociationStateHolder) instance.state();
         ValueCompositeType valueType = descriptor.valueType();
 
-        Element valueElement = document.createElement( getSettings().getValueTagName() );
+        Element valueElement = document.createElement( settings.getValueTagName() );
         valueType.properties().forEach(
             property ->
             {
@@ -185,14 +243,13 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
         );
         if( !root && options.includeTypeInfo() )
         {
-            valueElement.setAttribute( getSettings().getTypeInfoTagName(), valueType.primaryType().getName() );
+            valueElement.setAttribute( settings.getTypeInfoTagName(), valueType.primaryType().getName() );
         }
         return valueElement;
     }
 
     private Node serializeMap( Document document, Options options, Map<?, ?> map )
     {
-        JavaxXmlSettings settings = getSettings();
         Element mapElement = document.createElement( settings.getMapTagName() );
         if( map.isEmpty() )
         {
@@ -264,7 +321,6 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
 
     private Node serializeStream( Document document, Options options, Stream<?> object )
     {
-        JavaxXmlSettings settings = getSettings();
         Element collectionElement = document.createElement( settings.getCollectionTagName() );
         object.map( each -> doSerialize( document, options, each, false ) )
               .forEach( itemValueNode ->
@@ -275,9 +331,4 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
                         } );
         return collectionElement;
     }
-
-    private JavaxXmlSettings getSettings()
-    {
-        return JavaxXmlSettings.orDefault( descriptor.metaInfo( JavaxXmlSettings.class ) );
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSettings.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSettings.java b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSettings.java
index c5484fb..9f4d007 100644
--- a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSettings.java
+++ b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSettings.java
@@ -37,6 +37,9 @@ public class JavaxXmlSettings extends SerializationSettings<JavaxXmlSettings>
         return settings != null ? settings : DEFAULT;
     }
 
+    private String documentBuilderFactoryClassName;
+    private String transformerFactoryClassName;
+
     private String rootTagName;
     private String collectionTagName;
     private String collectionElementTagName;
@@ -44,6 +47,7 @@ public class JavaxXmlSettings extends SerializationSettings<JavaxXmlSettings>
     private String mapEntryTagName;
     private String valueTagName;
     private String typeInfoTagName;
+
     private Map<ValueType, JavaxXmlAdapter<?>> adapters;
 
     public JavaxXmlSettings()
@@ -58,6 +62,26 @@ public class JavaxXmlSettings extends SerializationSettings<JavaxXmlSettings>
         adapters = new LinkedHashMap<>();
     }
 
+    public String getDocumentBuilderFactoryClassName()
+    {
+        return documentBuilderFactoryClassName;
+    }
+
+    public void setDocumentBuilderFactoryClassName( String documentBuilderFactoryClassName )
+    {
+        this.documentBuilderFactoryClassName = documentBuilderFactoryClassName;
+    }
+
+    public String getTransformerFactoryClassName()
+    {
+        return transformerFactoryClassName;
+    }
+
+    public void setTransformerFactoryClassName( String transformerFactoryClassName )
+    {
+        this.transformerFactoryClassName = transformerFactoryClassName;
+    }
+
     public String getRootTagName()
     {
         return rootTagName;

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/extensions/serialization-javaxxml/src/main/resources/org/apache/polygene/serialization/javaxxml/deserializer-normalization.xsl
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/main/resources/org/apache/polygene/serialization/javaxxml/deserializer-normalization.xsl b/extensions/serialization-javaxxml/src/main/resources/org/apache/polygene/serialization/javaxxml/deserializer-normalization.xsl
new file mode 100644
index 0000000..6c8505b
--- /dev/null
+++ b/extensions/serialization-javaxxml/src/main/resources/org/apache/polygene/serialization/javaxxml/deserializer-normalization.xsl
@@ -0,0 +1,9 @@
+<?xml version="1.1" encoding="UTF-8" standalone="yes"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+    <xsl:strip-space elements="*"/>
+    <xsl:template match="@*|node()">
+        <xsl:copy>
+            <xsl:apply-templates select="@*|node()"/>
+        </xsl:copy>
+    </xsl:template>
+</xsl:stylesheet>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/HandCraftedXmlTest.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/HandCraftedXmlTest.java b/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/HandCraftedXmlTest.java
new file mode 100644
index 0000000..18f251a
--- /dev/null
+++ b/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/HandCraftedXmlTest.java
@@ -0,0 +1,146 @@
+/*
+ *  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.polygene.serialization.javaxxml;
+
+import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.property.Property;
+import org.apache.polygene.api.serialization.Deserializer;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.serialization.javaxxml.assembly.JavaxXmlSerializationAssembler;
+import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class HandCraftedXmlTest extends AbstractPolygeneTest
+{
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+        new JavaxXmlSerializationAssembler().assemble( module );
+        module.values( SomeValue.class );
+    }
+
+    public interface SomeValue
+    {
+        @Optional
+        Property<String> foo();
+    }
+
+    @Service
+    private Deserializer deserializer;
+
+    @Test
+    public void canReadSingleLineXml()
+    {
+        String xml = "<state><value><foo>bar</foo></value></state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar" ) );
+    }
+
+    @Test
+    public void canReadMultiLineXml()
+    {
+        String xml = "<state>\n<value>\n<foo>bar</foo>\n</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar" ) );
+    }
+
+    @Test
+    public void canReadIndentedMultiLineXml()
+    {
+        String xml = "<state>\n\t<value>\n\t\t<foo>bar</foo>\n\t</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar" ) );
+    }
+
+    @Test
+    public void canReadSingleLineXmlWithMultilineStringValue()
+    {
+        String xml = "<state><value><foo>bar\nbaz\n</foo></value></state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar\nbaz\n" ) );
+    }
+
+    @Test
+    public void canReadMultiLineXmlWithMultilineStringValue()
+    {
+        String xml = "<state>\n<value>\n<foo>bar\nbaz\n</foo>\n</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar\nbaz\n" ) );
+    }
+
+    @Test
+    public void canReadIndentedMultiLineXmlWithMultilineStringValue()
+    {
+        String xml = "<state>\n\t<value>\n\t\t<foo>bar\nbaz\n</foo>\n\t</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar\nbaz\n" ) );
+    }
+
+    @Test
+    public void canReadCommentedXml()
+    {
+        String xml = "<state><value><!-- Some comment --><foo>bar</foo></value></state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar" ) );
+    }
+
+    @Test
+    public void canReadMultilineCommentedXml()
+    {
+        String xml = "<state>\n<value>\n<!-- Some comment -->\n<foo>bar</foo>\n</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar" ) );
+    }
+
+    @Test
+    public void canReadIndentedMultilineCommentedXml()
+    {
+        String xml = "<state>\n\t<value>\n\t\t<!-- Some comment -->\n\t\t<foo>bar</foo>\n\t</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar" ) );
+    }
+
+    @Test
+    public void canReadIndentedMultilineCommentedXmlWithMultilineStringValue()
+    {
+        String xml = "<state>\n\t<value>\n\t\t<!-- Some comment -->\n\t\t<foo>bar\nbaz\n</foo>\n\t</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "bar\nbaz\n" ) );
+    }
+
+    @Test
+    public void canReadIndentedMultilineCommentedXmlWithTextValueStartingWithNewLine()
+    {
+        String xml
+            = "<state>\n\t<value>\n\t\t<!-- Some comment -->\n\t\t<foo>\n\t\t\tbar\n\t\t\tbaz\n</foo>\n\t</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(),
+                    equalTo( "\n\t\t\tbar\n\t\t\tbaz\n" ) );
+    }
+
+    @Test
+    public void canReadIndentedMultilineXmlWithNullValues()
+    {
+        String xml = "<state>\n\t<value>\n\t\t<foo>\n<null/>\n</foo>\n\t</value>\n</state>";
+        assertThat( deserializer.deserialize( module, SomeValue.class, xml ).foo().get(), nullValue() );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6552f230/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/JavaxXmlValueCompositeSerializationTest.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/JavaxXmlValueCompositeSerializationTest.java b/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/JavaxXmlValueCompositeSerializationTest.java
index dc910fc..5c5679f 100644
--- a/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/JavaxXmlValueCompositeSerializationTest.java
+++ b/extensions/serialization-javaxxml/src/test/java/org/apache/polygene/serialization/javaxxml/JavaxXmlValueCompositeSerializationTest.java
@@ -31,7 +31,6 @@ import static org.hamcrest.Matchers.equalTo;
 import static org.junit.Assert.assertThat;
 import static org.xmlunit.matchers.CompareMatcher.isSimilarTo;
 
-// TODO Assert deserialization from formatted XML, whitespaces are a problem ATM
 public class JavaxXmlValueCompositeSerializationTest extends AbstractValueCompositeSerializationTest
 {
     // START SNIPPET: assembly


[3/3] polygene-java git commit: JSON Serialization enhancements

Posted by pa...@apache.org.
JSON Serialization enhancements

Reuse JSON factories and transformers for performance reasons.
Allow to explicitly set JSON provider implementation during assembly.
Provide JsonBuilderFactory to adapters.
Ignore JSON comments by default when using Johnzon.


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

Branch: refs/heads/serialization-3.0
Commit: c9639a39053268d405b3b2fd065433a7bc1efa9f
Parents: 6552f23
Author: Paul Merlin <pa...@apache.org>
Authored: Sun Apr 2 18:35:58 2017 +0200
Committer: Paul Merlin <pa...@apache.org>
Committed: Sun Apr 2 18:48:00 2017 +0200

----------------------------------------------------------------------
 .../javaxjson/JavaxJsonAdapter.java             |   4 +-
 .../javaxjson/JavaxJsonAdapters.java            |  50 +++++---
 .../javaxjson/JavaxJsonDeserializer.java        | 109 ++++++++++++++--
 .../javaxjson/JavaxJsonFactories.java           | 127 +++++++++++++++++++
 .../javaxjson/JavaxJsonSerializer.java          |  77 ++++++++---
 .../javaxjson/JavaxJsonSettings.java            |  11 ++
 .../spi/serialization/JsonDeserializer.java     |  84 ------------
 .../spi/serialization/JsonSerializer.java       |  30 -----
 .../javaxjson/CustomJsonAdapterTest.java        |  17 ++-
 .../javaxjson/HandCraftedJsonTest.java          |   2 -
 10 files changed, 338 insertions(+), 173 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
index 99d5d80..9b17f37 100644
--- a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
@@ -19,6 +19,7 @@ package org.apache.polygene.serialization.javaxjson;
 
 import java.util.function.BiFunction;
 import java.util.function.Function;
+import javax.json.JsonBuilderFactory;
 import javax.json.JsonValue;
 import org.apache.polygene.api.type.ValueType;
 
@@ -37,11 +38,12 @@ public interface JavaxJsonAdapter<T>
     /**
      * Serialize.
      *
+     * @param builderFactory Factory to create JSON
      * @param object Object to serialize, never null
      * @param serialize Serialization function for nested structure serialization
      * @return Serialized JSON representation
      */
-    JsonValue serialize( Object object, Function<Object, JsonValue> serialize );
+    JsonValue serialize( JsonBuilderFactory builderFactory, Object object, Function<Object, JsonValue> serialize );
 
     /**
      * Deserialize.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/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 a6c7933..fdb3e53 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
@@ -21,7 +21,7 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.BiFunction;
 import java.util.function.Function;
-import javax.json.Json;
+import javax.json.JsonBuilderFactory;
 import javax.json.JsonNumber;
 import javax.json.JsonString;
 import javax.json.JsonValue;
@@ -112,7 +112,8 @@ public interface JavaxJsonAdapters
         private static abstract class ToJsonStringAdapter<T> implements JavaxJsonAdapter<T>
         {
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory, Object object,
+                                        Function<Object, JsonValue> serialize )
             {
                 return JavaxJson.toJsonString( object );
             }
@@ -149,7 +150,8 @@ public interface JavaxJsonAdapters
             public Class<Boolean> type() { return Boolean.class; }
 
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory, Object object,
+                                        Function<Object, JsonValue> serialize )
             {
                 return type().cast( object ) ? JsonValue.TRUE : JsonValue.FALSE;
             }
@@ -181,10 +183,11 @@ public interface JavaxJsonAdapters
             public Class<Integer> type() { return Integer.class; }
 
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                        Object object, Function<Object, JsonValue> serialize )
             {
-                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
-                           .getJsonNumber( "value" );
+                return builderFactory.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                                     .getJsonNumber( "value" );
             }
 
             @Override
@@ -211,10 +214,11 @@ public interface JavaxJsonAdapters
             public Class<Long> type() { return Long.class; }
 
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                        Object object, Function<Object, JsonValue> serialize )
             {
-                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build().getJsonNumber(
-                    "value" );
+                return builderFactory.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                                     .getJsonNumber( "value" );
             }
 
             @Override
@@ -241,10 +245,11 @@ public interface JavaxJsonAdapters
             public Class<Short> type() { return Short.class; }
 
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                        Object object, Function<Object, JsonValue> serialize )
             {
-                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
-                           .getJsonNumber( "value" );
+                return builderFactory.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                                     .getJsonNumber( "value" );
             }
 
             @Override
@@ -271,10 +276,11 @@ public interface JavaxJsonAdapters
             public Class<Byte> type() { return Byte.class; }
 
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                        Object object, Function<Object, JsonValue> serialize )
             {
-                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
-                           .getJsonNumber( "value" );
+                return builderFactory.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                                     .getJsonNumber( "value" );
             }
 
             @Override
@@ -301,10 +307,11 @@ public interface JavaxJsonAdapters
             public Class<Float> type() { return Float.class; }
 
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                        Object object, Function<Object, JsonValue> serialize )
             {
-                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
-                           .getJsonNumber( "value" );
+                return builderFactory.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                                     .getJsonNumber( "value" );
             }
 
             @Override
@@ -331,10 +338,11 @@ public interface JavaxJsonAdapters
             public Class<Double> type() { return Double.class; }
 
             @Override
-            public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+            public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                        Object object, Function<Object, JsonValue> serialize )
             {
-                return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
-                           .getJsonNumber( "value" );
+                return builderFactory.createObjectBuilder().add( "value", type().cast( object ) ).build()
+                                     .getJsonNumber( "value" );
             }
 
             @Override

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/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 43765c9..d1310d7 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,6 +17,11 @@
  */
 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,12 +36,16 @@ 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.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.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Initializable;
 import org.apache.polygene.api.property.PropertyDescriptor;
 import org.apache.polygene.api.serialization.Converter;
 import org.apache.polygene.api.serialization.Converters;
@@ -57,6 +66,7 @@ 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;
@@ -64,9 +74,13 @@ import static org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonA
 import static org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonObject;
 import static org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonStructure;
 
-public class JavaxJsonDeserializer extends AbstractTextDeserializer implements JsonDeserializer
+public class JavaxJsonDeserializer extends AbstractTextDeserializer
+    implements JsonDeserializer, Initializable
 {
     @This
+    private JavaxJsonFactories jsonFactories;
+
+    @This
     private Converters converters;
 
     @This
@@ -75,6 +89,88 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer implements J
     @Uses
     private ServiceDescriptor descriptor;
 
+    private JavaxJsonSettings settings;
+
+    @Override
+    public void initialize() throws Exception
+    {
+        settings = JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) );
+    }
+
+    @Override
+    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 ->
+        {
+            // 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 );
+                }
+            }
+        }
+        catch( JsonParsingException ex )
+        {
+            return outOfStructureFunction.apply( stateString );
+        }
+        // Empty state string?
+        return fromJson( module, valueType, JavaxJson.EMPTY_STRING );
+    }
+
     @Override
     public <T> T fromJson( ModuleDescriptor module, ValueType valueType, JsonValue state )
     {
@@ -148,7 +244,8 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer implements J
         {
             case OBJECT:
                 JsonObject object = (JsonObject) json;
-                String typeInfo = object.getString( getTypeInfoPropertyName(), valueType.primaryType().getName() );
+                String typeInfo = object.getString( settings.getTypeInfoPropertyName(),
+                                                    valueType.primaryType().getName() );
                 ValueDescriptor valueDescriptor = module.valueDescriptor( typeInfo );
                 if( valueDescriptor != null )
                 {
@@ -206,7 +303,7 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer implements J
 
     private Object deserializeValueComposite( ModuleDescriptor module, ValueCompositeType valueType, JsonObject json )
     {
-        String typeInfoName = getTypeInfoPropertyName();
+        String typeInfoName = settings.getTypeInfoPropertyName();
         String typeInfo = json.getString( typeInfoName, null );
         if( typeInfo != null )
         {
@@ -284,10 +381,4 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer implements J
             return map == null ? Stream.empty() : map.entrySet().stream();
         };
     }
-
-    private String getTypeInfoPropertyName()
-    {
-        return JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) )
-                                .getTypeInfoPropertyName();
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/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
new file mode 100644
index 0000000..e61e3e6
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonFactories.java
@@ -0,0 +1,127 @@
+/*
+ *  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.polygene.serialization.javaxjson;
+
+import java.util.Collections;
+import java.util.Map;
+import javax.json.JsonBuilderFactory;
+import javax.json.JsonException;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonWriterFactory;
+import javax.json.spi.JsonProvider;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParserFactory;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Initializable;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.service.ServiceDescriptor;
+
+@Mixins( JavaxJsonFactories.Mixin.class )
+public interface JavaxJsonFactories
+{
+    JsonParserFactory parserFactory();
+
+    JsonReaderFactory readerFactory();
+
+    JsonGeneratorFactory generatorFactory();
+
+    JsonBuilderFactory builderFactory();
+
+    JsonWriterFactory writerFactory();
+
+    class Mixin implements JavaxJsonFactories, Initializable
+    {
+        @Uses
+        private ServiceDescriptor descriptor;
+
+        private JsonParserFactory parserFactory;
+        private JsonReaderFactory readerFactory;
+        private JsonGeneratorFactory generatorFactory;
+        private JsonBuilderFactory builderFactory;
+        private JsonWriterFactory writerFactory;
+
+        @Override
+        public void initialize() throws Exception
+        {
+            JavaxJsonSettings settings = JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) );
+
+            String jsonProviderClassName = settings.getJsonProviderClassName();
+            JsonProvider jsonProvider;
+            if( jsonProviderClassName == null )
+            {
+                jsonProvider = JsonProvider.provider();
+            }
+            else
+            {
+                try
+                {
+                    Class<?> clazz = Class.forName( jsonProviderClassName );
+                    jsonProvider = (JsonProvider) clazz.newInstance();
+                }
+                catch( ClassNotFoundException ex )
+                {
+                    throw new JsonException( "Provider " + jsonProviderClassName + " not found", ex );
+                }
+                catch( Exception ex )
+                {
+                    throw new JsonException( "Provider " + jsonProviderClassName + " could not be instantiated", ex );
+                }
+            }
+
+            Map<String, ?> parserProperties = Collections.singletonMap( "org.apache.johnzon.supports-comments", true );
+            parserFactory = jsonProvider.createParserFactory( parserProperties );
+            readerFactory = jsonProvider.createReaderFactory( parserProperties );
+
+            Map<String, ?> generatorProperties = Collections.singletonMap( JsonGenerator.PRETTY_PRINTING, false );
+            generatorFactory = jsonProvider.createGeneratorFactory( generatorProperties );
+            builderFactory = jsonProvider.createBuilderFactory( generatorProperties );
+            writerFactory = jsonProvider.createWriterFactory( generatorProperties );
+        }
+
+        @Override
+        public JsonParserFactory parserFactory()
+        {
+            return parserFactory;
+        }
+
+        @Override
+        public JsonReaderFactory readerFactory()
+        {
+            return readerFactory;
+        }
+
+        @Override
+        public JsonGeneratorFactory generatorFactory()
+        {
+            return generatorFactory;
+        }
+
+        @Override
+        public JsonBuilderFactory builderFactory()
+        {
+            return builderFactory;
+        }
+
+        @Override
+        public JsonWriterFactory writerFactory()
+        {
+            return writerFactory;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/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 3bf8e1e..dcc2db8 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
@@ -17,23 +17,28 @@
  */
 package org.apache.polygene.serialization.javaxjson;
 
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.io.Writer;
 import java.util.Base64;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
 import javax.json.JsonValue;
 import org.apache.polygene.api.PolygeneAPI;
 import org.apache.polygene.api.association.AssociationStateHolder;
+import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.composite.CompositeInstance;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Initializable;
 import org.apache.polygene.api.serialization.Converter;
 import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.service.ServiceDescriptor;
@@ -51,9 +56,13 @@ import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.stream.Collectors.toList;
 import static org.apache.polygene.api.util.Collectors.toMap;
 
-public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonSerializer
+public class JavaxJsonSerializer extends AbstractTextSerializer
+    implements JsonSerializer, Initializable
 {
     @This
+    private JavaxJsonFactories jsonFactories;
+
+    @This
     private Converters converters;
 
     @This
@@ -62,6 +71,41 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
     @Uses
     private ServiceDescriptor descriptor;
 
+    private JavaxJsonSettings settings;
+
+    @Override
+    public void initialize() throws Exception
+    {
+        settings = JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) );
+    }
+
+    @Override
+    public void serialize( Options options, Writer writer, @Optional Object object )
+    {
+        JsonValue jsonValue = toJson( options, object );
+        if( jsonValue == null )
+        {
+            return;
+        }
+        try
+        {
+            // We want plain Strings to be serialized without quotes which is non JSON compliant
+            // See https://java.net/jira/browse/JSON_PROCESSING_SPEC-65
+            if( jsonValue.getValueType() == JsonValue.ValueType.STRING )
+            {
+                writer.write( ( (JsonString) jsonValue ).getString() );
+            }
+            else
+            {
+                writer.write( jsonValue.toString() );
+            }
+        }
+        catch( IOException ex )
+        {
+            throw new UncheckedIOException( ex );
+        }
+    }
+
     @Override
     public <T> Function<T, JsonValue> toJsonFunction( Options options )
     {
@@ -83,7 +127,8 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
         JavaxJsonAdapter<?> adapter = adapters.adapterFor( objectClass );
         if( adapter != null )
         {
-            return adapter.serialize( object, obj -> doSerialize( options, obj, false ) );
+            return adapter.serialize( jsonFactories.builderFactory(), object,
+                                      obj -> doSerialize( options, obj, false ) );
         }
         if( ValueCompositeType.isValueComposite( objectClass ) )
         {
@@ -117,7 +162,7 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
         AssociationStateHolder state = (AssociationStateHolder) instance.state();
         ValueCompositeType valueType = descriptor.valueType();
 
-        JsonObjectBuilder builder = Json.createObjectBuilder();
+        JsonObjectBuilder builder = jsonFactories.builderFactory().createObjectBuilder();
         valueType.properties().forEach(
             property -> builder.add(
                 property.qualifiedName().name(),
@@ -148,7 +193,7 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
 
     private JsonObjectBuilder withTypeInfo( JsonObjectBuilder builder, ValueType valueType )
     {
-        return builder.add( getTypeInfoPropertyName(), valueType.primaryType().getName() );
+        return builder.add( settings.getTypeInfoPropertyName(), valueType.primaryType().getName() );
     }
 
     /**
@@ -163,26 +208,26 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
         if( map.isEmpty() )
         {
             // Defaults to {}
-            return Json.createObjectBuilder().build();
+            return jsonFactories.builderFactory().createObjectBuilder().build();
         }
         Predicate<Object> characterKeyPredicate = key ->
             key != null && ( key instanceof CharSequence || key instanceof Character );
         if( map.keySet().stream().allMatch( characterKeyPredicate ) )
         {
-            JsonObjectBuilder builder = Json.createObjectBuilder();
+            JsonObjectBuilder builder = jsonFactories.builderFactory().createObjectBuilder();
             map.entrySet().forEach( entry -> builder.add( entry.getKey().toString(),
                                                           doSerialize( options, entry.getValue(), false ) ) );
             return builder.build();
         }
         else
         {
-            JsonArrayBuilder builder = Json.createArrayBuilder();
+            JsonArrayBuilder builder = jsonFactories.builderFactory().createArrayBuilder();
             map.entrySet().forEach(
                 entry -> builder.add(
-                    Json.createObjectBuilder()
-                        .add( "key", doSerialize( options, entry.getKey(), false ) )
-                        .add( "value", doSerialize( options, entry.getValue(), false ) )
-                        .build() ) );
+                    jsonFactories.builderFactory().createObjectBuilder()
+                                 .add( "key", doSerialize( options, entry.getKey(), false ) )
+                                 .add( "value", doSerialize( options, entry.getValue(), false ) )
+                                 .build() ) );
             return builder.build();
         }
     }
@@ -209,14 +254,8 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
 
     private <T> JsonArray serializeStream( Options options, Stream<?> stream )
     {
-        JsonArrayBuilder builder = Json.createArrayBuilder();
+        JsonArrayBuilder builder = jsonFactories.builderFactory().createArrayBuilder();
         stream.forEach( element -> builder.add( doSerialize( options, element, false ) ) );
         return builder.build();
     }
-
-    private String getTypeInfoPropertyName()
-    {
-        return JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) )
-                                .getTypeInfoPropertyName();
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSettings.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSettings.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSettings.java
index 7042638..de5c27f 100644
--- a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSettings.java
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSettings.java
@@ -31,6 +31,7 @@ public class JavaxJsonSettings extends SerializationSettings<JavaxJsonSettings>
         return settings != null ? settings : DEFAULT;
     }
 
+    private String jsonProviderClassName;
     private String typeInfoPropertyName;
     private Map<ValueType, JavaxJsonAdapter<?>> adapters;
 
@@ -40,6 +41,16 @@ public class JavaxJsonSettings extends SerializationSettings<JavaxJsonSettings>
         adapters = new LinkedHashMap<>();
     }
 
+    public String getJsonProviderClassName()
+    {
+        return jsonProviderClassName;
+    }
+
+    public void setJsonProviderClassName( String jsonProviderClassName )
+    {
+        this.jsonProviderClassName = jsonProviderClassName;
+    }
+
     public String getTypeInfoPropertyName()
     {
         return typeInfoPropertyName;

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
index 30060ef..fdec10c 100644
--- a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
@@ -17,28 +17,15 @@
  */
 package org.apache.polygene.spi.serialization;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.UncheckedIOException;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
 import javax.json.JsonValue;
-import javax.json.stream.JsonParser;
-import javax.json.stream.JsonParsingException;
 import org.apache.polygene.api.serialization.Deserializer;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.type.ValueType;
-import org.apache.polygene.serialization.javaxjson.JavaxJson;
 import org.apache.polygene.spi.module.ModuleSpi;
 
-import static java.util.stream.Collectors.joining;
-
 /**
  * {@literal javax.json} deserializer.
  */
@@ -92,75 +79,4 @@ public interface JsonDeserializer extends Deserializer
     {
         return fromJsonEach( module, valueType, Stream.of( states ) );
     }
-
-    @Override
-    default <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 = Json.createReader( new StringReader( poorMans ) ).readObject();
-            JsonValue value = poorMansJson.get( "value" );
-            return fromJson( module, valueType, value );
-        };
-        Function<String, T> outOfStructureFunction = string ->
-        {
-            // Is this an unquoted plain value?
-            try
-            {
-                return plainValueFunction.apply( '"' + string + '"' );
-            }
-            catch( JsonParsingException ex )
-            {
-                return plainValueFunction.apply( string );
-            }
-        };
-        try( JsonParser parser = Json.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 = Json.createReader( new StringReader( stateString ) ) )
-                        {
-                            return fromJson( module, valueType, reader.read() );
-                        }
-                    default:
-                        // JSON Value out of structure
-                        return outOfStructureFunction.apply( stateString );
-                }
-            }
-        }
-        catch( JsonParsingException ex )
-        {
-            return outOfStructureFunction.apply( stateString );
-        }
-        // Empty state string?
-        return fromJson( module, valueType, JavaxJson.EMPTY_STRING );
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
index 9ec1863..956b591 100644
--- a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
+++ b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
@@ -17,13 +17,9 @@
  */
 package org.apache.polygene.spi.serialization;
 
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.io.Writer;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import javax.json.JsonString;
 import javax.json.JsonValue;
 import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.serialization.Serializer;
@@ -79,30 +75,4 @@ public interface JsonSerializer extends Serializer
     {
         return toJsonEach( Options.DEFAULT, Stream.of( objects ) );
     }
-
-    default void serialize( Options options, Writer writer, @Optional Object object )
-    {
-        JsonValue jsonValue = toJson( options, object );
-        if( jsonValue == null )
-        {
-            return;
-        }
-        try
-        {
-            // We want plain Strings to be serialized without quotes which is non JSON compliant
-            // See https://java.net/jira/browse/JSON_PROCESSING_SPEC-65
-            if( jsonValue.getValueType() == JsonValue.ValueType.STRING )
-            {
-                writer.write( ( (JsonString) jsonValue ).getString() );
-            }
-            else
-            {
-                writer.write( jsonValue.toString() );
-            }
-        }
-        catch( IOException ex )
-        {
-            throw new UncheckedIOException( ex );
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/CustomJsonAdapterTest.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/CustomJsonAdapterTest.java b/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/CustomJsonAdapterTest.java
index c03c3a8..57ad62b 100644
--- a/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/CustomJsonAdapterTest.java
+++ b/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/CustomJsonAdapterTest.java
@@ -20,7 +20,7 @@ package org.apache.polygene.serialization.javaxjson;
 import java.time.LocalDate;
 import java.util.function.BiFunction;
 import java.util.function.Function;
-import javax.json.Json;
+import javax.json.JsonBuilderFactory;
 import javax.json.JsonObject;
 import javax.json.JsonString;
 import javax.json.JsonValue;
@@ -86,8 +86,10 @@ public class CustomJsonAdapterTest extends AbstractPolygeneTest
         public Class<CustomValue> type() { return CustomValue.class; }
 
         @Override
-        public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+        public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                    Object object, Function<Object, JsonValue> serialize )
         {
+            // TODO FUCK JSON
             return JavaxJson.toJsonString( type().cast( object ).state );
         }
 
@@ -110,13 +112,14 @@ public class CustomJsonAdapterTest extends AbstractPolygeneTest
         public Class<CustomStructure> type() { return CustomStructure.class; }
 
         @Override
-        public JsonValue serialize( Object object, Function<Object, JsonValue> serialize )
+        public JsonValue serialize( JsonBuilderFactory builderFactory,
+                                    Object object, Function<Object, JsonValue> serialize )
         {
             CustomStructure customStructure = type().cast( object );
-            return Json.createObjectBuilder()
-                       .add( "foo", customStructure.foo )
-                       .add( "bar", serialize.apply( customStructure.bar ) )
-                       .build();
+            return builderFactory.createObjectBuilder()
+                                 .add( "foo", customStructure.foo )
+                                 .add( "bar", serialize.apply( customStructure.bar ) )
+                                 .build();
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9639a39/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/HandCraftedJsonTest.java
----------------------------------------------------------------------
diff --git a/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/HandCraftedJsonTest.java b/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/HandCraftedJsonTest.java
index 2181b6b..18ad8ff 100644
--- a/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/HandCraftedJsonTest.java
+++ b/extensions/serialization-javaxjson/src/test/java/org/apache/polygene/serialization/javaxjson/HandCraftedJsonTest.java
@@ -63,8 +63,6 @@ public class HandCraftedJsonTest extends AbstractPolygeneTest
     }
 
     @Test
-    @NotYetImplemented( reason = "need to manage javax.json providers and properties first, could work with Johnzon" )
-    // See org.apache.johnzon.supports-comments
     public void canReadCommentedJson()
     {
         String json = "// One comment\n {  \n\t\"foo\"  :  \"bar\"  \n/* Two comments */ }\n  ";