Return-Path: X-Original-To: apmail-zest-commits-archive@minotaur.apache.org Delivered-To: apmail-zest-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4518D10980 for ; Wed, 26 Aug 2015 15:45:06 +0000 (UTC) Received: (qmail 81431 invoked by uid 500); 26 Aug 2015 15:45:06 -0000 Delivered-To: apmail-zest-commits-archive@zest.apache.org Received: (qmail 81404 invoked by uid 500); 26 Aug 2015 15:45:06 -0000 Mailing-List: contact commits-help@zest.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@zest.apache.org Delivered-To: mailing list commits@zest.apache.org Received: (qmail 80923 invoked by uid 99); 26 Aug 2015 15:45:05 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Aug 2015 15:45:05 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 31548E713A; Wed, 26 Aug 2015 15:45:05 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: niclas@apache.org To: commits@zest.apache.org Date: Wed, 26 Aug 2015 15:45:21 -0000 Message-Id: <0618b0e414c94585b85580c9b814d0a7@git.apache.org> In-Reply-To: <3b0cd4249ec842c6afdc1e132d3732fa@git.apache.org> References: <3b0cd4249ec842c6afdc1e132d3732fa@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [18/24] zest-java git commit: ZEST-118; Massive update of removing the Iterable<> use for type manipulation in the runtime internals and all public APIs of that. http://git-wip-us.apache.org/repos/asf/zest-java/blob/bd6fbad9/core/spi/src/main/java/org/apache/zest/spi/entitystore/helpers/MapEntityStoreMixin.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/zest/spi/entitystore/helpers/MapEntityStoreMixin.java b/core/spi/src/main/java/org/apache/zest/spi/entitystore/helpers/MapEntityStoreMixin.java index b1ba7b2..91aad69 100644 --- a/core/spi/src/main/java/org/apache/zest/spi/entitystore/helpers/MapEntityStoreMixin.java +++ b/core/spi/src/main/java/org/apache/zest/spi/entitystore/helpers/MapEntityStoreMixin.java @@ -28,12 +28,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.json.JSONWriter; -import org.apache.zest.api.association.AssociationDescriptor; import org.apache.zest.api.common.Optional; import org.apache.zest.api.common.QualifiedName; import org.apache.zest.api.entity.EntityDescriptor; @@ -41,15 +35,13 @@ import org.apache.zest.api.entity.EntityReference; import org.apache.zest.api.injection.scope.Service; import org.apache.zest.api.injection.scope.Structure; import org.apache.zest.api.injection.scope.This; -import org.apache.zest.api.injection.scope.Uses; -import org.apache.zest.api.property.PropertyDescriptor; -import org.apache.zest.api.service.ServiceDescriptor; import org.apache.zest.api.service.qualifier.Tagged; import org.apache.zest.api.structure.Application; import org.apache.zest.api.type.ValueType; import org.apache.zest.api.unitofwork.EntityTypeNotFoundException; import org.apache.zest.api.usecase.Usecase; import org.apache.zest.api.value.ValueSerialization; +import org.apache.zest.api.value.ValueSerializationException; import org.apache.zest.io.Input; import org.apache.zest.io.Output; import org.apache.zest.io.Receiver; @@ -66,9 +58,11 @@ import org.apache.zest.spi.entitystore.ModuleEntityStoreUnitOfWork; import org.apache.zest.spi.entitystore.StateCommitter; import org.apache.zest.spi.module.ModelModule; import org.apache.zest.spi.module.ModuleSpi; - -import static org.apache.zest.functional.Iterables.first; -import static org.apache.zest.functional.Iterables.map; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.json.JSONWriter; /** * Implementation of EntityStore that works with an implementation of MapEntityStore. @@ -101,9 +95,9 @@ public class MapEntityStoreMixin @Service private Migration migration; - @Uses - private ServiceDescriptor descriptor; - + // @Uses +// private ServiceDescriptor descriptor; +// protected String uuid; private int count; @@ -157,34 +151,28 @@ public class MapEntityStoreMixin { try { - mapEntityStore.applyChanges( new MapEntityStore.MapChanges() - { - @Override - public void visitMap( MapEntityStore.MapChanger changer ) - throws IOException + mapEntityStore.applyChanges( changer -> { + for( EntityState entityState : state ) { - for( EntityState entityState : state ) + DefaultEntityState state1 = (DefaultEntityState) entityState; + if( state1.status().equals( EntityStatus.NEW ) ) { - DefaultEntityState state = (DefaultEntityState) entityState; - if( state.status().equals( EntityStatus.NEW ) ) - { - try (Writer writer = changer.newEntity( state.identity(), state.entityDescriptor() )) - { - writeEntityState( state, writer, unitofwork.identity(), unitofwork.currentTime() ); - } - } - else if( state.status().equals( EntityStatus.UPDATED ) ) + try (Writer writer = changer.newEntity( state1.identity(), state1.entityDescriptor() )) { - try (Writer writer = changer.updateEntity( state.identity(), state.entityDescriptor() )) - { - writeEntityState( state, writer, unitofwork.identity(), unitofwork.currentTime() ); - } + writeEntityState( state1, writer, unitofwork.identity(), unitofwork.currentTime() ); } - else if( state.status().equals( EntityStatus.REMOVED ) ) + } + else if( state1.status().equals( EntityStatus.UPDATED ) ) + { + try (Writer writer = changer.updateEntity( state1.identity(), state1.entityDescriptor() )) { - changer.removeEntity( state.identity(), state.entityDescriptor() ); + writeEntityState( state1, writer, unitofwork.identity(), unitofwork.currentTime() ); } } + else if( state1.status().equals( EntityStatus.REMOVED ) ) + { + changer.removeEntity( state1.identity(), state1.entityDescriptor() ); + } } } ); } @@ -213,44 +201,38 @@ public class MapEntityStoreMixin output.receiveFrom( new Sender() { @Override - public void sendTo( final Receiver receiver ) - throws ReceiverThrowableType, EntityStoreException + public void sendTo( final Receiver receiver ) + throws RecThrowableType, EntityStoreException { final List migrated = new ArrayList<>(); try { - mapEntityStore.entityStates().transferTo( new Output() + mapEntityStore.entityStates().transferTo( new Output() { @Override public void receiveFrom( Sender sender ) - throws ReceiverThrowableType, SenderThrowableType + throws RecThrowableType, SenderThrowableType { - sender.sendTo( new Receiver() - { - @Override - public void receive( Reader item ) - throws ReceiverThrowableType + sender.sendTo( item -> { + final EntityState entity = readEntityState( module, item ); + if( entity.status() == EntityStatus.UPDATED ) { - final EntityState entity = readEntityState( module, item ); - if( entity.status() == EntityStatus.UPDATED ) - { - migrated.add( entity ); + migrated.add( entity ); - // Synch back 100 at a time - if( migrated.size() > 100 ) + // Synch back 100 at a time + if( migrated.size() > 100 ) + { + try { - try - { - synchMigratedEntities( migrated ); - } - catch( IOException e ) - { - throw new EntityStoreException( "Synchronization of Migrated Entities failed.", e ); - } + synchMigratedEntities( migrated ); + } + catch( IOException e ) + { + throw new EntityStoreException( "Synchronization of Migrated Entities failed.", e ); } } - receiver.receive( entity ); } + receiver.receive( entity ); } ); // Synch any remaining migrated entities @@ -281,19 +263,13 @@ public class MapEntityStoreMixin private void synchMigratedEntities( final List migratedEntities ) throws IOException { - mapEntityStore.applyChanges( new MapEntityStore.MapChanges() - { - @Override - public void visitMap( MapEntityStore.MapChanger changer ) - throws IOException + mapEntityStore.applyChanges( changer -> { + for( EntityState migratedEntity : migratedEntities ) { - for( EntityState migratedEntity : migratedEntities ) + DefaultEntityState state = (DefaultEntityState) migratedEntity; + try (Writer writer = changer.updateEntity( state.identity(), state.entityDescriptor() )) { - DefaultEntityState state = (DefaultEntityState) migratedEntity; - try (Writer writer = changer.updateEntity( state.identity(), state.entityDescriptor() )) - { - writeEntityState( state, writer, state.version(), state.lastModified() ); - } + writeEntityState( state, writer, state.version(), state.lastModified() ); } } } ); @@ -314,36 +290,42 @@ public class MapEntityStoreMixin JSONWriter properties = json.object(). key( JSONKeys.IDENTITY ).value( state.identity().identity() ). key( JSONKeys.APPLICATION_VERSION ).value( application.version() ). - key( JSONKeys.TYPE ).value( first( state.entityDescriptor().types() ).getName() ). + key( JSONKeys.TYPE ).value( state.entityDescriptor().types().findFirst().get().getName() ). key( JSONKeys.VERSION ).value( version ). key( JSONKeys.MODIFIED ).value( lastModified ). key( JSONKeys.PROPERTIES ).object(); EntityDescriptor entityType = state.entityDescriptor(); - for( PropertyDescriptor persistentProperty : entityType.state().properties() ) - { + entityType.state().properties().forEach( persistentProperty -> { Object value = state.properties().get( persistentProperty.qualifiedName() ); - json.key( persistentProperty.qualifiedName().name() ); - if( value == null || ValueType.isPrimitiveValue( value ) ) - { - json.value( value ); - } - else + try { - String serialized = valueSerialization.serialize( value ); - if( serialized.startsWith( "{" ) ) - { - json.value( new JSONObject( serialized ) ); - } - else if( serialized.startsWith( "[" ) ) + json.key( persistentProperty.qualifiedName().name() ); + if( value == null || ValueType.isPrimitiveValue( value ) ) { - json.value( new JSONArray( serialized ) ); + json.value( value ); } else { - json.value( serialized ); + String serialized = valueSerialization.serialize( value ); + if( serialized.startsWith( "{" ) ) + { + json.value( new JSONObject( serialized ) ); + } + else if( serialized.startsWith( "[" ) ) + { + json.value( new JSONArray( serialized ) ); + } + else + { + json.value( serialized ); + } } } - } + catch( JSONException e ) + { + throw new ValueSerializationException( "Unable to write property " + persistentProperty, e ); + } + } ); JSONWriter associations = properties.endObject().key( JSONKeys.ASSOCIATIONS ).object(); for( Map.Entry stateNameEntityReferenceEntry : state.associations() @@ -391,7 +373,7 @@ public class MapEntityStoreMixin try { JSONObject jsonObject = new JSONObject( new JSONTokener( entityState ) ); - EntityStatus status = EntityStatus.LOADED; + final EntityStatus[] status = {EntityStatus.LOADED}; String version = jsonObject.getString( JSONKeys.VERSION ); long modified = jsonObject.getLong( JSONKeys.MODIFIED ); @@ -411,7 +393,7 @@ public class MapEntityStoreMixin jsonObject.put( JSONKeys.APPLICATION_VERSION, application.version() ); } // State changed - status = EntityStatus.UPDATED; + status[0] = EntityStatus.UPDATED; } String type = jsonObject.getString( JSONKeys.TYPE ); @@ -421,43 +403,40 @@ public class MapEntityStoreMixin { throw new EntityTypeNotFoundException( type, module.name(), - map( ModelModule.toStringFunction, - module.findVisibleEntityTypes() - ) ); + module.findVisibleEntityTypes() + .map( ModelModule.toStringFunction ) + ); } Map properties = new HashMap<>(); JSONObject props = jsonObject.getJSONObject( JSONKeys.PROPERTIES ); - for( PropertyDescriptor propertyDescriptor : entityDescriptor.state().properties() ) - { + entityDescriptor.state().properties().forEach( propertyDescriptor -> { Object jsonValue; try { jsonValue = props.get( propertyDescriptor.qualifiedName().name() ); + if( JSONObject.NULL.equals( jsonValue ) ) + { + properties.put( propertyDescriptor.qualifiedName(), null ); + } + else + { + Object value = valueSerialization.deserialize( propertyDescriptor.valueType(), jsonValue.toString() ); + properties.put( propertyDescriptor.qualifiedName(), value ); + } } catch( JSONException e ) { // Value not found, default it Object initialValue = propertyDescriptor.initialValue( module ); properties.put( propertyDescriptor.qualifiedName(), initialValue ); - status = EntityStatus.UPDATED; - continue; - } - if( JSONObject.NULL.equals( jsonValue ) ) - { - properties.put( propertyDescriptor.qualifiedName(), null ); - } - else - { - Object value = valueSerialization.deserialize( propertyDescriptor.valueType(), jsonValue.toString() ); - properties.put( propertyDescriptor.qualifiedName(), value ); + status[0] = EntityStatus.UPDATED; } - } + } ); Map associations = new HashMap<>(); JSONObject assocs = jsonObject.getJSONObject( JSONKeys.ASSOCIATIONS ); - for( AssociationDescriptor associationType : entityDescriptor.state().associations() ) - { + entityDescriptor.state().associations().forEach( associationType -> { try { Object jsonValue = assocs.get( associationType.qualifiedName().name() ); @@ -470,14 +449,13 @@ public class MapEntityStoreMixin { // Association not found, default it to null associations.put( associationType.qualifiedName(), null ); - status = EntityStatus.UPDATED; + status[0] = EntityStatus.UPDATED; } - } + } ); JSONObject manyAssocs = jsonObject.getJSONObject( JSONKeys.MANY_ASSOCIATIONS ); Map> manyAssociations = new HashMap<>(); - for( AssociationDescriptor manyAssociationType : entityDescriptor.state().manyAssociations() ) - { + entityDescriptor.state().manyAssociations().forEach( manyAssociationType -> { List references = new ArrayList<>(); try { @@ -497,12 +475,11 @@ public class MapEntityStoreMixin // ManyAssociation not found, default to empty one manyAssociations.put( manyAssociationType.qualifiedName(), references ); } - } + } ); JSONObject namedAssocs = jsonObject.getJSONObject( JSONKeys.NAMED_ASSOCIATIONS ); Map> namedAssociations = new HashMap<>(); - for( AssociationDescriptor namedAssociationType : entityDescriptor.state().namedAssociations() ) - { + entityDescriptor.state().namedAssociations().forEach( namedAssociationType -> { Map references = new LinkedHashMap<>(); try { @@ -527,12 +504,12 @@ public class MapEntityStoreMixin // NamedAssociation not found, default to empty one namedAssociations.put( namedAssociationType.qualifiedName(), references ); } - } + } ); return new DefaultEntityState( version, modified, EntityReference.parseEntityReference( identity ), - status, + status[0], entityDescriptor, properties, associations, http://git-wip-us.apache.org/repos/asf/zest-java/blob/bd6fbad9/core/spi/src/main/java/org/apache/zest/spi/module/ModelModule.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/zest/spi/module/ModelModule.java b/core/spi/src/main/java/org/apache/zest/spi/module/ModelModule.java index 2aab450..4445697 100644 --- a/core/spi/src/main/java/org/apache/zest/spi/module/ModelModule.java +++ b/core/spi/src/main/java/org/apache/zest/spi/module/ModelModule.java @@ -27,37 +27,23 @@ import org.apache.zest.api.composite.ModelDescriptor; public class ModelModule { - public static Function toStringFunction = new Function, String>() - { - @Override - public String apply( ModelModule item ) - { - return item.model() - .types() - .iterator() - .next() - .getName() + "[" + item.module().name() + "]"; - } - }; + public static Function, String> toStringFunction = item -> item.model() + .types() + .iterator() + .next() + .getName() + "[" + item.module().name() + "]"; public static Function> modelModuleFunction( final ModuleSpi module ) { - return new Function>() - { - @Override - public ModelModule apply( T model ) - { - return new ModelModule<>( module, model ); - } - }; + return model1 -> new ModelModule<>( module, model1 ); } - public static Function, T> modelFunction() + public static Function, ModelDescriptor> modelFunction() { - return new Function, T>() + return new Function, ModelDescriptor>() { @Override - public T apply( ModelModule modelModule ) + public ModelDescriptor apply( ModelModule modelModule ) { return modelModule.model(); } http://git-wip-us.apache.org/repos/asf/zest-java/blob/bd6fbad9/core/spi/src/main/java/org/apache/zest/spi/module/ModuleSpi.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/zest/spi/module/ModuleSpi.java b/core/spi/src/main/java/org/apache/zest/spi/module/ModuleSpi.java index 6746853..e464fd6 100644 --- a/core/spi/src/main/java/org/apache/zest/spi/module/ModuleSpi.java +++ b/core/spi/src/main/java/org/apache/zest/spi/module/ModuleSpi.java @@ -16,11 +16,14 @@ */ package org.apache.zest.spi.module; +import java.util.stream.Stream; +import org.apache.zest.api.composite.ModelDescriptor; import org.apache.zest.api.composite.TransientDescriptor; import org.apache.zest.api.entity.EntityDescriptor; import org.apache.zest.api.entity.IdentityGenerator; import org.apache.zest.api.object.ObjectDescriptor; import org.apache.zest.api.service.ServiceDescriptor; +import org.apache.zest.api.service.ServiceReference; import org.apache.zest.api.structure.Module; import org.apache.zest.api.value.ValueDescriptor; import org.apache.zest.api.value.ValueSerialization; @@ -34,13 +37,13 @@ public interface ModuleSpi extends Module ValueSerialization valueSerialization(); - Iterable> findVisibleEntityTypes(); + Stream> findVisibleEntityTypes(); - Iterable> findVisibleValueTypes(); + Stream> findVisibleValueTypes(); - Iterable> findVisibleTransientTypes(); + Stream> findVisibleTransientTypes(); - Iterable> findVisibleObjectTypes(); + Stream> findVisibleObjectTypes(); - Iterable> findVisibleServiceTypes(); + Stream> findVisibleServiceTypes(); } http://git-wip-us.apache.org/repos/asf/zest-java/blob/bd6fbad9/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java b/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java index 43dbe37..88167af 100644 --- a/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java +++ b/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java @@ -34,69 +34,66 @@ import java.util.Scanner; import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.apache.zest.api.association.AssociationDescriptor; import org.apache.zest.api.entity.EntityReference; import org.apache.zest.api.injection.scope.Service; import org.apache.zest.api.injection.scope.Structure; -import org.apache.zest.api.property.PropertyDescriptor; import org.apache.zest.api.service.ServiceReference; import org.apache.zest.api.structure.Application; import org.apache.zest.api.structure.Module; import org.apache.zest.api.type.CollectionType; import org.apache.zest.api.type.EnumType; import org.apache.zest.api.type.MapType; +import org.apache.zest.api.type.Serialization; import org.apache.zest.api.type.ValueCompositeType; import org.apache.zest.api.type.ValueType; -import org.apache.zest.api.type.Serialization; import org.apache.zest.api.util.Base64Encoder; import org.apache.zest.api.util.Dates; import org.apache.zest.api.value.ValueBuilder; import org.apache.zest.api.value.ValueDescriptor; import org.apache.zest.api.value.ValueDeserializer; import org.apache.zest.api.value.ValueSerializationException; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; import static org.apache.zest.functional.Iterables.empty; -import static org.apache.zest.functional.Iterables.first; /** * Adapter for pull-parsing and tree-parsing capable ValueDeserializers. * *

- * Among Plain values (see {@link ValueDeserializer}) some are considered primitives to underlying serialization - * mechanisms and by so handed/come without conversion to/from implementations. Primitive values can be one of: + * Among Plain values (see {@link ValueDeserializer}) 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,
  • - *
  • Character or char,
  • - *
  • Boolean or boolean,
  • - *
  • Integer or int,
  • - *
  • Long or long,
  • - *
  • Short or short,
  • - *
  • Byte or byte,
  • - *
  • Float or float,
  • - *
  • Double or double.
  • + *
  • String,
  • + *
  • Character or char,
  • + *
  • Boolean or boolean,
  • + *
  • Integer or int,
  • + *
  • Long or long,
  • + *
  • Short or short,
  • + *
  • Byte or byte,
  • + *
  • Float or float,
  • + *
  • Double or double.
  • *
*

- * Some other Plain values are expected in given formats: + * Some other Plain values are expected in given formats: *

*
    - *
  • BigInteger and BigDecimal depends on {@link org.apache.zest.api.value.ValueSerializer.Options};
  • - *
  • Date as String in ISO-8601, {@literal @millis@} or {@literal /Date(..)} Microsoft format;
  • - *
  • DateTime (JodaTime) as a ISO-8601 String with optional timezone offset;
  • - *
  • LocalDateTime (JodaTime) as whatever {@link LocalDateTime#LocalDateTime(java.lang.Object)} accept as {@literal instant};
  • - *
  • LocalDate (JodaTime) as whatever {@link LocalDate#LocalDate(java.lang.Object)} accept as {@literal instant};
  • + *
  • BigInteger and BigDecimal depends on {@link org.apache.zest.api.value.ValueSerializer.Options};
  • + *
  • Date as String in ISO-8601, {@literal @millis@} or {@literal /Date(..)} Microsoft format;
  • + *
  • DateTime (JodaTime) as a ISO-8601 String with optional timezone offset;
  • + *
  • LocalDateTime (JodaTime) as whatever {@link LocalDateTime#LocalDateTime(java.lang.Object)} accept as {@literal instant};
  • + *
  • LocalDate (JodaTime) as whatever {@link LocalDate#LocalDate(java.lang.Object)} accept as {@literal instant};
  • *
* - * @param Implementor pull-parser type + * @param Implementor pull-parser type * @param Implementor tree-parser node type */ public abstract class ValueDeserializerAdapter implements ValueDeserializer { - public static interface ComplexDeserializer + public interface ComplexDeserializer { T deserializePull( InputType input ) throws Exception; @@ -116,8 +113,8 @@ public abstract class ValueDeserializerAdapter /** * Register a Plain Value type deserialization Function. * - * @param Plain Value parametrized Type - * @param type Plain Value Type + * @param Plain Value parametrized Type + * @param type Plain Value Type * @param deserializer Deserialization Function */ @SuppressWarnings( "unchecked" ) @@ -128,7 +125,8 @@ public abstract class ValueDeserializerAdapter @SuppressWarnings( { "UnusedDeclaration", "unchecked" } ) protected final void registerComplexDeserializer( Class type, - ComplexDeserializer deserializer ) + ComplexDeserializer deserializer + ) { complexDeserializers.put( type, (ComplexDeserializer) deserializer ); } @@ -136,14 +134,16 @@ public abstract class ValueDeserializerAdapter @SuppressWarnings( "unchecked" ) public ValueDeserializerAdapter( @Structure Application application, @Structure Module module, - @Service ServiceReference serviceRef ) + @Service ServiceReference serviceRef + ) { this( application, module, serviceRef.metaInfo( Function.class ) ); } protected ValueDeserializerAdapter( Application application, Module module, - Function valuesModuleFinder ) + Function valuesModuleFinder + ) { this.application = application; @@ -151,155 +151,42 @@ public abstract class ValueDeserializerAdapter setValuesModuleFinder( valuesModuleFinder ); // Primitive Value types - registerDeserializer( String.class, new Function() - { - @Override - public String apply( Object input ) - { - return input.toString(); - } - } ); - registerDeserializer( Character.class, new Function() - { - @Override - public Character apply( Object input ) - { - return input.toString().charAt( 0 ); - } - } ); - registerDeserializer( Boolean.class, new Function() - { - @SuppressWarnings( "UnnecessaryUnboxing" ) - @Override - public Boolean apply( Object input ) - { - return ( input instanceof String ) - ? Boolean.parseBoolean( (String) input ) - : ( (Boolean) input ).booleanValue(); - } - } ); - registerDeserializer( Integer.class, new Function() - { - @Override - public Integer apply( Object input ) - { - return ( input instanceof String ) - ? Integer.parseInt( (String) input ) - : ( (Number) input ).intValue(); - } - } ); - registerDeserializer( Long.class, new Function() - { - @Override - public Long apply( Object input ) - { - return ( input instanceof String ) - ? Long.parseLong( (String) input ) - : ( (Number) input ).longValue(); - } - } ); - registerDeserializer( Short.class, new Function() - { - @Override - public Short apply( Object input ) - { - return ( input instanceof String ) - ? Short.parseShort( (String) input ) - : ( (Number) input ).shortValue(); - } - } ); - registerDeserializer( Byte.class, new Function() - { - @Override - public Byte apply( Object input ) - { - return ( input instanceof String ) - ? Byte.parseByte( (String) input ) - : ( (Number) input ).byteValue(); - } - } ); - registerDeserializer( Float.class, new Function() - { - @Override - public Float apply( Object input ) - { - return ( input instanceof String ) - ? Float.parseFloat( (String) input ) - : ( (Number) input ).floatValue(); - } - } ); - registerDeserializer( Double.class, new Function() - { - @Override - public Double apply( Object input ) - { - return ( input instanceof String ) - ? Double.parseDouble( (String) input ) - : ( (Number) input ).doubleValue(); - } - } ); + registerDeserializer( String.class, Object::toString ); + registerDeserializer( Character.class, input -> input.toString().charAt( 0 ) ); + registerDeserializer( Boolean.class, input -> ( input instanceof String ) + ? Boolean.parseBoolean( (String) input ) + : (Boolean) input ); + registerDeserializer( Integer.class, input -> ( input instanceof String ) + ? Integer.parseInt( (String) input ) + : ( (Number) input ).intValue() ); + registerDeserializer( Long.class, input -> ( input instanceof String ) + ? Long.parseLong( (String) input ) + : ( (Number) input ).longValue() ); + registerDeserializer( Short.class, input -> ( input instanceof String ) + ? Short.parseShort( (String) input ) + : ( (Number) input ).shortValue() ); + registerDeserializer( Byte.class, input -> ( input instanceof String ) + ? Byte.parseByte( (String) input ) + : ( (Number) input ).byteValue() ); + registerDeserializer( Float.class, input -> ( input instanceof String ) + ? Float.parseFloat( (String) input ) + : ( (Number) input ).floatValue() ); + registerDeserializer( Double.class, input -> ( input instanceof String ) + ? Double.parseDouble( (String) input ) + : ( (Number) input ).doubleValue() ); // Number types - registerDeserializer( BigDecimal.class, new Function() - { - @Override - public BigDecimal apply( Object input ) - { - return new BigDecimal( input.toString() ); - } - } ); - registerDeserializer( BigInteger.class, new Function() - { - @Override - public BigInteger apply( Object input ) - { - return new BigInteger( input.toString() ); - } - } ); + registerDeserializer( BigDecimal.class, input -> new BigDecimal( input.toString() ) ); + registerDeserializer( BigInteger.class, input -> new BigInteger( input.toString() ) ); // Date types - registerDeserializer( Date.class, new Function() - { - @Override - public Date apply( Object input ) - { - return Dates.fromString( input.toString() ); - } - } ); - registerDeserializer( DateTime.class, new Function() - { - @Override - public DateTime apply( Object input ) - { - return DateTime.parse( input.toString() ); - } - } ); - registerDeserializer( LocalDateTime.class, new Function() - { - @Override - public LocalDateTime apply( Object input ) - { - return new LocalDateTime( input ); - } - } ); - registerDeserializer( LocalDate.class, new Function() - { - @Override - public LocalDate apply( Object input ) - { - return new LocalDate( input ); - } - } ); + registerDeserializer( Date.class, input -> Dates.fromString( input.toString() ) ); + registerDeserializer( DateTime.class, input -> DateTime.parse( input.toString() ) ); + registerDeserializer( LocalDateTime.class, LocalDateTime::new ); + registerDeserializer( LocalDate.class, LocalDate::new ); // Other supported types - registerDeserializer( EntityReference.class, new Function() - { - @Override - public EntityReference apply( Object input ) - { - return EntityReference.parseEntityReference( input.toString() ); - } - } ); + registerDeserializer( EntityReference.class, input -> EntityReference.parseEntityReference( input.toString() ) ); } private void setValuesModuleFinder( Function valuesModuleFinder ) @@ -347,27 +234,13 @@ public abstract class ValueDeserializerAdapter @Override public final Function deserialize( final ValueType valueType ) { - return new Function() - { - @Override - public T apply( String input ) - { - return deserialize( valueType, input ); - } - }; + return input -> deserialize( valueType, input ); } @Override public final BiFunction deserialize() { - return new BiFunction() - { - @Override - public T apply( ValueType valueType, String input ) - { - return deserialize( valueType, input ); - } - }; + return this::deserialize; } @Override @@ -444,7 +317,7 @@ public abstract class ValueDeserializerAdapter private T deserializeRoot( ValueType valueType, InputStream input ) throws Exception { - final Class type = first( valueType.types() ); + final Class type = valueType.types().findFirst().orElse( null ); // Plain ValueType if( deserializers.get( type ) != null ) { @@ -457,31 +330,31 @@ public abstract class ValueDeserializerAdapter return (T) deserializers.get( type ).apply( string ); } else // Array ValueType - if( type.isArray() ) - { - Scanner scanner = new Scanner( input, UTF_8 ).useDelimiter( "\\A" ); - if( !scanner.hasNext() ) + if( type.isArray() ) { - return null; + Scanner scanner = new Scanner( input, UTF_8 ).useDelimiter( "\\A" ); + if( !scanner.hasNext() ) + { + return null; + } + String string = scanner.next(); + return (T) deserializeBase64Serialized( string ); + } + else // Complex ValueType + { + InputType adaptedInput = adaptInput( input ); + onDeserializationStart( valueType, adaptedInput ); + T deserialized = doDeserialize( valueType, adaptedInput ); + onDeserializationEnd( valueType, adaptedInput ); + return deserialized; } - String string = scanner.next(); - return (T) deserializeBase64Serialized( string ); - } - else // Complex ValueType - { - InputType adaptedInput = adaptInput( input ); - onDeserializationStart( valueType, adaptedInput ); - T deserialized = doDeserialize( valueType, adaptedInput ); - onDeserializationEnd( valueType, adaptedInput ); - return deserialized; - } } @SuppressWarnings( "unchecked" ) private T doDeserialize( ValueType valueType, InputType input ) throws Exception { - final Class type = first( valueType.types() ); + final Class type = valueType.types().findFirst().orElse( null ); // Registered deserializers if( deserializers.get( type ) != null ) { @@ -497,53 +370,48 @@ public abstract class ValueDeserializerAdapter return (T) complexDeserializers.get( type ).deserializePull( input ); } else // Explicit ValueComposite - if( ValueCompositeType.class.isAssignableFrom( valueType.getClass() ) ) - { - return (T) deserializeValueComposite( valueType, input ); - } - else // Explicit Collections - if( CollectionType.class.isAssignableFrom( valueType.getClass() ) ) - { - return (T) deserializeCollection( (CollectionType) valueType, input ); - } - else // Explicit Map - if( MapType.class.isAssignableFrom( valueType.getClass() ) ) - { - return (T) deserializeMap( (MapType) valueType, input ); - } - else // Enum - if( EnumType.class.isAssignableFrom( valueType.getClass() ) || type.isEnum() ) - { - return (T) Enum.valueOf( (Class) type, readPlainValue( input ).toString() ); - } - else // Array - if( type.isArray() ) - { - return (T) deserializeBase64Serialized( readPlainValue( input ).toString() ); - } + if( ValueCompositeType.class.isAssignableFrom( valueType.getClass() ) ) + { + return (T) deserializeValueComposite( valueType, input ); + } + else // Explicit Collections + if( CollectionType.class.isAssignableFrom( valueType.getClass() ) ) + { + return (T) deserializeCollection( (CollectionType) valueType, input ); + } + else // Explicit Map + if( MapType.class.isAssignableFrom( valueType.getClass() ) ) + { + return (T) deserializeMap( (MapType) valueType, input ); + } + else // Enum + if( EnumType.class.isAssignableFrom( valueType.getClass() ) || type.isEnum() ) + { + return (T) Enum.valueOf( (Class) type, readPlainValue( input ).toString() ); + } + else // Array + if( type.isArray() ) + { + return (T) deserializeBase64Serialized( readPlainValue( input ).toString() ); + } // Guessed Deserialization return (T) deserializeGuessed( valueType, input ); } private Function buildDeserializeInputFunction( final ValueType valueType ) { - return new Function() - { - @Override - public T apply( InputType input ) + return input -> { + try { - try - { - return doDeserialize( valueType, input ); - } - catch( ValueSerializationException ex ) - { - throw ex; - } - catch( Exception ex ) - { - throw new ValueSerializationException( ex ); - } + return doDeserialize( valueType, input ); + } + catch( ValueSerializationException ex ) + { + throw ex; + } + catch( Exception ex ) + { + throw new ValueSerializationException( ex ); } }; } @@ -552,7 +420,7 @@ public abstract class ValueDeserializerAdapter throws Exception { Collection collection; - Class collectionMainType = first( collectionType.types() ); + Class collectionMainType = collectionType.types().findFirst().orElse( null ); if( Set.class.equals( collectionMainType ) ) { collection = new LinkedHashSet<>(); @@ -572,7 +440,7 @@ public abstract class ValueDeserializerAdapter return readMapInMap( input, this.buildDeserializeInputFunction( mapType.keyType() ), this.buildDeserializeInputFunction( mapType.valueType() ), - new HashMap() ); + new HashMap<>() ); } private T deserializeValueComposite( ValueType valueType, InputType input ) @@ -590,7 +458,7 @@ public abstract class ValueDeserializerAdapter throws Exception { ValueCompositeType valueCompositeType = (ValueCompositeType) valueType; - Class valueBuilderType = first( valueCompositeType.types() ); + Class valueBuilderType = valueCompositeType.types().findFirst().orElse( null ); String typeInfo = this.getObjectFieldValue( inputNode, "_type", @@ -609,88 +477,117 @@ public abstract class ValueDeserializerAdapter } @SuppressWarnings( "unchecked" ) - private T deserializeValueComposite( ValueCompositeType valueCompositeType, Class valueBuilderType, InputNodeType inputNode ) + private T deserializeValueComposite( ValueCompositeType valueCompositeType, + Class valueBuilderType, + InputNodeType inputNode + ) throws Exception { final Map stateMap = new HashMap<>(); // Properties - for( PropertyDescriptor property : valueCompositeType.properties() ) - { - String propertyName = property.qualifiedName().name(); + valueCompositeType.properties().forEach( property -> { + String propertyName = null; Object value; - if( objectHasField( inputNode, propertyName ) ) + try { - value = getObjectFieldValue( - inputNode, - propertyName, - buildDeserializeInputNodeFunction( property.valueType() ) ); - if( property.isImmutable() ) + propertyName = property.qualifiedName().name(); + if( objectHasField( inputNode, propertyName ) ) { - if( value instanceof Set ) - { - value = Collections.unmodifiableSet( (Set) value ); - } - else if( value instanceof List ) - { - value = Collections.unmodifiableList( (List) value ); - } - else if( value instanceof Map ) + value = getObjectFieldValue( + inputNode, + propertyName, + buildDeserializeInputNodeFunction( property.valueType() ) ); + if( property.isImmutable() ) { - value = Collections.unmodifiableMap( (Map) value ); + if( value instanceof Set ) + { + value = Collections.unmodifiableSet( (Set) value ); + } + else if( value instanceof List ) + { + value = Collections.unmodifiableList( (List) value ); + } + else if( value instanceof Map ) + { + value = Collections.unmodifiableMap( (Map) value ); + } } } + else + { + // Serialized object does not contain the field, try to default it + value = property.initialValue( valuesModule() ); + } } - else + catch( Exception e ) { - // Serialized object does not contain the field, try to default it - value = property.initialValue( valuesModule() ); + throw new ValueSerializationException( "Unable to deserialize property " + property, e ); } stateMap.put( propertyName, value ); - } + } ); // Associations - for( AssociationDescriptor association : valueCompositeType.associations() ) - { - String associationName = association.qualifiedName().name(); - if( objectHasField( inputNode, associationName ) ) + valueCompositeType.associations().forEach( association -> { + try { - Object value = getObjectFieldValue( - inputNode, - associationName, - buildDeserializeInputNodeFunction( new ValueType( EntityReference.class ) ) ); - stateMap.put( associationName, value ); + String associationName = association.qualifiedName().name(); + if( objectHasField( inputNode, associationName ) ) + { + Object value = getObjectFieldValue( + inputNode, + associationName, + buildDeserializeInputNodeFunction( new ValueType( EntityReference.class ) ) ); + stateMap.put( associationName, value ); + } } - } + catch( Exception e ) + { + throw new ValueSerializationException( "Unable to deserialize association " + association, e ); + } + } ); // ManyAssociations - for( AssociationDescriptor manyAssociation : valueCompositeType.manyAssociations() ) - { - String manyAssociationName = manyAssociation.qualifiedName().name(); - if( objectHasField( inputNode, manyAssociationName ) ) + valueCompositeType.manyAssociations().forEach( manyAssociation -> { + try { - Object value = getObjectFieldValue( - inputNode, - manyAssociationName, - buildDeserializeInputNodeFunction( new CollectionType( Collection.class, - new ValueType( EntityReference.class ) ) ) ); - stateMap.put( manyAssociationName, value ); + String manyAssociationName = manyAssociation.qualifiedName().name(); + if( objectHasField( inputNode, manyAssociationName ) ) + { + Object value = getObjectFieldValue( + inputNode, + manyAssociationName, + buildDeserializeInputNodeFunction( new CollectionType( + Collection.class, + new ValueType( EntityReference.class ) ) ) ); + stateMap.put( manyAssociationName, value ); + } } - } + catch( Exception e ) + { + throw new ValueSerializationException( "Unable to deserialize manyassociation " + manyAssociation, e ); + } + } ); // NamedAssociations - for( AssociationDescriptor namedAssociation : valueCompositeType.namedAssociations() ) - { - String namedAssociationName = namedAssociation.qualifiedName().name(); - if( objectHasField( inputNode, namedAssociationName ) ) + valueCompositeType.namedAssociations().forEach( namedAssociation -> { + try { - Object value = getObjectFieldValue( - inputNode, - namedAssociationName, - buildDeserializeInputNodeFunction( MapType.of( String.class, EntityReference.class, Serialization.Variant.object ) ) ); - stateMap.put( namedAssociationName, value ); + String namedAssociationName = namedAssociation.qualifiedName().name(); + if( objectHasField( inputNode, namedAssociationName ) ) + { + Object value = getObjectFieldValue( + inputNode, + namedAssociationName, + buildDeserializeInputNodeFunction( MapType.of( String.class, EntityReference.class, Serialization.Variant.object ) ) ); + stateMap.put( namedAssociationName, value ); + } } - } + catch( Exception e ) + { + throw new ValueSerializationException( "Unable to deserialize namedassociation " + namedAssociation, e ); + } + } ); ValueBuilder valueBuilder = buildNewValueBuilderWithState( valueBuilderType, stateMap ); return (T) valueBuilder.newInstance(); // Unchecked cast because the builder could use a type != T @@ -698,23 +595,18 @@ public abstract class ValueDeserializerAdapter private Function buildDeserializeInputNodeFunction( final ValueType valueType ) { - return new Function() - { - @Override - public T apply( InputNodeType inputNode ) + return inputNode -> { + try { - try - { - return doDeserializeInputNodeValue( valueType, inputNode ); - } - catch( ValueSerializationException ex ) - { - throw ex; - } - catch( Exception ex ) - { - throw new ValueSerializationException( ex ); - } + return doDeserializeInputNodeValue( valueType, inputNode ); + } + catch( ValueSerializationException ex ) + { + throw ex; + } + catch( Exception ex ) + { + throw new ValueSerializationException( ex ); } }; } @@ -727,7 +619,7 @@ public abstract class ValueDeserializerAdapter { return null; } - final Class type = first( valueType.types() ); + final Class type = valueType.types().findFirst().orElse( null ); // Registered deserializers if( deserializers.get( type ) != null ) { @@ -743,38 +635,38 @@ public abstract class ValueDeserializerAdapter return (T) complexDeserializers.get( type ).deserializeTree( inputNode ); } else // Explicit ValueComposite - if( ValueCompositeType.class.isAssignableFrom( valueType.getClass() ) ) - { - return (T) deserializeNodeValueComposite( valueType, inputNode ); - } - else // Explicit Collections - if( CollectionType.class.isAssignableFrom( valueType.getClass() ) ) - { - return (T) deserializeNodeCollection( (CollectionType) valueType, inputNode ); - } - else // Explicit Map - if( MapType.class.isAssignableFrom( valueType.getClass() ) ) - { - MapType mapType = (MapType) valueType; - if( mapType.variant().equals( Serialization.Variant.entry ) ) - { - return (T) deserializeNodeEntryMap( (MapType) valueType, inputNode ); - } - else + if( ValueCompositeType.class.isAssignableFrom( valueType.getClass() ) ) { - return (T) deserializeNodeObjectMap( (MapType) valueType, inputNode ); + return (T) deserializeNodeValueComposite( valueType, inputNode ); } - } - else // Enum - if( EnumType.class.isAssignableFrom( valueType.getClass() ) || type.isEnum() ) - { - Object value = asSimpleValue( inputNode ); - if( value == null ) - { - return null; - } - return (T) Enum.valueOf( (Class) type, value.toString() ); - } + else // Explicit Collections + if( CollectionType.class.isAssignableFrom( valueType.getClass() ) ) + { + return (T) deserializeNodeCollection( (CollectionType) valueType, inputNode ); + } + else // Explicit Map + if( MapType.class.isAssignableFrom( valueType.getClass() ) ) + { + MapType mapType = (MapType) valueType; + if( mapType.variant().equals( Serialization.Variant.entry ) ) + { + return (T) deserializeNodeEntryMap( (MapType) valueType, inputNode ); + } + else + { + return (T) deserializeNodeObjectMap( (MapType) valueType, inputNode ); + } + } + else // Enum + if( EnumType.class.isAssignableFrom( valueType.getClass() ) || type.isEnum() ) + { + Object value = asSimpleValue( inputNode ); + if( value == null ) + { + return null; + } + return (T) Enum.valueOf( (Class) type, value.toString() ); + } // Guessed deserialization return (T) deserializeNodeGuessed( valueType, inputNode ); } @@ -783,54 +675,32 @@ public abstract class ValueDeserializerAdapter { return valuesModule().newValueBuilderWithState( type, - new Function() - { - @Override - public Object apply( PropertyDescriptor property ) - { - return stateMap.get( property.qualifiedName().name() ); - } - }, - new Function() - { - @Override - public EntityReference apply( AssociationDescriptor association ) + property -> stateMap.get( property.qualifiedName().name() ), + association -> { + Object entityRef = stateMap.get( association.qualifiedName().name() ); + if( entityRef == null ) { - Object entityRef = stateMap.get( association.qualifiedName().name() ); - if( entityRef == null ) - { - return null; - } - return (EntityReference) entityRef; + return null; } + return (EntityReference) entityRef; }, - new Function>() - { - @Override - @SuppressWarnings( "unchecked" ) - public Iterable apply( AssociationDescriptor manyAssociation ) + manyAssociation -> { + Object entityRefs = stateMap.get( manyAssociation.qualifiedName().name() ); + if( entityRefs == null ) { - Object entityRefs = stateMap.get( manyAssociation.qualifiedName().name() ); - if( entityRefs == null ) - { - return empty(); - } - return (Iterable) entityRefs; + return empty(); } + //noinspection unchecked + return (Iterable) entityRefs; }, - new Function>() - { - @Override - @SuppressWarnings( "unchecked" ) - public Map apply( AssociationDescriptor namedAssociation ) + namedAssociation -> { + Object entityRefs = stateMap.get( namedAssociation.qualifiedName().name() ); + if( entityRefs == null ) { - Object entityRefs = stateMap.get( namedAssociation.qualifiedName().name() ); - if( entityRefs == null ) - { - return Collections.emptyMap(); - } - return (Map) entityRefs; + return Collections.emptyMap(); } + //noinspection unchecked + return (Map) entityRefs; } ); } @@ -850,7 +720,7 @@ public abstract class ValueDeserializerAdapter throws Exception { Collection collection; - Class collectionMainType = first( collectionType.types() ); + Class collectionMainType = collectionType.types().findFirst().orElse( null ); if( Set.class.equals( collectionMainType ) ) { collection = new LinkedHashSet<>(); @@ -909,14 +779,17 @@ public abstract class ValueDeserializerAdapter } else // without _type info { - ValueDescriptor valueDescriptor = valuesModule().valueDescriptor( first( valueType.types() ).getName() ); + ValueDescriptor valueDescriptor = valuesModule().valueDescriptor( valueType.types() + .findFirst() + .get() + .getName() ); if( valueDescriptor == null ) { throw new ValueSerializationException( "Don't know how to deserialize " + inputNode ); } valueCompositeType = valueDescriptor.valueType(); } - Class valueBuilderType = first( valueCompositeType.types() ); + Class valueBuilderType = valueCompositeType.types().findFirst().orElse( null ); return deserializeValueComposite( valueCompositeType, valueBuilderType, inputNode ); } // Last resort : base64 java deserialization @@ -943,7 +816,7 @@ public abstract class ValueDeserializerAdapter byte[] bytes = inputString.getBytes( UTF_8 ); bytes = Base64Encoder.decode( bytes ); Object result; - try( ObjectInputStream oin = new ObjectInputStream( new ByteArrayInputStream( bytes ) ) ) + try (ObjectInputStream oin = new ObjectInputStream( new ByteArrayInputStream( bytes ) )) { result = oin.readObject(); } @@ -953,11 +826,13 @@ public abstract class ValueDeserializerAdapter // // Deserialization Extension Points // + /** * Called by the adapter on deserialization start, after {@link #adaptInput(java.io.InputStream)}. * * @param valueType ValueType - * @param input Input + * @param input Input + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ @SuppressWarnings( "UnusedParameters" ) @@ -971,7 +846,8 @@ public abstract class ValueDeserializerAdapter * Called by the adapter on deserialization end. * * @param valueType ValueType - * @param input Input + * @param input Input + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ protected void onDeserializationEnd( ValueType valueType, InputType input ) @@ -983,11 +859,14 @@ public abstract class ValueDeserializerAdapter // // Pull Parsing Deserialization // + /** * This method is always called first, this is a chance to wrap the input type. * * @param input InputStream to adapt + * * @return Adapted input + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ protected abstract InputType adaptInput( InputStream input ) @@ -995,23 +874,28 @@ public abstract class ValueDeserializerAdapter /** * @param input Input + * * @return a Plain Value read from the input + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ protected abstract Object readPlainValue( InputType input ) throws Exception; /** - * @param Parameterized collection type - * @param input Input + * @param Parameterized collection type + * @param input Input * @param deserializer Deserialization function - * @param collection Collection + * @param collection Collection + * * @return The filled collection or null if no array + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ protected abstract Collection readArrayInCollection( InputType input, Function deserializer, - Collection collection ) + Collection collection + ) throws Exception; /** @@ -1027,28 +911,33 @@ public abstract class ValueDeserializerAdapter *

And an empty Map:

*
[]
*

- * 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. + * 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. *

* - * @param Parameterized map key type - * @param Parameterized map value type - * @param input Input - * @param keyDeserializer Map key deserialization function + * @param Parameterized map key type + * @param Parameterized map value type + * @param input Input + * @param keyDeserializer Map key deserialization function * @param valueDeserializer Map value deserialization function - * @param map Map + * @param map Map + * * @return The filled map or null if no array + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ protected abstract Map readMapInMap( InputType input, Function keyDeserializer, Function valueDeserializer, - Map map ) + Map map + ) throws Exception; /** * @param input Input + * * @return an InputNodeType or null if the value was null + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ protected abstract InputNodeType readObjectTree( InputType input ) @@ -1068,21 +957,26 @@ public abstract class ValueDeserializerAdapter /** * Return null if the field do not exists. - * @param Parameterized object field value type - * @param inputNode Input Node - * @param key Object key + * + * @param Parameterized object field value type + * @param inputNode Input Node + * @param key Object key * @param valueDeserializer Deserialization function + * * @return The value of the field. + * * @throws Exception that will be wrapped in a {@link ValueSerializationException} */ protected abstract T getObjectFieldValue( InputNodeType inputNode, String key, - Function valueDeserializer ) + Function valueDeserializer + ) throws Exception; protected abstract void putArrayNodeInCollection( InputNodeType inputNode, Function deserializer, - Collection collection ) + Collection collection + ) throws Exception; protected abstract void putArrayNodeInMap( InputNodeType inputNode, http://git-wip-us.apache.org/repos/asf/zest-java/blob/bd6fbad9/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java b/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java index d9b2127..632602c 100644 --- a/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java +++ b/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java @@ -27,12 +27,8 @@ import java.util.HashMap; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; import org.apache.zest.api.ZestAPI; import org.apache.zest.api.association.Association; -import org.apache.zest.api.association.AssociationDescriptor; import org.apache.zest.api.association.AssociationStateHolder; import org.apache.zest.api.association.ManyAssociation; import org.apache.zest.api.association.NamedAssociation; @@ -40,15 +36,15 @@ import org.apache.zest.api.composite.CompositeInstance; import org.apache.zest.api.entity.EntityComposite; import org.apache.zest.api.entity.EntityReference; import org.apache.zest.api.property.Property; -import org.apache.zest.api.property.PropertyDescriptor; import org.apache.zest.api.util.Base64Encoder; import org.apache.zest.api.util.Dates; import org.apache.zest.api.value.ValueComposite; import org.apache.zest.api.value.ValueDescriptor; import org.apache.zest.api.value.ValueSerializationException; import org.apache.zest.api.value.ValueSerializer; - -import static org.apache.zest.functional.Iterables.first; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; /** * Adapter for pull-parsing capable ValueSerializers. @@ -95,14 +91,7 @@ public abstract class ValueSerializerAdapter private static BiFunction identitySerializer() { - return new BiFunction() - { - @Override - public TO apply( Options options, FROM from ) - { - return from; - } - }; + return ( options, from ) -> from; } private final Map, BiFunction> serializers = new HashMap<>( 16 ); @@ -148,107 +137,38 @@ public abstract class ValueSerializerAdapter registerSerializer( Double.class, ValueSerializerAdapter.identitySerializer() ); // Number types - registerSerializer( BigDecimal.class, new BiFunction() - { - @Override - public Object apply( Options options, BigDecimal bigDecimal ) - { - return bigDecimal.toString(); - } - } ); - registerSerializer( BigInteger.class, new BiFunction() - { - @Override - public Object apply( Options options, BigInteger bigInteger ) - { - return bigInteger.toString(); - } - } ); + registerSerializer( BigDecimal.class, ( options, bigDecimal ) -> bigDecimal.toString() ); + registerSerializer( BigInteger.class, ( options, bigInteger ) -> bigInteger.toString() ); // Date types - registerSerializer( Date.class, new BiFunction() - { - @Override - public Object apply( Options options, Date date ) - { - return Dates.toUtcString( date ); - } - } ); - registerSerializer( DateTime.class, new BiFunction() - { - @Override - public Object apply( Options options, DateTime date ) - { - return date.toString(); - } - } ); - registerSerializer( LocalDateTime.class, new BiFunction() - { - @Override - public Object apply( Options options, LocalDateTime date ) - { - return date.toString(); - } - } ); - registerSerializer( LocalDate.class, new BiFunction() - { - @Override - public Object apply( Options options, LocalDate date ) - { - return date.toString(); - } - } ); + registerSerializer( Date.class, ( options, date ) -> Dates.toUtcString( date ) ); + registerSerializer( DateTime.class, ( options, date ) -> date.toString() ); + registerSerializer( LocalDateTime.class, ( options, date ) -> date.toString() ); + registerSerializer( LocalDate.class, ( options, date ) -> date.toString() ); // Other supported types - registerSerializer( EntityReference.class, new BiFunction() - { - @Override - public Object apply( Options options, EntityReference ref ) - { - return ref.toString(); - } - } ); + registerSerializer( EntityReference.class, ( options, ref ) -> ref.toString() ); } @Override public final Function serialize() { - return new Function() - { - @Override - public String apply( T object ) - { - return serialize( object ); - } - }; + return object -> serialize( object ); } @Override public final Function serialize( final Options options ) { - return new Function() - { - @Override - public String apply( T object ) - { - return serialize( options, object ); - } - }; + return object -> serialize( options, object ); } @Override @Deprecated public final Function serialize( final boolean includeTypeInfo ) { - return new Function() - { - @Override - public String apply( T object ) - { - return serialize( includeTypeInfo ? new Options().withTypeInfo() : new Options().withoutTypeInfo(), - object ); - } - }; + return object -> serialize( + includeTypeInfo ? new Options().withTypeInfo() : new Options().withoutTypeInfo(), + object ); } @Override @@ -420,72 +340,96 @@ public abstract class ValueSerializerAdapter { onFieldStart( output, "_type" ); onValueStart( output ); - onValue( output, first( descriptor.valueType().types() ).getName() ); + onValue( output, descriptor.valueType().types().findFirst().orElse( null )); onValueEnd( output ); onFieldEnd( output ); } - for( PropertyDescriptor persistentProperty : descriptor.valueType().properties() ) - { + descriptor.valueType().properties().forEach( persistentProperty -> { Property property = state.propertyFor( persistentProperty.accessor() ); - onFieldStart( output, persistentProperty.qualifiedName().name() ); - onValueStart( output ); - doSerialize( options, property.get(), output, false ); - onValueEnd( output ); - onFieldEnd( output ); - } - for( AssociationDescriptor associationDescriptor : descriptor.valueType().associations() ) - { + try + { + onFieldStart( output, persistentProperty.qualifiedName().name() ); + onValueStart( output ); + doSerialize( options, property.get(), output, false ); + onValueEnd( output ); + onFieldEnd( output ); + } + catch( Exception e ) + { + throw new ValueSerializationException( "Unable to serialize property " + persistentProperty, e ); + } + } ); + descriptor.valueType().associations().forEach(associationDescriptor -> { Association association = state.associationFor( associationDescriptor.accessor() ); - onFieldStart( output, associationDescriptor.qualifiedName().name() ); - onValueStart( output ); - EntityReference ref = association.reference(); - if( ref == null ) + try { - onValue( output, null ); + onFieldStart( output, associationDescriptor.qualifiedName().name() ); + onValueStart( output ); + EntityReference ref = association.reference(); + if( ref == null ) + { + onValue( output, null ); + } + else + { + onValue( output, ref.identity() ); + } + onValueEnd( output ); + onFieldEnd( output ); } - else + catch( Exception e ) { - onValue( output, ref.identity() ); + throw new ValueSerializationException( "Unable to serialize association " + associationDescriptor, e ); } - onValueEnd( output ); - onFieldEnd( output ); - } - for( AssociationDescriptor associationDescriptor : descriptor.valueType().manyAssociations() ) - { + } ); + descriptor.valueType().manyAssociations().forEach( associationDescriptor -> { ManyAssociation manyAssociation = state.manyAssociationFor( associationDescriptor.accessor() ); - onFieldStart( output, associationDescriptor.qualifiedName().name() ); - onValueStart( output ); - onArrayStart( output ); - for( EntityReference ref : manyAssociation.references() ) + try { + onFieldStart( output, associationDescriptor.qualifiedName().name() ); onValueStart( output ); - onValue( output, ref.identity() ); + onArrayStart( output ); + for( EntityReference ref : manyAssociation.references() ) + { + onValueStart( output ); + onValue( output, ref.identity() ); + onValueEnd( output ); + } + onArrayEnd( output ); onValueEnd( output ); + onFieldEnd( output ); } - onArrayEnd( output ); - onValueEnd( output ); - onFieldEnd( output ); - } - for( AssociationDescriptor associationDescriptor : descriptor.valueType().namedAssociations() ) - { + catch( Exception e ) + { + throw new ValueSerializationException( "Unable to serialize manyassociation " + associationDescriptor, e ); + } + }); + descriptor.valueType().namedAssociations().forEach( associationDescriptor -> { NamedAssociation namedAssociation = state.namedAssociationFor( associationDescriptor.accessor() ); - onFieldStart( output, associationDescriptor.qualifiedName().name() ); - onValueStart( output ); - onObjectStart( output ); - for( String name : namedAssociation ) + try { - onFieldStart( output, name ); + onFieldStart( output, associationDescriptor.qualifiedName().name() ); onValueStart( output ); - EntityReference ref = namedAssociation.referenceOf( name ); - onValue( output, ref.identity() ); + onObjectStart( output ); + for( String name : namedAssociation ) + { + onFieldStart( output, name ); + onValueStart( output ); + EntityReference ref = namedAssociation.referenceOf( name ); + onValue( output, ref.identity() ); + onValueEnd( output ); + onFieldEnd( output ); + } + onObjectEnd( output ); onValueEnd( output ); onFieldEnd( output ); } - onObjectEnd( output ); - onValueEnd( output ); - onFieldEnd( output ); - } + catch( Exception e ) + { + throw new ValueSerializationException( "Unable to serialize namedassociation " + associationDescriptor, e ); + } + } ); onObjectEnd( output ); } @@ -516,6 +460,7 @@ public abstract class ValueSerializerAdapter { @SuppressWarnings( "unchecked" ) Map map = (Map) object; + //noinspection ConstantConditions if( options.getBoolean( Options.MAP_ENTRIES_AS_OBJECTS ) ) { onObjectStart( output );