Repository: zest-qi4j Updated Branches: refs/heads/ValueSerialization_Cleanup [created] 0de48249f
Trying to untangle the Options from all the methods call. Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/0de48249 Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/0de48249 Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/0de48249 Branch: refs/heads/ValueSerialization_Cleanup Commit: 0de48249fd0e9191b3f50a830081a16c1858335d Parents: 44a2872 Author: Niclas Hedhman <[email protected]> Authored: Fri Jul 10 19:04:19 2015 +0300 Committer: Niclas Hedhman <[email protected]> Committed: Fri Jul 10 19:04:19 2015 +0300 ---------------------------------------------------------------------- build.gradle | 2 +- .../org/qi4j/api/value/ValueBuilderFactory.java | 1 - .../org/qi4j/api/value/ValueDeserializer.java | 1 - .../org/qi4j/api/value/ValueSerialization.java | 3 - .../org/qi4j/api/value/ValueSerializer.java | 39 +--- .../qi4j/runtime/structure/ModuleInstance.java | 1 + .../spi/value/ValueDeserializerAdapter.java | 44 +++- .../qi4j/spi/value/ValueSerializerAdapter.java | 222 +++++++++---------- .../orgjson/OrgJsonValueSerialization.java | 23 +- .../orgjson/OrgJsonValueSerializer.java | 4 +- ...AbstractValueCompositeSerializationTest.java | 50 ++++- .../elasticsearch/ElasticSearchIndexer.java | 2 +- .../rdf/query/internal/RdfQueryParserImpl.java | 2 +- .../JacksonValueSerializationAssembler.java | 26 ++- .../OrgJsonValueSerializationAssembler.java | 27 ++- .../stax/StaxValueSerializationAssembler.java | 26 ++- .../rdf/entity/EntityStateSerializer.java | 2 +- 17 files changed, 266 insertions(+), 209 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/build.gradle ---------------------------------------------------------------------- diff --git a/build.gradle b/build.gradle index 126e4af..09bfafb 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ project.ext { mainClassName = 'org.qi4j.container.Main' groovycMain_mx = "700m" groovycMain_permSize = "512m" - groovycMain_maxPermSize = "512m" + groovycMain_maxPermSize = "1G" } buildscript { http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/api/src/main/java/org/qi4j/api/value/ValueBuilderFactory.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/value/ValueBuilderFactory.java b/core/api/src/main/java/org/qi4j/api/value/ValueBuilderFactory.java index 57c4e29..4867113 100644 --- a/core/api/src/main/java/org/qi4j/api/value/ValueBuilderFactory.java +++ b/core/api/src/main/java/org/qi4j/api/value/ValueBuilderFactory.java @@ -96,5 +96,4 @@ public interface ValueBuilderFactory * @throws ConstructionException if the value could not be instantiated */ <T> T newValueFromSerializedState( Class<T> valueType, String serializedState ); - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/api/src/main/java/org/qi4j/api/value/ValueDeserializer.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/value/ValueDeserializer.java b/core/api/src/main/java/org/qi4j/api/value/ValueDeserializer.java index 175b176..5740849 100644 --- a/core/api/src/main/java/org/qi4j/api/value/ValueDeserializer.java +++ b/core/api/src/main/java/org/qi4j/api/value/ValueDeserializer.java @@ -69,7 +69,6 @@ import org.qi4j.functional.Function2; */ public interface ValueDeserializer { - /** * Factory method for a typed deserialize function. * http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/api/src/main/java/org/qi4j/api/value/ValueSerialization.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/value/ValueSerialization.java b/core/api/src/main/java/org/qi4j/api/value/ValueSerialization.java index 503aa5c..33a3590 100644 --- a/core/api/src/main/java/org/qi4j/api/value/ValueSerialization.java +++ b/core/api/src/main/java/org/qi4j/api/value/ValueSerialization.java @@ -23,7 +23,6 @@ package org.qi4j.api.value; public interface ValueSerialization extends ValueSerializer, ValueDeserializer { - /** * Serialization format @Service tags. * @@ -34,7 +33,6 @@ public interface ValueSerialization */ interface Formats { - /** * Tag a ValueSerialization service that support the JSON format. */ @@ -44,5 +42,4 @@ public interface ValueSerialization */ String XML = "xml"; } - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/api/src/main/java/org/qi4j/api/value/ValueSerializer.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/value/ValueSerializer.java b/core/api/src/main/java/org/qi4j/api/value/ValueSerializer.java index 337c37e..be60eee 100644 --- a/core/api/src/main/java/org/qi4j/api/value/ValueSerializer.java +++ b/core/api/src/main/java/org/qi4j/api/value/ValueSerializer.java @@ -70,7 +70,6 @@ import org.qi4j.functional.Function; */ public interface ValueSerializer { - /** * Factory method for a serialize function. * @@ -83,15 +82,6 @@ public interface ValueSerializer * Factory method for a serialize function. * * @param <T> the parametrized function input type - * @param options ValueSerializer Options - * @return a serialization function. - */ - <T> Function<T, String> serialize( Options options ); - - /** - * Factory method for a serialize function. - * - * @param <T> the parametrized function input type * @param includeTypeInfo if type information should be included in the output * @return a serialization function. */ @@ -111,17 +101,6 @@ public interface ValueSerializer /** * Serialize the state of a value. * - * @param options ValueSerializer Options - * @param object an Object to serialize - * @return the state - * @throws ValueSerializationException if the Value serialization failed - */ - String serialize( Options options, Object object ) - throws ValueSerializationException; - - /** - * Serialize the state of a value. - * * @param object an Object to serialize * @param includeTypeInfo if type information should be included in the output * @return the state @@ -144,17 +123,6 @@ public interface ValueSerializer /** * Serialize the state of a value. * - * @param options ValueSerializer Options - * @param object an Object to serialize - * @param output that will be used as output - * @throws ValueSerializationException if the Value serialization failed - */ - void serialize( Options options, Object object, OutputStream output ) - throws ValueSerializationException; - - /** - * Serialize the state of a value. - * * @param object an Object to serialize * @param output that will be used as output * @param includeTypeInfo if type information should be included in the output @@ -221,11 +189,12 @@ public interface ValueSerializer */ public Boolean getBoolean( String option ) { - if( !options.containsKey( option ) ) + String value = options.get( option ); + if( value == null ) { - return null; + return false; } - return Boolean.valueOf( options.get( option ) ); + return Boolean.valueOf( value ); } /** http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java index 1612089..aa7fa45 100644 --- a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java +++ b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java @@ -657,6 +657,7 @@ public class ModuleInstance } catch( NoSuchServiceException e ) { +// valueSerialization = newObject( OrgJsonValueSerialization.class ); valueSerialization = new OrgJsonValueSerialization( layer.applicationInstance(), this, this ); } } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java b/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java index b20bd79..68b49bd 100644 --- a/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java +++ b/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java @@ -54,6 +54,7 @@ import org.qi4j.api.value.ValueBuilder; import org.qi4j.api.value.ValueDescriptor; import org.qi4j.api.value.ValueDeserializer; import org.qi4j.api.value.ValueSerializationException; +import org.qi4j.api.value.ValueSerializer; import org.qi4j.functional.Function; import org.qi4j.functional.Function2; @@ -1015,21 +1016,54 @@ public abstract class ValueDeserializerAdapter<InputType, InputNodeType> /** * A Map<K,V> is serialized in an array of entries objects. - * - * <p>Here is an example in JSON:</p> + * <p> + * If {@link ValueSerializer.Options#MAP_ENTRIES_AS_OBJECTS} is @{code false}, then the format is key/value + * explicit, such as follows; + * </p> * <pre> * [ * { "key": "foo", "value": "bar" }, * { "key": "cathedral", "value": "bazar" } * ] * </pre> - * <p>And an empty Map:</p> - * <pre>[]</pre> + * <p> + * An empty Map is an empty JSON array, i.e; + * </p> + * <pre> + * [] + * </pre> + * <p> + * <b> + * NOTE: This was default in Qi4j ver 2.0 and Zest ver 2.1. In Zest 3.0 and later, the + * {@link ValueSerializer.Options#MAP_ENTRIES_AS_OBJECTS} must be set to @{code false} explicitly in + * the assmebly. + * </b> + * </p> * <p> * This allow to use any type as keys and values while keeping the Map order at the cost of having * non-predictible order of key/value inside an entry object. * </p> - * + * <p> + * If the {@link ValueSerializer.Options#MAP_ENTRIES_AS_OBJECTS} is {@code true}, then the format is + * object-oriented, as in regular javascript objects, such as; + * </p> + * <pre> + * { + * { "foo" : "bar" }, + * { "cathedral" : "bazar" } + * } + * </pre> + * <p> + * <b> + * NOTE: This was NOT default in Qi4j ver 2.0 and Zest ver 2.1. In those versions, the + * {@link ValueSerializer.Options#MAP_ENTRIES_AS_OBJECTS} must be set to @{code true} explicitly in + * the assembly to enable this format. + * </b> + * </p> + * <p> + * This has the advantage of smaller serialized format, and easier use in javascript, where the dot notation + * can be used directly. + * </p> * @param <K> Parameterized map key type * @param <V> Parameterized map value type * @param input Input http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java b/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java index 004745a..ab75cb8 100644 --- a/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java +++ b/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java @@ -38,6 +38,8 @@ import org.qi4j.api.composite.CompositeInstance; import org.qi4j.api.entity.EntityComposite; import org.qi4j.api.entity.EntityReference; import org.qi4j.api.entity.Identity; +import org.qi4j.api.injection.scope.Structure; +import org.qi4j.api.injection.scope.This; import org.qi4j.api.property.Property; import org.qi4j.api.property.PropertyDescriptor; import org.qi4j.api.util.Base64Encoder; @@ -47,7 +49,6 @@ import org.qi4j.api.value.ValueDescriptor; import org.qi4j.api.value.ValueSerializationException; import org.qi4j.api.value.ValueSerializer; import org.qi4j.functional.Function; -import org.qi4j.functional.Function2; import static org.qi4j.functional.Iterables.first; @@ -86,29 +87,37 @@ public abstract class ValueSerializerAdapter<OutputType> implements ValueSerializer { - public static interface ComplexSerializer<T, OutputType> + public static final Options DEFAULT_OPTIONS = new Options(); + + public interface ComplexSerializer<T, OutputType> { - void serialize( Options options, T object, OutputType output ) + void serialize( T object, OutputType output ) throws Exception; } private static final String UTF_8 = "UTF-8"; - private static <TO, FROM extends TO> Function2<Options, FROM, TO> identitySerializer() + private static <TO, FROM extends TO> Function<FROM, TO> identitySerializer() { - return new Function2<Options, FROM, TO>() + return new Function<FROM, TO>() { @Override - public TO map( Options options, FROM from ) + public TO map( FROM from ) { return from; } }; } - private final Map<Class<?>, Function2<Options, Object, Object>> serializers = new HashMap<>( 16 ); + private final Map<Class<?>, Function<Object, Object>> serializers = new HashMap<>( 16 ); private final Map<Class<?>, ComplexSerializer<Object, OutputType>> complexSerializers = new HashMap<>( 2 ); + @Structure + private Qi4j api; + + @This + private ValueSerializer me; + /** * Register a Plain Value type serialization Function. * @@ -117,9 +126,9 @@ public abstract class ValueSerializerAdapter<OutputType> * @param serializer Serialization Function */ @SuppressWarnings( "unchecked" ) - protected final <T> void registerSerializer( Class<T> type, Function2<Options, T, Object> serializer ) + protected final <T> void registerSerializer( Class<T> type, Function<T, Object> serializer ) { - serializers.put( type, (Function2<Options, Object, Object>) serializer ); + serializers.put( type, (Function<Object, Object>) serializer ); } /** @@ -149,62 +158,62 @@ public abstract class ValueSerializerAdapter<OutputType> registerSerializer( Double.class, ValueSerializerAdapter.<Object, Double>identitySerializer() ); // Number types - registerSerializer( BigDecimal.class, new Function2<Options, BigDecimal, Object>() + registerSerializer( BigDecimal.class, new Function<BigDecimal, Object>() { @Override - public Object map( Options options, BigDecimal bigDecimal ) + public Object map( BigDecimal bigDecimal ) { return bigDecimal.toString(); } } ); - registerSerializer( BigInteger.class, new Function2<Options, BigInteger, Object>() + registerSerializer( BigInteger.class, new Function<BigInteger, Object>() { @Override - public Object map( Options options, BigInteger bigInteger ) + public Object map( BigInteger bigInteger ) { return bigInteger.toString(); } } ); // Date types - registerSerializer( Date.class, new Function2<Options, Date, Object>() + registerSerializer( Date.class, new Function<Date, Object>() { @Override - public Object map( Options options, Date date ) + public Object map( Date date ) { return Dates.toUtcString( date ); } } ); - registerSerializer( DateTime.class, new Function2<Options, DateTime, Object>() + registerSerializer( DateTime.class, new Function<DateTime, Object>() { @Override - public Object map( Options options, DateTime date ) + public Object map( DateTime date ) { return date.toString(); } } ); - registerSerializer( LocalDateTime.class, new Function2<Options, LocalDateTime, Object>() + registerSerializer( LocalDateTime.class, new Function<LocalDateTime, Object>() { @Override - public Object map( Options options, LocalDateTime date ) + public Object map( LocalDateTime date ) { return date.toString(); } } ); - registerSerializer( LocalDate.class, new Function2<Options, LocalDate, Object>() + registerSerializer( LocalDate.class, new Function<LocalDate, Object>() { @Override - public Object map( Options options, LocalDate date ) + public Object map( LocalDate date ) { return date.toString(); } } ); // Other supported types - registerSerializer( EntityReference.class, new Function2<Options, EntityReference, Object>() + registerSerializer( EntityReference.class, new Function<EntityReference, Object>() { @Override - public Object map( Options options, EntityReference ref ) + public Object map( EntityReference ref ) { return ref.toString(); } @@ -225,19 +234,6 @@ public abstract class ValueSerializerAdapter<OutputType> } @Override - public final <T> Function<T, String> serialize( final Options options ) - { - return new Function<T, String>() - { - @Override - public String map( T object ) - { - return serialize( options, object ); - } - }; - } - - @Override @Deprecated public final <T> Function<T, String> serialize( final boolean includeTypeInfo ) { @@ -246,8 +242,7 @@ public abstract class ValueSerializerAdapter<OutputType> @Override public String map( T object ) { - return serialize( includeTypeInfo ? new Options().withTypeInfo() : new Options().withoutTypeInfo(), - object ); + return serialize( object ); } }; } @@ -256,17 +251,10 @@ public abstract class ValueSerializerAdapter<OutputType> public final String serialize( Object object ) throws ValueSerializationException { - return serialize( new Options(), object ); - } - - @Override - public final String serialize( Options options, Object object ) - throws ValueSerializationException - { try { ByteArrayOutputStream output = new ByteArrayOutputStream(); - serializeRoot( options, object, output ); + serializeRoot( object, output ); return output.toString( UTF_8 ); } catch( ValueSerializationException ex ) @@ -284,24 +272,16 @@ public abstract class ValueSerializerAdapter<OutputType> public final String serialize( Object object, boolean includeTypeInfo ) throws ValueSerializationException { - return serialize( includeTypeInfo ? new Options().withTypeInfo() : new Options().withoutTypeInfo(), - object ); + return serialize( object ); } @Override public final void serialize( Object object, OutputStream output ) throws ValueSerializationException { - serialize( new Options(), object, output ); - } - - @Override - public final void serialize( Options options, Object object, OutputStream output ) - throws ValueSerializationException - { try { - serializeRoot( options, object, output ); + serializeRoot( object, output ); } catch( ValueSerializationException ex ) { @@ -318,11 +298,10 @@ public abstract class ValueSerializerAdapter<OutputType> public final void serialize( Object object, OutputStream output, boolean includeTypeInfo ) throws ValueSerializationException { - serialize( includeTypeInfo ? new Options().withTypeInfo() : new Options().withoutTypeInfo(), - object, output ); + serialize( object, output ); } - private void serializeRoot( Options options, Object object, OutputStream output ) + private void serializeRoot( Object object, OutputStream output ) throws Exception { if( object != null ) @@ -330,7 +309,7 @@ public abstract class ValueSerializerAdapter<OutputType> if( serializers.get( object.getClass() ) != null ) { // Plain Value - Object serialized = serializers.get( object.getClass() ).map( options, object ); + Object serialized = serializers.get( object.getClass() ).map( object ); output.write( serialized.toString().getBytes( UTF_8 ) ); } else if( object.getClass().isEnum() ) @@ -348,13 +327,13 @@ public abstract class ValueSerializerAdapter<OutputType> // Complex Value OutputType adaptedOutput = adaptOutput( output ); onSerializationStart( object, adaptedOutput ); - doSerialize( options, object, adaptedOutput, true ); + doSerialize( object, adaptedOutput, true ); onSerializationEnd( object, adaptedOutput ); } } } - private void doSerialize( Options options, Object object, OutputType output, boolean rootPass ) + private void doSerialize( Object object, OutputType output, boolean rootPass ) throws Exception { // Null @@ -362,54 +341,48 @@ public abstract class ValueSerializerAdapter<OutputType> { onValue( output, null ); } - else // Registered serializer - if( serializers.get( object.getClass() ) != null ) - { - onValue( output, serializers.get( object.getClass() ).map( options, object ) ); - } - else if( complexSerializers.get( object.getClass() ) != null ) - { - complexSerializers.get( object.getClass() ).serialize( options, object, output ); - } - else // ValueComposite - if( ValueComposite.class.isAssignableFrom( object.getClass() ) ) - { - serializeValueComposite( options, object, output, rootPass ); - } - else // EntityComposite - if( EntityComposite.class.isAssignableFrom( object.getClass() ) ) - { - serializeEntityComposite( object, output ); - } - else // Collection - Iterable - if( Iterable.class.isAssignableFrom( object.getClass() ) ) - { - serializeIterable( options, object, output ); - } - else // Array - QUID Remove this and use java serialization for arrays? - if( object.getClass().isArray() ) - { - serializeBase64Serializable( object, output ); - } - else // Map - if( Map.class.isAssignableFrom( object.getClass() ) ) - { - serializeMap( options, object, output ); - } - else // Enum - if( object.getClass().isEnum() ) - { - onValue( output, object.toString() ); - } - else // Fallback to Base64 encoded Java Serialization - { - serializeBase64Serializable( object, output ); - } + else if( serializers.get( object.getClass() ) != null ) // Registered serializer + { + onValue( output, serializers.get( object.getClass() ).map( object ) ); + } + else if( complexSerializers.get( object.getClass() ) != null ) + { + complexSerializers.get( object.getClass() ).serialize( object, output ); + } + else if( ValueComposite.class.isAssignableFrom( object.getClass() ) ) // ValueComposite + { + serializeValueComposite( object, output, rootPass ); + } + else if( EntityComposite.class.isAssignableFrom( object.getClass() ) ) // EntityComposite + { + serializeEntityComposite( object, output ); + } + else if( Iterable.class.isAssignableFrom( object.getClass() ) ) // Collection - Iterable + { + serializeIterable( object, output ); + } + else if( object.getClass().isArray() ) // Array - QUID Remove this and use java serialization for arrays? + { + serializeBase64Serializable( object, output ); + } + else if( Map.class.isAssignableFrom( object.getClass() ) ) // Map + { + serializeMap( object, output ); + } + else if( object.getClass().isEnum() )// Enum + { + onValue( output, object.toString() ); + } + else // Fallback to Base64 encoded Java Serialization + { + serializeBase64Serializable( object, output ); + } } - private void serializeValueComposite( Options options, Object object, OutputType output, boolean rootPass ) + private void serializeValueComposite( Object object, OutputType output, boolean rootPass ) throws Exception { + boolean includeTypeInfo = options().getBoolean( Options.INCLUDE_TYPE_INFO ); CompositeInstance valueInstance = Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( (ValueComposite) object ); ValueDescriptor descriptor = (ValueDescriptor) valueInstance.descriptor(); AssociationStateHolder state = (AssociationStateHolder) valueInstance.state(); @@ -417,7 +390,7 @@ public abstract class ValueSerializerAdapter<OutputType> onObjectStart( output ); //noinspection ConstantConditions - if( options.getBoolean( Options.INCLUDE_TYPE_INFO ) && !rootPass ) + if( includeTypeInfo && !rootPass ) { onFieldStart( output, "_type" ); onValueStart( output ); @@ -431,7 +404,7 @@ public abstract class ValueSerializerAdapter<OutputType> Property<?> property = state.propertyFor( persistentProperty.accessor() ); onFieldStart( output, persistentProperty.qualifiedName().name() ); onValueStart( output ); - doSerialize( options, property.get(), output, false ); + doSerialize( property.get(), output, false ); onValueEnd( output ); onFieldEnd( output ); } @@ -491,13 +464,31 @@ public abstract class ValueSerializerAdapter<OutputType> onObjectEnd( output ); } + private Options options() + { + Options options; + if( api == null ) // fallback is in progress and no injection has happened. + { + options = DEFAULT_OPTIONS; + } + else + { + options = api.compositeDescriptorFor( me ).metaInfo( Options.class ); + if( options == null ) + { + options = DEFAULT_OPTIONS; + } + } + return options; + } + private void serializeEntityComposite( Object object, OutputType output ) throws Exception { onValue( output, EntityReference.entityReferenceFor( object ) ); } - private void serializeIterable( Options options, Object object, OutputType output ) + private void serializeIterable( Object object, OutputType output ) throws Exception { @SuppressWarnings( "unchecked" ) @@ -506,25 +497,26 @@ public abstract class ValueSerializerAdapter<OutputType> for( Object item : collection ) { onValueStart( output ); - doSerialize( options, item, output, false ); + doSerialize( item, output, false ); onValueEnd( output ); } onArrayEnd( output ); } - private void serializeMap( Options options, Object object, OutputType output ) + private void serializeMap( Object object, OutputType output ) throws Exception { + boolean mapEntriesAsObjects = options().getBoolean( Options.MAP_ENTRIES_AS_OBJECTS ); @SuppressWarnings( "unchecked" ) Map<Object, Object> map = (Map<Object, Object>) object; - if( options.getBoolean( Options.MAP_ENTRIES_AS_OBJECTS ) ) + if( mapEntriesAsObjects ) { onObjectStart( output ); for( Map.Entry<Object, Object> entry : map.entrySet() ) { onFieldStart( output, entry.getKey().toString() ); onValueStart( output ); - doSerialize( options, entry.getValue(), output, false ); + doSerialize( entry.getValue(), output, false ); onValueEnd( output ); onFieldEnd( output ); } @@ -545,7 +537,7 @@ public abstract class ValueSerializerAdapter<OutputType> onFieldStart( output, "value" ); onValueStart( output ); - doSerialize( options, entry.getValue(), output, false ); + doSerialize( entry.getValue(), output, false ); onValueEnd( output ); onFieldEnd( output ); @@ -565,7 +557,7 @@ public abstract class ValueSerializerAdapter<OutputType> throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try (ObjectOutputStream out = new ObjectOutputStream( bout )) + try( ObjectOutputStream out = new ObjectOutputStream( bout ) ) { out.writeUnshared( object ); } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerialization.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerialization.java b/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerialization.java index 2e5413f..f86da50 100644 --- a/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerialization.java +++ b/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerialization.java @@ -17,6 +17,7 @@ package org.qi4j.valueserialization.orgjson; import java.io.InputStream; import java.io.OutputStream; +import org.qi4j.api.injection.scope.Structure; import org.qi4j.api.structure.Application; import org.qi4j.api.structure.Module; import org.qi4j.api.type.ValueType; @@ -43,7 +44,7 @@ public class OrgJsonValueSerialization private final OrgJsonValueSerializer serializer; private final OrgJsonValueDeserializer deserializer; - public OrgJsonValueSerialization( Application application, Module module, final Module valuesModule ) + public OrgJsonValueSerialization( @Structure Application application, @Structure Module module, @Structure final Module valuesModule ) { this.serializer = new OrgJsonValueSerializer(); this.deserializer = new OrgJsonValueDeserializer( application, module, new Function<Application, Module>() @@ -63,12 +64,6 @@ public class OrgJsonValueSerialization } @Override - public <T> Function<T, String> serialize( Options options ) - { - return serializer.serialize( options ); - } - - @Override @Deprecated public <T> Function<T, String> serialize( boolean includeTypeInfo ) { @@ -83,13 +78,6 @@ public class OrgJsonValueSerialization } @Override - public String serialize( Options options, Object object ) - throws ValueSerializationException - { - return serializer.serialize( options, object ); - } - - @Override @Deprecated public String serialize( Object object, boolean includeTypeInfo ) throws ValueSerializationException @@ -105,13 +93,6 @@ public class OrgJsonValueSerialization } @Override - public void serialize( Options options, Object object, OutputStream output ) - throws ValueSerializationException - { - serializer.serialize( options, object, output ); - } - - @Override @Deprecated public void serialize( Object object, OutputStream output, boolean includeTypeInfo ) throws ValueSerializationException http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializer.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializer.java b/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializer.java index ddf2fb1..435ba9e 100644 --- a/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializer.java +++ b/core/spi/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializer.java @@ -21,6 +21,9 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import org.json.JSONWriter; +import org.qi4j.api.injection.scope.This; +import org.qi4j.api.value.ValueSerializer; +import org.qi4j.spi.Qi4jSPI; import org.qi4j.spi.value.ValueSerializerAdapter; import org.qi4j.valueserialization.orgjson.OrgJsonValueSerializer.OrgJsonOutput; @@ -30,7 +33,6 @@ import org.qi4j.valueserialization.orgjson.OrgJsonValueSerializer.OrgJsonOutput; public class OrgJsonValueSerializer extends ValueSerializerAdapter<OrgJsonOutput> { - /** * Helper to pass around the Writer alongside the JSONWriter so we can flush it onSerializationEnd. * http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java ---------------------------------------------------------------------- diff --git a/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java b/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java index b3615af..ce84d66 100644 --- a/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java +++ b/core/testsupport/src/main/java/org/qi4j/test/value/AbstractValueCompositeSerializationTest.java @@ -34,6 +34,7 @@ import org.qi4j.api.association.Association; import org.qi4j.api.association.ManyAssociation; import org.qi4j.api.common.Optional; import org.qi4j.api.common.UseDefaults; +import org.qi4j.api.composite.CompositeDescriptor; import org.qi4j.api.entity.EntityBuilder; import org.qi4j.api.entity.EntityComposite; import org.qi4j.api.entity.EntityReference; @@ -45,6 +46,7 @@ import org.qi4j.api.unitofwork.UnitOfWork; import org.qi4j.api.value.ValueBuilder; import org.qi4j.api.value.ValueComposite; import org.qi4j.api.value.ValueSerialization; +import org.qi4j.api.value.ValueSerializer; import org.qi4j.bootstrap.AssemblyException; import org.qi4j.bootstrap.ModuleAssembly; import org.qi4j.bootstrap.ServiceDeclaration; @@ -66,7 +68,6 @@ import static org.junit.Assert.assertThat; public abstract class AbstractValueCompositeSerializationTest extends AbstractQi4jTest { - @Rule @SuppressWarnings( "PublicField" ) public TestName testName = new TestName(); @@ -87,14 +88,18 @@ public abstract class AbstractValueCompositeSerializationTest { module.injectTo( this ); } + @Service @SuppressWarnings( "ProtectedField" ) protected ValueSerialization valueSerialization; @Test - public void givenValueCompositeWhenSerializingAndDeserializingExpectEquals() + public void givenValueCompositeAndOldMapFormatWhenSerializingAndDeserializingExpectEquals() throws Exception { + CompositeDescriptor descriptor = spi.compositeDescriptorFor( valueSerialization ); + ValueSerializer.Options options = descriptor.metaInfo( ValueSerializer.Options.class ); + options.put( ValueSerializer.Options.MAP_ENTRIES_AS_OBJECTS, Boolean.FALSE ); UnitOfWork uow = module.newUnitOfWork(); try { @@ -128,6 +133,47 @@ public abstract class AbstractValueCompositeSerializationTest } } + @Test + public void givenValueCompositeAndNewMapFormatWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + CompositeDescriptor descriptor = spi.compositeDescriptorFor( valueSerialization ); + ValueSerializer.Options options = descriptor.metaInfo( ValueSerializer.Options.class ); + options.put( ValueSerializer.Options.MAP_ENTRIES_AS_OBJECTS, Boolean.TRUE ); + UnitOfWork uow = module.newUnitOfWork(); + try + { + SomeValue some = buildSomeValue(); + + // Serialize using injected service + ByteArrayOutputStream output = new ByteArrayOutputStream(); + valueSerialization.serialize( some, output ); + String stateString = output.toString( "UTF-8" ); + + // Deserialize using Module API + SomeValue some2 = module.newValueFromSerializedState( SomeValue.class, stateString ); + + assertThat( "Same value toString", some.toString(), equalTo( some2.toString() ) ); +// assertThat( "Same value", some, equalTo( some2 ) ); + assertThat( "Same JSON value toString", stateString, equalTo( some2.toString() ) ); + assertThat( "Same JSON value", some.customFoo().get() instanceof CustomFooValue, is( true ) ); + assertThat( "Same JSON value explicit", some.customFooValue().get() instanceof CustomFooValue, is( true ) ); + + assertThat( "String Integer Map", some2.stringIntMap().get().get( "foo" ), equalTo( 42 ) ); + assertThat( "String Value Map", some2.stringValueMap().get().get( "foo" ).internalVal(), equalTo( "Bar" ) ); + assertThat( "Nested Entities", some2.barAssociation().get().cathedral().get(), equalTo( "bazar in barAssociation" ) ); + } + catch( Exception ex ) + { + throw ex; + } + finally + { + uow.discard(); + } + } + + /** * @return a SomeValue ValueComposite whose state is populated with test data. */ http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/extensions/indexing-elasticsearch/src/main/java/org/qi4j/index/elasticsearch/ElasticSearchIndexer.java ---------------------------------------------------------------------- diff --git a/extensions/indexing-elasticsearch/src/main/java/org/qi4j/index/elasticsearch/ElasticSearchIndexer.java b/extensions/indexing-elasticsearch/src/main/java/org/qi4j/index/elasticsearch/ElasticSearchIndexer.java index 329c8e5..bda3e30 100644 --- a/extensions/indexing-elasticsearch/src/main/java/org/qi4j/index/elasticsearch/ElasticSearchIndexer.java +++ b/extensions/indexing-elasticsearch/src/main/java/org/qi4j/index/elasticsearch/ElasticSearchIndexer.java @@ -211,7 +211,7 @@ public interface ElasticSearchIndexer } else { - String serialized = valueSerializer.serialize( new Options().withoutTypeInfo(), value ); + String serialized = valueSerializer.serialize( value ); // TODO Theses tests are pretty fragile, find a better way to fix this, Jackson API should behave better if( serialized.startsWith( "{" ) ) { http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/extensions/indexing-rdf/src/main/java/org/qi4j/index/rdf/query/internal/RdfQueryParserImpl.java ---------------------------------------------------------------------- diff --git a/extensions/indexing-rdf/src/main/java/org/qi4j/index/rdf/query/internal/RdfQueryParserImpl.java b/extensions/indexing-rdf/src/main/java/org/qi4j/index/rdf/query/internal/RdfQueryParserImpl.java index 122ce01..37d733d 100644 --- a/extensions/indexing-rdf/src/main/java/org/qi4j/index/rdf/query/internal/RdfQueryParserImpl.java +++ b/extensions/indexing-rdf/src/main/java/org/qi4j/index/rdf/query/internal/RdfQueryParserImpl.java @@ -341,7 +341,7 @@ public class RdfQueryParserImpl private String createAndEscapeJSONString( Object value ) { - return escapeJSONString( valueSerializer.serialize( new Options().withoutTypeInfo(), value ) ); + return escapeJSONString( valueSerializer.serialize( value ) ); } private String createRegexStringForContaining( String valueVariable, String containedString ) http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/extensions/valueserialization-jackson/src/main/java/org/qi4j/valueserialization/jackson/JacksonValueSerializationAssembler.java ---------------------------------------------------------------------- diff --git a/extensions/valueserialization-jackson/src/main/java/org/qi4j/valueserialization/jackson/JacksonValueSerializationAssembler.java b/extensions/valueserialization-jackson/src/main/java/org/qi4j/valueserialization/jackson/JacksonValueSerializationAssembler.java index a0ee430..f37e53b 100644 --- a/extensions/valueserialization-jackson/src/main/java/org/qi4j/valueserialization/jackson/JacksonValueSerializationAssembler.java +++ b/extensions/valueserialization-jackson/src/main/java/org/qi4j/valueserialization/jackson/JacksonValueSerializationAssembler.java @@ -18,6 +18,7 @@ package org.qi4j.valueserialization.jackson; import org.qi4j.api.structure.Application; import org.qi4j.api.structure.Module; import org.qi4j.api.value.ValueSerialization; +import org.qi4j.api.value.ValueSerializer; import org.qi4j.bootstrap.Assemblers; import org.qi4j.bootstrap.AssemblyException; import org.qi4j.bootstrap.ModuleAssembly; @@ -30,6 +31,7 @@ public class JacksonValueSerializationAssembler extends Assemblers.Visibility<JacksonValueSerializationAssembler> { private Function<Application, Module> valuesModuleFinder; + private ValueSerializer.Options options = new ValueSerializer.Options(); public JacksonValueSerializationAssembler withValuesModuleFinder( Function<Application, Module> valuesModuleFinder ) { @@ -37,22 +39,32 @@ public class JacksonValueSerializationAssembler return this; } + public JacksonValueSerializationAssembler withOptions( ValueSerializer.Options options ) + { + this.options = options; + return this; + } + @Override public void assemble( ModuleAssembly module ) throws AssemblyException { if( valuesModuleFinder == null ) { - module.services( JacksonValueSerializationService.class ). - visibleIn( visibility() ). - taggedWith( ValueSerialization.Formats.JSON ); + module.services( JacksonValueSerializationService.class ) + .visibleIn( visibility() ) + .taggedWith( ValueSerialization.Formats.JSON ) + .setMetaInfo( options ) + ; } else { - module.services( JacksonValueSerializationService.class ). - visibleIn( visibility() ). - taggedWith( ValueSerialization.Formats.JSON ). - setMetaInfo( valuesModuleFinder ); + module.services( JacksonValueSerializationService.class ) + .visibleIn( visibility() ) + .taggedWith( ValueSerialization.Formats.JSON ) + .setMetaInfo( valuesModuleFinder ) + .setMetaInfo( options ) + ; } } } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/extensions/valueserialization-orgjson/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializationAssembler.java ---------------------------------------------------------------------- diff --git a/extensions/valueserialization-orgjson/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializationAssembler.java b/extensions/valueserialization-orgjson/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializationAssembler.java index 82ed416..075d4ab 100644 --- a/extensions/valueserialization-orgjson/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializationAssembler.java +++ b/extensions/valueserialization-orgjson/src/main/java/org/qi4j/valueserialization/orgjson/OrgJsonValueSerializationAssembler.java @@ -18,6 +18,7 @@ package org.qi4j.valueserialization.orgjson; import org.qi4j.api.structure.Application; import org.qi4j.api.structure.Module; import org.qi4j.api.value.ValueSerialization; +import org.qi4j.api.value.ValueSerializer; import org.qi4j.bootstrap.Assemblers; import org.qi4j.bootstrap.AssemblyException; import org.qi4j.bootstrap.ModuleAssembly; @@ -30,6 +31,7 @@ public class OrgJsonValueSerializationAssembler extends Assemblers.Visibility<OrgJsonValueSerializationAssembler> { private Function<Application, Module> valuesModuleFinder; + private ValueSerializer.Options options = new ValueSerializer.Options(); public OrgJsonValueSerializationAssembler withValuesModuleFinder( Function<Application, Module> valuesModuleFinder ) { @@ -37,22 +39,33 @@ public class OrgJsonValueSerializationAssembler return this; } + public OrgJsonValueSerializationAssembler withOptions( ValueSerializer.Options options ) + { + this.options = options; + return this; + } + + @Override public void assemble( ModuleAssembly module ) throws AssemblyException { if( valuesModuleFinder == null ) { - module.services( OrgJsonValueSerializationService.class ). - visibleIn( visibility() ). - taggedWith( ValueSerialization.Formats.JSON ); + module.services( OrgJsonValueSerializationService.class ) + .visibleIn( visibility() ) + .taggedWith( ValueSerialization.Formats.JSON ) + .setMetaInfo( options ) + ; } else { - module.services( OrgJsonValueSerializationService.class ). - visibleIn( visibility() ). - taggedWith( ValueSerialization.Formats.JSON ). - setMetaInfo( valuesModuleFinder ); + module.services( OrgJsonValueSerializationService.class ) + .visibleIn( visibility() ) + .taggedWith( ValueSerialization.Formats.JSON ) + .setMetaInfo( valuesModuleFinder ) + .setMetaInfo( options ) + ; } } } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueSerializationAssembler.java ---------------------------------------------------------------------- diff --git a/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueSerializationAssembler.java b/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueSerializationAssembler.java index 84c8f21..b6371c3 100644 --- a/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueSerializationAssembler.java +++ b/extensions/valueserialization-stax/src/main/java/org/qi4j/valueserialization/stax/StaxValueSerializationAssembler.java @@ -18,6 +18,7 @@ package org.qi4j.valueserialization.stax; import org.qi4j.api.structure.Application; import org.qi4j.api.structure.Module; import org.qi4j.api.value.ValueSerialization; +import org.qi4j.api.value.ValueSerializer; import org.qi4j.bootstrap.Assemblers; import org.qi4j.bootstrap.AssemblyException; import org.qi4j.bootstrap.ModuleAssembly; @@ -30,6 +31,7 @@ public class StaxValueSerializationAssembler extends Assemblers.Visibility<StaxValueSerializationAssembler> { private Function<Application, Module> valuesModuleFinder; + private ValueSerializer.Options options = new ValueSerializer.Options(); public StaxValueSerializationAssembler withValuesModuleFinder( Function<Application, Module> valuesModuleFinder ) { @@ -37,22 +39,32 @@ public class StaxValueSerializationAssembler return this; } + public StaxValueSerializationAssembler withOptions( ValueSerializer.Options options ) + { + this.options = options; + return this; + } + @Override public void assemble( ModuleAssembly module ) throws AssemblyException { if( valuesModuleFinder == null ) { - module.services( StaxValueSerializationService.class ). - visibleIn( visibility() ). - taggedWith( ValueSerialization.Formats.XML ); + module.services( StaxValueSerializationService.class ) + .visibleIn( visibility() ) + .taggedWith( ValueSerialization.Formats.XML ) + .setMetaInfo( options ) + ; } else { - module.services( StaxValueSerializationService.class ). - visibleIn( visibility() ). - taggedWith( ValueSerialization.Formats.XML ). - setMetaInfo( valuesModuleFinder ); + module.services( StaxValueSerializationService.class ) + .visibleIn( visibility() ) + .taggedWith( ValueSerialization.Formats.XML ) + .setMetaInfo( valuesModuleFinder ) + .setMetaInfo( options ) + ; } } } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0de48249/libraries/rdf/src/main/java/org/qi4j/library/rdf/entity/EntityStateSerializer.java ---------------------------------------------------------------------- diff --git a/libraries/rdf/src/main/java/org/qi4j/library/rdf/entity/EntityStateSerializer.java b/libraries/rdf/src/main/java/org/qi4j/library/rdf/entity/EntityStateSerializer.java index b26fade..a7d403d 100644 --- a/libraries/rdf/src/main/java/org/qi4j/library/rdf/entity/EntityStateSerializer.java +++ b/libraries/rdf/src/main/java/org/qi4j/library/rdf/entity/EntityStateSerializer.java @@ -148,7 +148,7 @@ public class EntityStateSerializer } else { - String stringProperty = valueSerializer.serialize( new Options().withoutTypeInfo(), property ); + String stringProperty = valueSerializer.serialize( property ); final Literal object = valueFactory.createLiteral( stringProperty ); graph.add( subject, predicate, object ); }
