felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Leangen <o...@leangen.net>
Subject Re: [Converter] Serializer
Date Sun, 21 Aug 2016 05:46:19 GMT

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 <seijoed@gmail.com> 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 <osgi@leangen.net> 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 <osgi@leangen.net> 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 );
>>>  }
>>> }
>>> 
>> 
> 


Mime
View raw message