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/03/13 10:35:24 UTC
[32/50] [abbrv] polygene-java git commit: New (de)serialization API
and SPI & new implementations
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
index 116e82c..fc4937a 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/mixin/JDKMixinTest.java
@@ -26,6 +26,9 @@ import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
import org.apache.polygene.api.common.Visibility;
import org.apache.polygene.api.concern.Concerns;
import org.apache.polygene.api.concern.GenericConcern;
@@ -36,7 +39,6 @@ import org.apache.polygene.api.service.ServiceReference;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.test.AbstractPolygeneTest;
-import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
@@ -46,56 +48,46 @@ import static org.junit.Assert.assertThat;
/**
* Assert that JDK classes are usable as Mixins.
*/
-public class JDKMixinTest
- extends AbstractPolygeneTest
+public class JDKMixinTest extends AbstractPolygeneTest
{
-
@Concerns( JDKMixinConcern.class )
- public interface JSONSerializableMap
- extends Map<String, String>
+ public interface JSONSerializableMap extends Map<String, String>
{
-
- JSONObject toJSON();
-
+ JsonObject toJSON();
}
@SuppressWarnings( "serial" )
- public static class ExtendsJDKMixin
- extends HashMap<String, String>
+ public static class ExtendsJDKMixin extends HashMap<String, String>
implements JSONSerializableMap
{
-
@Override
- public JSONObject toJSON()
+ public JsonObject toJSON()
{
System.out.println( ">>>> Call ExtendsJDKMixin.toJSON()" );
- // Copy the Map before handing it to JSONObject so that the JSONObject do not use the Composite
- return new JSONObject( new HashMap<String, String>( this ) );
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ entrySet().forEach( entry -> builder.add( entry.getKey(), entry.getValue() ) );
+ return builder.build();
}
-
}
public static abstract class ComposeWithJDKMixin
implements JSONSerializableMap
{
-
@This
private Map<String, String> map;
@Override
- public JSONObject toJSON()
+ public JsonObject toJSON()
{
System.out.println( ">>>> Call ComposeWithJDKMixin.toJSON()" );
- // Copy the Map before handing it to JSONObject so that the JSONObject do not use the Composite
- return new JSONObject( new HashMap<String, String>( map ) );
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ map.entrySet().forEach( entry -> builder.add( entry.getKey(), entry.getValue() ) );
+ return builder.build();
}
-
}
- public static class JDKMixinConcern
- extends GenericConcern
+ public static class JDKMixinConcern extends GenericConcern
{
-
@Override
public Object invoke( Object proxy, Method method, Object[] args )
throws Throwable
@@ -104,13 +96,14 @@ public class JDKMixinTest
CONCERN_RECORDS.add( method.getName() );
return next.invoke( proxy, method, args );
}
-
}
private static final Identity EXTENDS_IDENTITY = new StringIdentity( ExtendsJDKMixin.class.getName() );
private static final Identity COMPOSE_IDENTITY = new StringIdentity( ComposeWithJDKMixin.class.getName() );
- private static final Predicate<ServiceReference<?>> EXTENDS_IDENTITY_SPEC = new ServiceIdentitySpec( EXTENDS_IDENTITY );
- private static final Predicate<ServiceReference<?>> COMPOSE_IDENTITY_SPEC = new ServiceIdentitySpec( COMPOSE_IDENTITY );
+ private static final Predicate<ServiceReference<?>> EXTENDS_IDENTITY_SPEC = new ServiceIdentitySpec(
+ EXTENDS_IDENTITY );
+ private static final Predicate<ServiceReference<?>> COMPOSE_IDENTITY_SPEC = new ServiceIdentitySpec(
+ COMPOSE_IDENTITY );
private static final List<String> CONCERN_RECORDS = new ArrayList<String>();
@Before
@@ -123,16 +116,16 @@ public class JDKMixinTest
public void assemble( ModuleAssembly module )
throws AssemblyException
{
- module.services( JSONSerializableMap.class ).
- identifiedBy( EXTENDS_IDENTITY.toString() ).
- withMixins( ExtendsJDKMixin.class ).
- instantiateOnStartup();
-
- module.layer().module( "compose" ).services( JSONSerializableMap.class ).
- visibleIn( Visibility.layer ).
- identifiedBy( COMPOSE_IDENTITY.toString() ).
- withMixins( HashMap.class, ComposeWithJDKMixin.class ).
- instantiateOnStartup();
+ module.services( JSONSerializableMap.class )
+ .identifiedBy( EXTENDS_IDENTITY.toString() )
+ .withMixins( ExtendsJDKMixin.class )
+ .instantiateOnStartup();
+
+ module.layer().module( "compose" ).services( JSONSerializableMap.class )
+ .visibleIn( Visibility.layer )
+ .identifiedBy( COMPOSE_IDENTITY.toString() )
+ .withMixins( HashMap.class, ComposeWithJDKMixin.class )
+ .instantiateOnStartup();
}
@Test
@@ -147,12 +140,12 @@ public class JDKMixinTest
JSONSerializableMap extending = services.get( 0 ).get();
extending.put( "foo", "bar" ); // Concern trigger #1 (put)
- JSONObject json = extending.toJSON(); // Concern trigger #2, #3 and #4 (toJSON, size, entrySet)
+ JsonObject json = extending.toJSON(); // Concern trigger #2 and #3 (toJSON, entrySet)
- assertThat( json.length(), equalTo( 1 ) );
- assertThat( json.optString( "foo" ), equalTo( "bar" ) );
+ assertThat( json.size(), equalTo( 1 ) );
+ assertThat( json.getString( "foo" ), equalTo( "bar" ) );
- assertThat( CONCERN_RECORDS.size(), equalTo( 4 ) );
+ assertThat( CONCERN_RECORDS.size(), equalTo( 3 ) );
}
@Test
@@ -167,21 +160,20 @@ public class JDKMixinTest
JSONSerializableMap composing = services.get( 0 ).get();
composing.put( "foo", "bar" ); // Concern trigger #1 (put)
- JSONObject json = composing.toJSON(); // Concern trigger #2, #3 and #4 (toJSON, size, entrySet)
+ JsonObject json = composing.toJSON(); // Concern trigger #2 and #3 (toJSON, entrySet)
- assertThat( json.length(), equalTo( 1 ) );
- assertThat( json.optString( "foo" ), equalTo( "bar" ) );
+ assertThat( json.size(), equalTo( 1 ) );
+ assertThat( json.getString( "foo" ), equalTo( "bar" ) );
- assertThat( CONCERN_RECORDS.size(), equalTo( 4 ) );
+ assertThat( CONCERN_RECORDS.size(), equalTo( 3 ) );
}
private static class ServiceIdentitySpec
implements Predicate<ServiceReference<?>>
{
-
private final Identity identity;
- ServiceIdentitySpec(Identity identity)
+ ServiceIdentitySpec( Identity identity )
{
this.identity = identity;
}
@@ -191,7 +183,5 @@ public class JDKMixinTest
{
return item.identity().equals( identity );
}
-
}
-
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
index caad29d..026cb13 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/property/ValueNestedBuilderTest.java
@@ -30,13 +30,11 @@ import org.apache.polygene.api.value.ValueComposite;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
import org.junit.Test;
public class ValueNestedBuilderTest
extends AbstractPolygeneTest
{
-
private interface InnerValue
extends ValueComposite
{
@@ -75,7 +73,6 @@ public class ValueNestedBuilderTest
public void assemble( ModuleAssembly module )
throws AssemblyException
{
- module.services( OrgJsonValueSerializationService.class );
module.values( InnerValue.class, InnerDefaultedValue.class, OuterValue.class, OuterDefaultedValue.class );
}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
index 370883f..18b6935 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/AssociationToValueTest.java
@@ -35,12 +35,10 @@ import org.apache.polygene.api.unitofwork.UnitOfWork;
import org.apache.polygene.api.unitofwork.UnitOfWorkFactory;
import org.apache.polygene.api.unitofwork.concern.UnitOfWorkConcern;
import org.apache.polygene.api.unitofwork.concern.UnitOfWorkPropagation;
-import org.apache.polygene.api.value.ValueSerialization;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
import org.junit.Test;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
@@ -102,7 +100,6 @@ public class AssociationToValueTest extends AbstractPolygeneTest
module.entities( Person.class );
module.values( Person.class );
module.services( PersonRepository.class ).withConcerns( UnitOfWorkConcern.class );
- module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
module.services( MemoryEntityStoreService.class );
module.services( Runnable.class )
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
index 55196cb..45859de 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/NestedValueBuilderTest.java
@@ -23,8 +23,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
-import org.junit.Test;
import org.apache.polygene.api.common.UseDefaults;
import org.apache.polygene.api.property.Property;
import org.apache.polygene.api.value.ValueBuilder;
@@ -32,6 +30,7 @@ import org.apache.polygene.api.value.ValueComposite;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
import static org.junit.Assert.fail;
@@ -78,7 +77,6 @@ public class NestedValueBuilderTest
public void assemble( ModuleAssembly module )
throws AssemblyException
{
- module.services( OrgJsonValueSerializationService.class );
module.values( InnerValue.class, InnerDefaultedValue.class, OuterValue.class, OuterDefaultedValue.class );
}
@@ -87,8 +85,8 @@ public class NestedValueBuilderTest
{
ValueBuilder<InnerValue> innerBuilder = valueBuilderFactory.newValueBuilder( InnerValue.class );
InnerValue inner = innerBuilder.prototype();
- inner.listProp().set( new ArrayList<String>() );
- inner.mapProp().set( new HashMap<String, String>() );
+ inner.listProp().set( new ArrayList<>() );
+ inner.mapProp().set( new HashMap<>() );
inner = innerBuilder.newInstance();
// If we reach this point, value creation went well
try
@@ -116,12 +114,12 @@ public class NestedValueBuilderTest
{
ValueBuilder<InnerValue> innerBuilder = valueBuilderFactory.newValueBuilder( InnerValue.class );
InnerValue innerPrototype = innerBuilder.prototype();
- innerPrototype.listProp().set( new ArrayList<String>() );
- innerPrototype.mapProp().set( new HashMap<String, String>() );
+ innerPrototype.listProp().set( new ArrayList<>() );
+ innerPrototype.mapProp().set( new HashMap<>() );
InnerValue innerInstance = innerBuilder.newInstance();
ValueBuilder<OuterValue> outerBuilder = valueBuilderFactory.newValueBuilder( OuterValue.class );
OuterValue outerPrototype = outerBuilder.prototype();
- List<InnerValue> inners = new ArrayList<InnerValue>();
+ List<InnerValue> inners = new ArrayList<>();
inners.add( innerInstance );
outerPrototype.innerListProp().set( inners );
OuterValue outerInstance = outerBuilder.newInstance();
@@ -171,7 +169,7 @@ public class NestedValueBuilderTest
InnerDefaultedValue innerInstance = innerBuilder.newInstance();
ValueBuilder<OuterDefaultedValue> outerBuilder = valueBuilderFactory.newValueBuilder( OuterDefaultedValue.class );
OuterDefaultedValue outerPrototype = outerBuilder.prototype();
- List<InnerDefaultedValue> inners = new ArrayList<InnerDefaultedValue>();
+ List<InnerDefaultedValue> inners = new ArrayList<>();
inners.add( innerInstance );
outerPrototype.innerListPropDefault().set( inners );
OuterDefaultedValue outerInstance = outerBuilder.newInstance();
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
index 2ad6db4..bc538f1 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueCompositeBasicsTest.java
@@ -19,15 +19,14 @@
*/
package org.apache.polygene.runtime.value;
-import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
-import org.junit.Test;
import org.apache.polygene.api.injection.scope.This;
import org.apache.polygene.api.mixin.Mixins;
import org.apache.polygene.api.property.Property;
import org.apache.polygene.api.value.ValueBuilder;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -39,7 +38,6 @@ public class ValueCompositeBasicsTest
public void assemble( ModuleAssembly module )
throws AssemblyException
{
- module.services( OrgJsonValueSerializationService.class );
module.values( SomeValue.class );
}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
index 5143909..fe8cdd8 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueSerializationRegressionTest.java
@@ -19,21 +19,19 @@
*/
package org.apache.polygene.runtime.value;
-import org.apache.polygene.api.identity.HasIdentity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.junit.Test;
import org.apache.polygene.api.association.Association;
import org.apache.polygene.api.association.ManyAssociation;
import org.apache.polygene.api.association.NamedAssociation;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.StringIdentity;
import org.apache.polygene.api.property.Property;
import org.apache.polygene.api.unitofwork.UnitOfWorkCompletionException;
import org.apache.polygene.api.value.ValueBuilder;
-import org.apache.polygene.api.value.ValueSerialization;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
+import org.junit.Test;
public class ValueSerializationRegressionTest extends AbstractPolygeneTest
{
@@ -45,7 +43,6 @@ public class ValueSerializationRegressionTest extends AbstractPolygeneTest
module.entities( DualFaced.class );
module.values( DualFaced.class );
module.services( MemoryEntityStoreService.class );
- module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
}
@Test
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
index 175e116..4441a76 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/value/ValueWithAssociationTest.java
@@ -19,10 +19,6 @@
*/
package org.apache.polygene.runtime.value;
-import org.apache.polygene.api.identity.HasIdentity;
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.junit.Test;
import org.apache.polygene.api.association.Association;
import org.apache.polygene.api.association.AssociationStateHolder;
import org.apache.polygene.api.association.ManyAssociation;
@@ -31,16 +27,18 @@ import org.apache.polygene.api.common.Optional;
import org.apache.polygene.api.entity.EntityBuilder;
import org.apache.polygene.api.entity.EntityComposite;
import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.identity.StringIdentity;
import org.apache.polygene.api.property.Property;
import org.apache.polygene.api.unitofwork.UnitOfWork;
import org.apache.polygene.api.unitofwork.UnitOfWorkCompletionException;
import org.apache.polygene.api.value.ValueBuilder;
-import org.apache.polygene.api.value.ValueSerialization;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
+import org.junit.Test;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
@@ -56,7 +54,6 @@ public class ValueWithAssociationTest extends AbstractPolygeneTest
module.values( SimpleName.class );
module.values( DualFaced.class );
module.services( MemoryEntityStoreService.class );
- module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
}
@Test
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java b/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
index b7dfe66..66c4bc8 100644
--- a/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/runtime/visibility/VisibilityInUnitOfWorkTest.java
@@ -30,7 +30,6 @@ import org.apache.polygene.api.structure.Application;
import org.apache.polygene.api.structure.Module;
import org.apache.polygene.api.unitofwork.UnitOfWork;
import org.apache.polygene.api.unitofwork.UnitOfWorkFactory;
-import org.apache.polygene.api.value.ValueSerialization;
import org.apache.polygene.bootstrap.ApplicationAssembly;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.Energy4Java;
@@ -38,7 +37,6 @@ import org.apache.polygene.bootstrap.LayerAssembly;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
import org.junit.Test;
public class VisibilityInUnitOfWorkTest
@@ -155,9 +153,6 @@ public class VisibilityInUnitOfWorkTest
yourModule.services( YourService.class ).visibleIn( Visibility.layer );
new DefaultUnitOfWorkAssembler().assemble( yourModule );
infraModule.services( MemoryEntityStoreService.class ).visibleIn( Visibility.layer );
- infraModule.services( OrgJsonValueSerializationService.class )
- .visibleIn( Visibility.layer )
- .taggedWith( ValueSerialization.Formats.JSON );
new DefaultUnitOfWorkAssembler().assemble( infraModule );
return appAssembly;
} );
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java b/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
index ce4b878..25c4a1b 100644
--- a/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
+++ b/core/runtime/src/test/java/org/apache/polygene/test/performance/entitystore/memory/MemoryEntityStoreTest.java
@@ -20,14 +20,12 @@
package org.apache.polygene.test.performance.entitystore.memory;
-import org.apache.polygene.api.value.ValueSerialization;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
import org.apache.polygene.spi.entity.EntityState;
import org.apache.polygene.spi.entitystore.StateChangeListener;
import org.apache.polygene.test.entity.AbstractEntityStoreTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
import static org.apache.polygene.bootstrap.ImportedServiceDeclaration.NEW_OBJECT;
@@ -44,7 +42,6 @@ public class MemoryEntityStoreTest
super.assemble( module );
module.services( MemoryEntityStoreService.class );
- module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
module.importedServices( StatePrinter.class ).importedBy( NEW_OBJECT );
module.objects( StatePrinter.class );
}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/build.gradle
----------------------------------------------------------------------
diff --git a/core/spi/build.gradle b/core/spi/build.gradle
index b6240e9..605d3c7 100644
--- a/core/spi/build.gradle
+++ b/core/spi/build.gradle
@@ -24,7 +24,9 @@ jar { manifest { name = "Apache Polygene\u2122 Core SPI" } }
dependencies {
api polygene.core.api
- api libraries.org_json
+ api libraries.javax_json
+
+ runtimeOnly libraries.johnzon
testImplementation polygene.core.testsupport
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/docs/serialization.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/serialization.txt b/core/spi/src/docs/serialization.txt
new file mode 100644
index 0000000..dca8955
--- /dev/null
+++ b/core/spi/src/docs/serialization.txt
@@ -0,0 +1,83 @@
+///////////////////////////////////////////////////////////////
+ * 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.
+///////////////////////////////////////////////////////////////
+
+[[core-spi-serialization,Serialization SPI]]
+= Serialization SPI =
+
+== Overview ==
+
+The Polygene\u2122 Core Runtime use Serialization to provide string representation of ValueComposites via their `toString()`
+method, and, their instantiation from the very same representation via the `newValueFromSerializedState(..)` method of
+the ValueBuilderFactory API.
+
+In each Module, if no Serialization service is assembled, a default one supporting the JSON format is used.
+
+// TODO Add sample usage of the Serialization service
+
+== Implementation notes ==
+
+Simply implement Serialization to create an extension for the Serialization SPI.
+The Core SPI module provides adapters to create pull-parsing capable Serializers and pull-parsing and tree-parsing
+capable Deserializers.
+
+The behaviour described here apply to all Serialization services implemented using the Core SPI adapters. Note that
+nothing stops you from implementing an extension for the Serialization SPI without relying on theses adapters.
+
+Theses adapters are tailored for serialization mechanisms that support the following two structures that can be nested:
+
+ * a collection of name/value pairs. In various languages, this is realized as an object, record, struct,
+ dictionary, hash table, keyed list, or associative array,
+ * an ordered list of values. In most languages, this is realized as an array, vector, list, or sequence ;
+
+in other words, a JSON-like structure.
+
+Special attention is taken when dealing with Maps. They are serialized as an ordered list of collections of
+name/value pairs to keep the Map order for least surprise. That way, even when the underlying serialization mechanism
+do not keep the collection of name/value pairs order we can rely on it being kept.
+
+Here is a sample Map with two entries in JSON notation to make things clear:
+
+[source,javascript]
+----
+[
+ { "key": "foo", "value": "bar" },
+ { "key": "cathedral", "value": "bazar" }
+]
+----
+
+Among Plain Values (see the <<core-api-value,Serialization API>> section) some are considered primitives to
+underlying serialization mechanisms and by so handed/come without conversion to/from implementations.
+
+Primitive values can be one of:
+
+ * String,
+ * Boolean or boolean,
+ * Integer or int,
+ * Long or long,
+ * Short or short,
+ * Byte or byte,
+ * Float or float,
+ * Double or double.
+
+Serialization is always done in a streaming manner using a pull-parsing based approach.
+
+Deserialization is done in a streaming manner using a pull-parsing based approach except when encountering a
+ValueComposite. ValueComposite types are deserialized using a tree-parsing based approach.
+
+All this means that you can serialize and deserialize large collections of values without filling the heap.
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/docs/spi.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/spi.txt b/core/spi/src/docs/spi.txt
index 3980412..9371827 100644
--- a/core/spi/src/docs/spi.txt
+++ b/core/spi/src/docs/spi.txt
@@ -32,7 +32,7 @@ include::../../build/docs/buildinfo/artifact.txt[]
There are currently 5 Core SPI extensions;
- * <<core-spi-valueserialization>>
+ * <<core-spi-serialization>>
* <<core-spi-entitystore>>
* <<core-spi-cache>>
* <<core-spi-indexing>>
@@ -45,7 +45,7 @@ can be solved in a support manner, or that we need to extend the Core API to sup
:leveloffset: {level3}
-include::valueserialization.txt[]
+include::serialization.txt[]
:leveloffset: {level3}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/docs/valueserialization.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/valueserialization.txt b/core/spi/src/docs/valueserialization.txt
deleted file mode 100644
index 9f76b73..0000000
--- a/core/spi/src/docs/valueserialization.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-///////////////////////////////////////////////////////////////
- * 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.
-///////////////////////////////////////////////////////////////
-
-[[core-spi-valueserialization,ValueSerialization SPI]]
-= ValueSerialization SPI =
-
-== Overview ==
-
-The Polygene\u2122 Core Runtime use ValueSerialization to provide string representation of ValueComposites via their `toString()`
-method, and, their instanciation from the very same representation via the `newValueFromSerializedState(..)` method of
-the ValueBuilderFactory API.
-
-If no ValueSerialization service is visible, a default implementation supporting the JSON format used but note that it
-won't be available as a Service. So, in order to use the full ValueSerialization API a ValueSerialization service must
-be explicitely assembled in the Application. See the <<extensions>> documentation for details.
-
-== Implementation notes ==
-
-Simply implement ValueSerialization to create an extension for the ValueSerialization SPI.
-The Core SPI module provides adapters to create pull-parsing capable ValueSerializers and pull-parsing and tree-parsing
-capable ValueDeserializers.
-
-The behaviour described here apply to all ValueSerialization services implemented using the Core SPI adapters. Note that
-nothing stops you from implementing an extension for the ValueSerialization SPI without relying on theses adapters.
-
-Theses adapters are tailored for serialization mechanisms that support the following two structures that can be nested:
-
- * a collection of name/value pairs. In various languages, this is realized as an object, record, struct,
- dictionary, hash table, keyed list, or associative array,
- * an ordered list of values. In most languages, this is realized as an array, vector, list, or sequence ;
-
-in other words, a JSON-like structure.
-
-Special attention is taken when dealing with Maps. They are serialized as an ordered list of collections of
-name/value pairs to keep the Map order for least surprise. That way, even when the underlying serialization mechanism
-do not keep the collection of name/value pairs order we can rely on it being kept.
-
-Here is a sample Map with two entries in JSON notation to make things clear:
-
-[source,javascript]
-----
-[
- { "key": "foo", "value": "bar" },
- { "key": "cathedral", "value": "bazar" }
-]
-----
-
-Among Plain Values (see the <<core-api-value,ValueSerialization API>> section) some are considered primitives to
-underlying serialization mechanisms and by so handed/come without conversion to/from implementations.
-
-Primitive values can be one of:
-
- * String,
- * Boolean or boolean,
- * Integer or int,
- * Long or long,
- * Short or short,
- * Byte or byte,
- * Float or float,
- * Double or double.
-
-Serialization is always done in a streaming manner using a pull-parsing based approach.
-
-Deserialization is done in a streaming manner using a pull-parsing based approach except when encountering a
-ValueComposite. ValueComposite types are deserialized using a tree-parsing based approach.
-
-All this means that you can serialize and deserialize large collections of values without filling the heap.
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java b/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
index 7c343fa..98b4f8c 100644
--- a/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
+++ b/core/spi/src/main/java/org/apache/polygene/entitystore/memory/MemoryMapEntityStoreMixin.java
@@ -23,11 +23,11 @@ import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
-import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
+import javax.json.Json;
import org.apache.polygene.api.entity.EntityDescriptor;
import org.apache.polygene.api.entity.EntityReference;
import org.apache.polygene.spi.entitystore.BackupRestore;
@@ -37,9 +37,6 @@ import org.apache.polygene.spi.entitystore.EntityStoreException;
import org.apache.polygene.spi.entitystore.helpers.JSONKeys;
import org.apache.polygene.spi.entitystore.helpers.MapEntityStore;
import org.apache.polygene.spi.entitystore.helpers.MapEntityStoreActivation;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
/**
* In-memory implementation of MapEntityStore.
@@ -55,21 +52,15 @@ public class MemoryMapEntityStoreMixin
}
@Override
- public void activateMapEntityStore()
- throws Exception
- {
- // NOOP
- }
+ public void activateMapEntityStore() {}
- public boolean contains( EntityReference entityReference, EntityDescriptor descriptor )
- throws EntityStoreException
+ public boolean contains( EntityReference entityReference, EntityDescriptor descriptor ) throws EntityStoreException
{
return store.containsKey( entityReference );
}
@Override
- public Reader get( EntityReference entityReference )
- throws EntityStoreException
+ public Reader get( EntityReference entityReference ) throws EntityStoreException
{
String state = store.get( entityReference );
if( state == null )
@@ -81,8 +72,7 @@ public class MemoryMapEntityStoreMixin
}
@Override
- public void applyChanges( MapEntityStore.MapChanges changes )
- throws IOException
+ public void applyChanges( MapEntityStore.MapChanges changes ) throws Exception
{
changes.visitMap( new MemoryMapChanger() );
}
@@ -100,29 +90,23 @@ public class MemoryMapEntityStoreMixin
}
@Override
- public void restore( final Stream<String> stream )
+ public void restore( Stream<String> stream )
{
store.clear();
- stream.forEach( item -> {
- try
+ stream.forEach(
+ item ->
{
- JSONTokener tokener = new JSONTokener( item );
- JSONObject entity = (JSONObject) tokener.nextValue();
- String id = entity.getString( JSONKeys.IDENTITY );
+ String id = Json.createReader( new StringReader( item ) )
+ .readObject().getString( JSONKeys.IDENTITY );
store.put( EntityReference.parseEntityReference( id ), item );
- }
- catch( JSONException e )
- {
- throw new UncheckedIOException( new IOException( e ) );
- }
- } );
+ } );
}
private class MemoryMapChanger
implements MapChanger
{
@Override
- public Writer newEntity( final EntityReference ref, EntityDescriptor descriptor )
+ public Writer newEntity( EntityReference ref, EntityDescriptor descriptor )
{
return new StringWriter( 1000 )
{
@@ -142,7 +126,7 @@ public class MemoryMapEntityStoreMixin
}
@Override
- public Writer updateEntity( final EntityReference ref, EntityDescriptor descriptor )
+ public Writer updateEntity( MapChange mapChange )
throws IOException
{
return new StringWriter( 1000 )
@@ -152,11 +136,12 @@ public class MemoryMapEntityStoreMixin
throws IOException
{
super.close();
- String old = store.put( ref, toString() );
+ EntityReference reference = mapChange.reference();
+ String old = store.put( reference, toString() );
if( old == null )
{
- store.remove( ref );
- throw new EntityNotFoundException( ref );
+ store.remove( reference );
+ throw new EntityNotFoundException( reference );
}
}
};
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java
new file mode 100644
index 0000000..3c44864
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJson.java
@@ -0,0 +1,139 @@
+/*
+ * 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.Map;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+/**
+ * javax.json utilities.
+ */
+public class JavaxJson
+{
+ /**
+ * Create a {@link JsonObjectBuilder} populated with the state of a {@link JsonObject}.
+ *
+ * @param jo the JsonObject
+ * @return the builder
+ */
+ public static JsonObjectBuilder toBuilder( JsonObject jo )
+ {
+ JsonObjectBuilder job = Json.createObjectBuilder();
+ for( Map.Entry<String, JsonValue> entry : jo.entrySet() )
+ {
+ job.add( entry.getKey(), entry.getValue() );
+ }
+ return job;
+ }
+
+ /**
+ * Create a {@link JsonArrayBuilder} populated with the state of a {@link JsonArray}.
+ *
+ * @param ja the JsonArray
+ * @return the builder
+ */
+ public static JsonArrayBuilder toBuilder( JsonArray ja )
+ {
+ JsonArrayBuilder job = Json.createArrayBuilder();
+ for( JsonValue value : ja )
+ {
+ job.add( value );
+ }
+ return job;
+ }
+
+ /**
+ * Create a {@link JsonString} from {@link Object#toString()}.
+ *
+ * @param object the Object
+ * @return the JsonString
+ */
+ public static JsonString toJsonString( Object object )
+ {
+ return Json.createObjectBuilder().add( "value", object.toString() ).build().getJsonString( "value" );
+ }
+
+ /**
+ * Get a {@link String} out of a {@link JsonValue}.
+ *
+ * @param jsonValue the JSON value
+ * @return the String
+ */
+ public static String asString( JsonValue jsonValue )
+ {
+ return jsonValue instanceof JsonString ? ( (JsonString) jsonValue ).getString() : jsonValue.toString();
+ }
+
+ /**
+ * Require a {@link JsonValue} to be a {@link JsonStructure}.
+ *
+ * @param json the JSON value
+ * @return the JSON structure
+ * @throws JsonException if it is not
+ */
+ public static JsonStructure requireJsonStructure( JsonValue json )
+ {
+ if( json.getValueType() != JsonValue.ValueType.OBJECT && json.getValueType() != JsonValue.ValueType.ARRAY )
+ {
+ throw new JsonException( "Expected a JSON object or array but got " + json );
+ }
+ return (JsonStructure) json;
+ }
+
+ /**
+ * Require a {@link JsonValue} to be a {@link JsonObject}.
+ *
+ * @param json the JSON value
+ * @return the JSON object
+ * @throws JsonException if it is not
+ */
+ public static JsonObject requireJsonObject( JsonValue json )
+ {
+ if( json.getValueType() != JsonValue.ValueType.OBJECT )
+ {
+ throw new JsonException( "Expected a JSON object but got " + json );
+ }
+ return (JsonObject) json;
+ }
+
+ /**
+ * Require a {@link JsonValue} to be a {@link JsonArray}.
+ *
+ * @param json the JSON value
+ * @return the JSON array
+ * @throws JsonException if it is not
+ */
+ public static JsonArray requireJsonArray( JsonValue json )
+ {
+ if( json.getValueType() != JsonValue.ValueType.ARRAY )
+ {
+ throw new JsonException( "Expected a JSON array but got " + json );
+ }
+ return (JsonArray) json;
+ }
+
+ private JavaxJson() {}
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/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
new file mode 100644
index 0000000..d8ffcfa
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapter.java
@@ -0,0 +1,54 @@
+/*
+ * 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.function.BiFunction;
+import java.util.function.Function;
+import javax.json.JsonValue;
+import org.apache.polygene.api.type.ValueType;
+
+/**
+ * Adapter for JSON (de)serialization.
+ *
+ * @param <T> the adapted type
+ */
+public interface JavaxJsonAdapter<T>
+{
+ /**
+ * @return the adapted type
+ */
+ Class<T> type();
+
+ /**
+ * Serialize.
+ *
+ * @param object Object to serialize, never null
+ * @param serializeFunction Serialization function for nested structure serialization
+ * @return Serialized JSON representation
+ */
+ JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction );
+
+ /**
+ * Deserialize.
+ *
+ * @param json JSON to deserialize from, never null
+ * @param deserializeFunction Deserialization function for nested structure deserialization
+ * @return Deserialized object
+ */
+ T deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction );
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/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
new file mode 100644
index 0000000..fdc9d27
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonAdapters.java
@@ -0,0 +1,64 @@
+/*
+ * 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.LinkedHashMap;
+import java.util.Map;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.type.ValueType;
+
+import static org.apache.polygene.api.type.HasTypesCollectors.closestType;
+
+@Mixins( JavaxJsonAdapters.Mixin.class )
+public interface JavaxJsonAdapters
+{
+ void registerAdapter( ValueType valueType, JavaxJsonAdapter<?> adapter );
+
+ <T> JavaxJsonAdapter<T> adapterFor( ValueType valueType );
+
+ default <T> JavaxJsonAdapter<T> adapterFor( Class<T> type )
+ {
+ return adapterFor( ValueType.of( type ) );
+ }
+
+ class Mixin implements JavaxJsonAdapters
+ {
+ private Map<ValueType, JavaxJsonAdapter<?>> adapters = new LinkedHashMap<>();
+
+ @Override
+ public void registerAdapter( ValueType valueType, JavaxJsonAdapter<?> adapter )
+ {
+ adapters.put( valueType, adapter );
+ }
+
+ @Override
+ public <T> JavaxJsonAdapter<T> adapterFor( ValueType valueType )
+ {
+ return castAdapter( adapters.keySet().stream()
+ .collect( closestType( valueType ) )
+ .map( adapters::get )
+ .orElse( null ) );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private <T> JavaxJsonAdapter<T> castAdapter( JavaxJsonAdapter<?> adapter )
+ {
+ return (JavaxJsonAdapter<T>) adapter;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/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
new file mode 100644
index 0000000..721c884
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
@@ -0,0 +1,273 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+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.JsonStructure;
+import javax.json.JsonValue;
+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.property.PropertyDescriptor;
+import org.apache.polygene.api.serialization.SerializationException;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.CollectionType;
+import org.apache.polygene.api.type.EnumType;
+import org.apache.polygene.api.type.MapType;
+import org.apache.polygene.api.type.ValueCompositeType;
+import org.apache.polygene.api.type.ValueType;
+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.JsonDeserializer;
+
+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.toCollection;
+import static org.apache.polygene.api.util.Collectors.toMapWithNullValues;
+import static org.apache.polygene.serialization.javaxjson.JavaxJson.asString;
+import static org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonArray;
+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
+{
+ @This
+ private JavaxJsonAdapters adapters;
+
+ @Uses
+ private ServiceDescriptor descriptor;
+
+ @Override
+ public <T> T fromJson( ModuleDescriptor module, ValueType valueType, JsonValue state )
+ {
+ return doDeserialize( module, valueType, state );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private <T> T doDeserialize( ModuleDescriptor module, ValueType valueType, JsonValue json )
+ {
+ if( json == null || JsonValue.NULL.equals( json ) )
+ {
+ return null;
+ }
+ JavaxJsonAdapter<?> adapter = adapters.adapterFor( valueType );
+ if( adapter != null )
+ {
+ return (T) adapter.deserialize( json, ( jsonValue, type ) -> doDeserialize( module, type, jsonValue ) );
+ }
+ Class<? extends ValueType> valueTypeClass = valueType.getClass();
+ if( EnumType.class.isAssignableFrom( valueTypeClass ) )
+ {
+ return (T) Enum.valueOf( (Class) valueType.primaryType(), asString( json ) );
+ }
+ if( CollectionType.class.isAssignableFrom( valueTypeClass ) )
+ {
+ return (T) deserializeCollection( module, (CollectionType) valueType, requireJsonArray( json ) );
+ }
+ if( MapType.class.isAssignableFrom( valueTypeClass ) )
+ {
+ return (T) deserializeMap( module, (MapType) valueType, requireJsonStructure( json ) );
+ }
+ if( ValueCompositeType.class.isAssignableFrom( valueTypeClass ) )
+ {
+ return (T) deserializeValueComposite( module, (ValueCompositeType) valueType, requireJsonObject( json ) );
+ }
+ return doGuessDeserialize( module, valueType, json );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private <T> T doGuessDeserialize( ModuleDescriptor module, ValueType valueType, JsonValue json )
+ {
+ switch( json.getValueType() )
+ {
+ case OBJECT:
+ JsonObject object = (JsonObject) json;
+ String typeInfo = object.getString( getTypeInfoPropertyName(), valueType.primaryType().getName() );
+ ValueDescriptor valueDescriptor = module.valueDescriptor( typeInfo );
+ if( valueDescriptor != null )
+ {
+ return (T) deserializeValueComposite( module, valueDescriptor.valueType(), object );
+ }
+ case STRING:
+ return (T) deserializeBase64( asString( json ) );
+ default:
+ throw new SerializationException( "Don't know how to deserialize " + valueType + " from " + json );
+ }
+ }
+
+ private <T> Collection<T> deserializeCollection( ModuleDescriptor module, CollectionType collectionType,
+ JsonArray json )
+ {
+ return (Collection<T>) json.stream()
+ .map( item -> doDeserialize( module, collectionType.collectedType(), item ) )
+ .collect( toCollection(
+ () -> collectionType.isSet() ? new LinkedHashSet<>() : new ArrayList<>() ) );
+ }
+
+ /**
+ * Map deserialization.
+ *
+ * {@literal JsonObject}s are deserialized to {@literal Map<String, ?>}.
+ * {@literal JsonArray}s of key/value {@literal JsonObject}s are deserialized to {@literal Map<?, ?>}.
+ */
+ private Map<?, ?> deserializeMap( ModuleDescriptor module, MapType mapType, JsonStructure json )
+ {
+ if( json.getValueType() == JsonValue.ValueType.OBJECT )
+ {
+ JsonObject object = (JsonObject) json;
+ return object.entrySet().stream()
+ .map( entry -> new AbstractMap.SimpleImmutableEntry<>(
+ entry.getKey(),
+ doDeserialize( module, mapType.valueType(), entry.getValue() ) ) )
+ .collect( toMapWithNullValues( LinkedHashMap::new ) );
+ }
+ if( json.getValueType() == JsonValue.ValueType.ARRAY )
+ {
+ JsonArray array = (JsonArray) json;
+ return array.stream()
+ .map( JsonObject.class::cast )
+ .map( entry -> new AbstractMap.SimpleImmutableEntry<>(
+ doDeserialize( module, mapType.keyType(), entry.get( "key" ) ),
+ doDeserialize( module, mapType.valueType(), entry.get( "value" ) )
+ ) )
+ .collect( toMapWithNullValues( LinkedHashMap::new ) );
+ }
+ throw new SerializationException( "Don't know how to deserialize " + mapType + " from " + json );
+ }
+
+ private Object deserializeValueComposite( ModuleDescriptor module, ValueCompositeType valueType, JsonObject json )
+ {
+ String typeInfoName = getTypeInfoPropertyName();
+ String typeInfo = json.getString( typeInfoName, null );
+ if( typeInfo != null )
+ {
+ ValueDescriptor descriptor = module.valueDescriptor( typeInfo );
+ if( descriptor == null )
+ {
+ throw new SerializationException(
+ typeInfoName + ": " + typeInfo + " could not be resolved while deserializing " + json );
+ }
+ valueType = descriptor.valueType();
+ }
+ ValueBuilder builder = module.instance().newValueBuilderWithState(
+ valueType.primaryType(),
+ propertyFunction( module, json ),
+ associationFunction( module, json ),
+ manyAssociationFunction( module, json ),
+ namedAssociationFunction( module, json ) );
+ return builder.newInstance();
+ }
+
+ private Function<PropertyDescriptor, Object> propertyFunction( ModuleDescriptor module, JsonObject object )
+ {
+ return property ->
+ {
+ JsonValue jsonValue = object.get( property.qualifiedName().name() );
+ if( jsonValue != null )
+ {
+ Object value = doDeserialize( module, property.valueType(), jsonValue );
+ if( property.isImmutable() )
+ {
+ if( value instanceof Set )
+ {
+ return unmodifiableSet( (Set<?>) value );
+ }
+ else if( value instanceof List )
+ {
+ return unmodifiableList( (List<?>) value );
+ }
+ else if( value instanceof Map )
+ {
+ return unmodifiableMap( (Map<?, ?>) value );
+ }
+ }
+ return value;
+ }
+ return property.resolveInitialValue( module );
+ };
+ }
+
+ private Function<AssociationDescriptor, EntityReference> associationFunction( ModuleDescriptor module,
+ JsonObject object )
+ {
+ return association -> doDeserialize( module, ValueType.ENTITY_REFERENCE,
+ object.get( association.qualifiedName().name() ) );
+ }
+
+ private Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction( ModuleDescriptor module,
+ JsonObject object )
+ {
+ return association ->
+ {
+ List<EntityReference> list = doDeserialize( module, ENTITY_REF_LIST_VALUE_TYPE,
+ object.get( association.qualifiedName().name() ) );
+ return list == null ? Stream.empty() : list.stream();
+ };
+ }
+
+ private Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction(
+ ModuleDescriptor module, JsonObject object )
+ {
+ return association ->
+ {
+ Map<String, EntityReference> map = doDeserialize( module, ENTITY_REF_MAP_VALUE_TYPE,
+ object.get( association.qualifiedName().name() ) );
+ return map == null ? Stream.empty() : map.entrySet().stream();
+ };
+ }
+
+ private Object deserializeBase64( String inputString )
+ {
+ byte[] bytes = inputString.getBytes( UTF_8 );
+ bytes = Base64.getDecoder().decode( bytes );
+ try( ObjectInputStream oin = new ObjectInputStream( new ByteArrayInputStream( bytes ) ) )
+ {
+ return oin.readObject();
+ }
+ catch( IOException | ClassNotFoundException ex )
+ {
+ throw new SerializationException( "Unable to deserialize Base64 serialized " + inputString, ex );
+ }
+ }
+
+ private String getTypeInfoPropertyName()
+ {
+ return JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) )
+ .getTypeInfoPropertyName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java
new file mode 100644
index 0000000..2e034b0
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerialization.java
@@ -0,0 +1,26 @@
+/*
+ * 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 org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.spi.serialization.JsonSerialization;
+
+@Mixins( { JavaxJsonSerializer.class, JavaxJsonDeserializer.class } )
+public interface JavaxJsonSerialization extends JsonSerialization
+{
+}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
new file mode 100644
index 0000000..2b662ea
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
@@ -0,0 +1,533 @@
+/*
+ * 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.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZonedDateTime;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import javax.json.Json;
+import javax.json.JsonNumber;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.identity.StringIdentity;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.serialization.SerializationException;
+import org.apache.polygene.api.service.ServiceActivation;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.api.type.ValueType;
+
+// TODO Move into JavaxJsonSerialization
+// TODO Do the same on XML & MessagePack
+@Mixins( JavaxJsonSerializationService.Activation.class )
+public interface JavaxJsonSerializationService extends JavaxJsonSerialization, ServiceActivation
+{
+ class Activation implements ServiceActivation
+ {
+ @Uses
+ private ServiceDescriptor descriptor;
+
+ @This
+ private JavaxJsonAdapters adapters;
+
+ private boolean registrationDone = false;
+
+ @Override
+ public void activateService()
+ {
+ if( !registrationDone )
+ {
+ registerCustomAdapters();
+ registerBaseAdapters();
+ registrationDone = true;
+ }
+ }
+
+ @Override
+ public void passivateService() {}
+
+ private void registerCustomAdapters()
+ {
+ JavaxJsonSettings.orDefault( descriptor.metaInfo( JavaxJsonSettings.class ) )
+ .getAdapters()
+ .forEach( ( valueType, adapter ) -> adapters.registerAdapter( valueType, adapter ) );
+ }
+
+ private void registerBaseAdapters()
+ {
+ // Primitive Value types
+ adapters.registerAdapter( ValueType.STRING, new StringAdapter() );
+ adapters.registerAdapter( ValueType.CHARACTER, new CharacterAdapter() );
+ adapters.registerAdapter( ValueType.BOOLEAN, new BooleanAdapter() );
+ adapters.registerAdapter( ValueType.INTEGER, new IntegerAdapter() );
+ adapters.registerAdapter( ValueType.LONG, new LongAdapter() );
+ adapters.registerAdapter( ValueType.SHORT, new ShortAdapter() );
+ adapters.registerAdapter( ValueType.BYTE, new ByteAdapter() );
+ adapters.registerAdapter( ValueType.FLOAT, new FloatAdapter() );
+ adapters.registerAdapter( ValueType.DOUBLE, new DoubleAdapter() );
+
+ // Number types
+ adapters.registerAdapter( ValueType.BIG_DECIMAL, new BigDecimalAdapter() );
+ adapters.registerAdapter( ValueType.BIG_INTEGER, new BigIntegerAdapter() );
+
+ // Date types
+ adapters.registerAdapter( ValueType.INSTANT, new InstantAdapter() );
+ adapters.registerAdapter( ValueType.ZONED_DATE_TIME, new ZonedDateTimeAdapter() );
+ adapters.registerAdapter( ValueType.OFFSET_DATE_TIME, new OffsetDateTimeAdapter() );
+ adapters.registerAdapter( ValueType.LOCAL_DATE_TIME, new LocalDateTimeAdapter() );
+ adapters.registerAdapter( ValueType.LOCAL_DATE, new LocalDateAdapter() );
+ adapters.registerAdapter( ValueType.LOCAL_TIME, new LocalTimeAdapter() );
+ adapters.registerAdapter( ValueType.DURATION, new DurationAdapter() );
+ adapters.registerAdapter( ValueType.PERIOD, new PeriodAdapter() );
+
+ // Other supported types
+ adapters.registerAdapter( ValueType.IDENTITY, new IdentityAdapter() );
+ adapters.registerAdapter( ValueType.ENTITY_REFERENCE, new EntityReferenceAdapter() );
+ }
+
+ private static abstract class ToJsonStringAdapter<T> implements JavaxJsonAdapter<T>
+ {
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return JavaxJson.toJsonString( object );
+ }
+ }
+
+ private static class StringAdapter extends ToJsonStringAdapter<String>
+ {
+ @Override
+ public Class<String> type() { return String.class; }
+
+ @Override
+ public String deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return JavaxJson.asString( json );
+ }
+ }
+
+ private static class CharacterAdapter extends ToJsonStringAdapter<Character>
+ {
+ @Override
+ public Class<Character> type() { return Character.class; }
+
+ @Override
+ public Character deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ String string = JavaxJson.asString( json );
+ return string.isEmpty() ? null : string.charAt( 0 );
+ }
+ }
+
+ private static class BooleanAdapter implements JavaxJsonAdapter<Boolean>
+ {
+ @Override
+ public Class<Boolean> type() { return Boolean.class; }
+
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return type().cast( object ) ? JsonValue.TRUE : JsonValue.FALSE;
+ }
+
+ @Override
+ public Boolean deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case TRUE:
+ return true;
+ case FALSE:
+ return false;
+ case NULL:
+ return null;
+ case NUMBER:
+ return ( (JsonNumber) json ).doubleValue() > 0;
+ case STRING:
+ return Boolean.valueOf( ( (JsonString) json ).getString() );
+ default:
+ throw new SerializationException( "Don't know how to deserialize Boolean from " + json );
+ }
+ }
+ }
+
+ private static class IntegerAdapter implements JavaxJsonAdapter<Integer>
+ {
+ @Override
+ public Class<Integer> type() { return Integer.class; }
+
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+ .getJsonNumber( "value" );
+ }
+
+ @Override
+ public Integer deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return ( (JsonNumber) json ).intValueExact();
+ case STRING:
+ String string = ( (JsonString) json ).getString();
+ return string.isEmpty() ? 0 : Integer.parseInt( string );
+ default:
+ throw new SerializationException( "Don't know how to deserialize Integer from " + json );
+ }
+ }
+ }
+
+ private static class LongAdapter implements JavaxJsonAdapter<Long>
+ {
+ @Override
+ public Class<Long> type() { return Long.class; }
+
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return Json.createObjectBuilder().add( "value", type().cast( object ) ).build().getJsonNumber(
+ "value" );
+ }
+
+ @Override
+ public Long deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return ( (JsonNumber) json ).longValueExact();
+ case STRING:
+ String string = ( (JsonString) json ).getString();
+ return string.isEmpty() ? 0L : Long.parseLong( string );
+ default:
+ throw new SerializationException( "Don't know how to deserialize Long from " + json );
+ }
+ }
+ }
+
+ private static class ShortAdapter implements JavaxJsonAdapter<Short>
+ {
+ @Override
+ public Class<Short> type() { return Short.class; }
+
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+ .getJsonNumber( "value" );
+ }
+
+ @Override
+ public Short deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return (short) ( (JsonNumber) json ).intValueExact();
+ case STRING:
+ String string = ( (JsonString) json ).getString();
+ return string.isEmpty() ? 0 : Short.parseShort( string );
+ default:
+ throw new SerializationException( "Don't know how to deserialize Short from " + json );
+ }
+ }
+ }
+
+ private static class ByteAdapter implements JavaxJsonAdapter<Byte>
+ {
+ @Override
+ public Class<Byte> type() { return Byte.class; }
+
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+ .getJsonNumber( "value" );
+ }
+
+ @Override
+ public Byte deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return (byte) ( (JsonNumber) json ).intValueExact();
+ case STRING:
+ String string = ( (JsonString) json ).getString();
+ return string.isEmpty() ? 0 : Byte.parseByte( string );
+ default:
+ throw new SerializationException( "Don't know how to deserialize Byte from " + json );
+ }
+ }
+ }
+
+ private static class FloatAdapter implements JavaxJsonAdapter<Float>
+ {
+ @Override
+ public Class<Float> type() { return Float.class; }
+
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+ .getJsonNumber( "value" );
+ }
+
+ @Override
+ public Float deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return (float) ( (JsonNumber) json ).doubleValue();
+ case STRING:
+ String string = ( (JsonString) json ).getString();
+ return string.isEmpty() ? 0F : Float.parseFloat( string );
+ default:
+ throw new SerializationException( "Don't know how to deserialize Float from " + json );
+ }
+ }
+ }
+
+ private static class DoubleAdapter implements JavaxJsonAdapter<Double>
+ {
+ @Override
+ public Class<Double> type() { return Double.class; }
+
+ @Override
+ public JsonValue serialize( Object object, Function<Object, JsonValue> serializeFunction )
+ {
+ return Json.createObjectBuilder().add( "value", type().cast( object ) ).build()
+ .getJsonNumber( "value" );
+ }
+
+ @Override
+ public Double deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return ( (JsonNumber) json ).doubleValue();
+ case STRING:
+ String string = ( (JsonString) json ).getString();
+ return string.isEmpty() ? 0D : Double.parseDouble( string );
+ default:
+ throw new SerializationException( "Don't know how to deserialize Double from " + json );
+ }
+ }
+ }
+
+ private static class BigDecimalAdapter extends ToJsonStringAdapter<BigDecimal>
+ {
+ @Override
+ public Class<BigDecimal> type() { return BigDecimal.class; }
+
+ @Override
+ public BigDecimal deserialize( JsonValue json,
+ BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return new BigDecimal( json.toString() );
+ case STRING:
+ return new BigDecimal( ( (JsonString) json ).getString() );
+ default:
+ throw new SerializationException(
+ "Don't know how to deserialize BigDecimal from " + json );
+ }
+ }
+ }
+
+ private static class BigIntegerAdapter extends ToJsonStringAdapter<BigInteger>
+ {
+ @Override
+ public Class<BigInteger> type() { return BigInteger.class; }
+
+ @Override
+ public BigInteger deserialize( JsonValue json,
+ BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ switch( json.getValueType() )
+ {
+ case NULL:
+ return null;
+ case NUMBER:
+ return new BigInteger( json.toString() );
+ case STRING:
+ return new BigInteger( ( (JsonString) json ).getString() );
+ default:
+ throw new SerializationException(
+ "Don't know how to deserialize BigInteger from " + json );
+ }
+ }
+ }
+
+ private static class PeriodAdapter extends ToJsonStringAdapter<Period>
+ {
+ @Override
+ public Class<Period> type() { return Period.class; }
+
+ @Override
+ public Period deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return Period.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class DurationAdapter extends ToJsonStringAdapter<Duration>
+ {
+ @Override
+ public Class<Duration> type() { return Duration.class; }
+
+ @Override
+ public Duration deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return Duration.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class LocalTimeAdapter extends ToJsonStringAdapter<LocalTime>
+ {
+ @Override
+ public Class<LocalTime> type() { return LocalTime.class; }
+
+ @Override
+ public LocalTime deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return LocalTime.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class LocalDateAdapter extends ToJsonStringAdapter<LocalDate>
+ {
+ @Override
+ public Class<LocalDate> type() { return LocalDate.class; }
+
+ @Override
+ public LocalDate deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return LocalDate.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class LocalDateTimeAdapter extends ToJsonStringAdapter<LocalDateTime>
+ {
+ @Override
+ public Class<LocalDateTime> type() { return LocalDateTime.class; }
+
+ @Override
+ public LocalDateTime deserialize( JsonValue json,
+ BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return LocalDateTime.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class OffsetDateTimeAdapter extends ToJsonStringAdapter<OffsetDateTime>
+ {
+ @Override
+ public Class<OffsetDateTime> type() { return OffsetDateTime.class; }
+
+ @Override
+ public OffsetDateTime deserialize( JsonValue json,
+ BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return OffsetDateTime.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class ZonedDateTimeAdapter extends ToJsonStringAdapter<ZonedDateTime>
+ {
+ @Override
+ public Class<ZonedDateTime> type() { return ZonedDateTime.class; }
+
+ @Override
+ public ZonedDateTime deserialize( JsonValue json,
+ BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return ZonedDateTime.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class InstantAdapter extends ToJsonStringAdapter<Instant>
+ {
+ @Override
+ public Class<Instant> type() { return Instant.class; }
+
+ @Override
+ public Instant deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return Instant.parse( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class IdentityAdapter extends ToJsonStringAdapter<Identity>
+ {
+ @Override
+ public Class<Identity> type() { return Identity.class; }
+
+ @Override
+ public Identity deserialize( JsonValue json, BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return StringIdentity.fromString( JavaxJson.asString( json ) );
+ }
+ }
+
+ private static class EntityReferenceAdapter extends ToJsonStringAdapter<EntityReference>
+ {
+ @Override
+ public Class<EntityReference> type() { return EntityReference.class; }
+
+ @Override
+ public EntityReference deserialize( JsonValue json,
+ BiFunction<JsonValue, ValueType, Object> deserializeFunction )
+ {
+ return EntityReference.parseEntityReference( JavaxJson.asString( json ) );
+ }
+ }
+ }
+}