Hi Johan,

Thanks for your thoughts. Are you able to elaborate a little more?

> Whenever you serialize and say “Hey’ let’s use polymorphism", you are pretty 
> much bound to fail.

I’m not sure why you say this. I thought that by including the schema 
information, that is exactly what we were avoiding…

I’m not sure I’m getting your idea about the command pattern. Would you mind 
showing me a quick example?

Cheers,
=David



> On Aug 21, 2016, at 2:42 PM, Johan Edstrom <[email protected]> wrote:
> 
> Whenever you serialize and say “Hey’ let’s use polymorphism", you are pretty 
> much bound to fail.
> 
> Use something like a command pattern identifying what you are doing 
> so you can pick the de-serializer. 
> 
> 
> 
>> On Aug 20, 2016, at 11:32 PM, David Leangen <[email protected]> wrote:
>> 
>> 
>> I had a few thoughts about this topic.
>> 
>> In order to properly deserialise, we would need the schema. Since the DTO 
>> type *is* the schema, then somehow the schema needs to be serialised as 
>> well, or at least known upon serialisation.
>> 
>> If the API were to have a toSchema() method, that would simplify things a 
>> lot. A client should also be able to do something like this:
>> 
>> SomeDTO dto = ...
>> codec.encode( dto ).serializeTo( out );
>> 
>> Or maybe:
>> 
>> codec.withSchema( SomeDTO.class).encode( dto ).to( out );
>> 
>> The SomeDTO schema would also be serialised (perhaps simply using the 
>> fully-qualified class name as an alias?), so then the client could do this:
>> 
>> Object o = codec.deserializeFrom( in )
>> 
>> Since the schema is included in the input data, the serializer will behind 
>> the scene do something like:
>> 
>> 
>>  Map<String, Object> map = codec.decode( Map.class ).from( in );
>>  // Get the schema type, which is SomeDTO.class
>>  ...
>>  Object o = converter.convert( map.get(“data”) ).to( SomeDTO.class );
>> 
>> 
>> wdyt?
>> 
>> =David
>> 
>> 
>> 
>>> On Aug 20, 2016, at 3:23 PM, David Leangen <[email protected]> wrote:
>>> 
>>> 
>>> Hi,
>>> 
>>> I am trying to use the Convert/Codec as a serializer, but it has been a bit 
>>> of a struggle so far.
>>> 
>>> I have a “deep” object structure (i.e. at least one level of embedded 
>>> objects). Writing the data as a JSON string works just fine. However, when 
>>> deserialising, I am having trouble. The data object uses generics, so it is 
>>> not possible to determine the type at runtime. My embedded objects end up 
>>> being deserialised as Maps, which of course causes a ClassCastException 
>>> later on in the code.
>>> 
>>> I have tried adding a Rule using an adapter, and setting the 
>>> codec.with(thatAdapter), but that didn’t work out so well, either.
>>> 
>>> Here is an example of my attempt so far. I am working with Prevayler, so I 
>>> need to serialize/deserialze a command object, which contains some data.
>>> 
>>> I think that this code _should_ work, which means that there is likely a 
>>> bug in the code. Even so…
>>> 
>>> This is a very convoluted way of working, which doesn’t seem right to me. 
>>> Am I missing some concept?
>>> 
>>> 
>>> Example below.
>>> 
>>> Cheers,
>>> =David
>>> 
>>> 
>>> public class DTOSerializer<E>
>>>      implements Serializer // This is the interface provided by Prevayler
>>> {
>>>  private final Converter converter;
>>>  private final Codec codec;
>>>  private final Class<E> type;
>>> 
>>>  public DTOSerializer( Converter aConverter, Codec aCodec, Class<E> aType )
>>>  {
>>>     // Very convoluted attempt at adding a rule to try to make the 
>>> conversion of my “PutCommand” work during deserialization
>>>      converter = aConverter.getAdapter()
>>>              .rule( 
>>>                      PutCommand.class, 
>>>                      Map.class, 
>>>                      dto -> { Map map = new HashMap<>(); map.put( "key", 
>>> dto.key ); map.put( "entity", dto.entity ); return map; }, 
>>>                      map -> { PutCommand c = new PutCommand(); c.key = 
>>> (String)map.get( "key" ); c.entity = aConverter.convert( map.get( "entity" 
>>> ) ).to( aType ); return c; } );
>>>      codec = aCodec.with( converter );
>>>  }
>>> 
>>>  @Override
>>>  public Object readObject( InputStream in )
>>>          throws Exception
>>>  {
>>>     // This is the raw data
>>>      final Map<String, Object> map = codec.decode( Map.class ).from( in );
>>>     // The name of the object type to cast to
>>>      final String commandTypeName = (String)map.get( "command" );
>>>      final Class<?> commandType = Class.forName( commandTypeName );
>>>     // This indeed returns an object of the correct type,
>>>     // HOWEVER, the embedded objects are not of the correct type, they are 
>>> of type Map
>>>      final Object command = converter.convert( map.get( "payload" ) ).to( 
>>> commandType );
>>>      return command;
>>>  }
>>> 
>>>  @Override
>>>  public void writeObject( OutputStream out, Object object )
>>>          throws Exception
>>>  {
>>>      final Map<String, Object> map = new HashMap<>();
>>>     // Serialize the name of the command so I know what to cast it do when 
>>> deserializing
>>>      map.put( "command", object.getClass().getName() );
>>>     // This is the actual payload, which is nothing more than the command 
>>> object
>>>      map.put( "payload", object );
>>>      codec.encode( map ).to( out );
>>>  }
>>> }
>>> 
>> 
> 

Reply via email to