matteobaccan / owner

Get rid of the boilerplate code in properties based configuration.
https://matteobaccan.github.io/owner/
BSD 3-Clause "New" or "Revised" License
917 stars 213 forks source link

Feature Required: DisableFeature.TOKENIZATION #206

Open shariqislam786 opened 7 years ago

shariqislam786 commented 7 years ago

Hi,

I have written custom converter which converts json properties into objects specified in reloadable interface.

my json convertor

public class JsonConvertor implements Converter<Object>{
     public Object convert(Method method, String input) {
    ObjectMapper mapper = new ObjectMapper();
    try {
            return mapper.readValue(input, 
                  mapper.getTypeFactory().constructType(method.getGenericReturnType()));
    }catch (IOException e) {
          throw new RuntimeException(e);
    }  
  }
 }

example:

public interface TestProps extends Reloadable{
    @ConverterClass(JsonConvertor.class)
    SomeObject object();
}

This works fine for all simple objects, maps etc. but for collections this breaks because owner tokenizes collections and pass the chunks to converter. resulting in unparsable json. for example below it doesn't work.


public interface TestProps extends Reloadable{
    @ConverterClass(JsonConvertor.class)
    List<SomeObject> object();
}

if there was way to disable tokenization this wouldn't be a issue. if i use my own tokenization class then issue arises that in convert method of converter i have only method object from which i can get the return type and make my object. but i cannot get the class of object owner is trying to create(element class of collection)

lviggiano commented 7 years ago

Hi.

At the moment there is no way to disable collection tokenization. well, actually a trick could be specifying a separator that is never used, such as @Separator("\u0000") or something like that; but in this case you would get a List of a single object.

What I would do instead is to create a container class such as:

class JsonContainer<V> {
    public V value;

    public JsonContainer(V value) {
        this.value = value;
    }

    public V get() {
        return value; 
    }
}

And have your converter class returning a JsonContainer<List<SomeObject>>.

I understand that this is not pretty elegant.

You can evaluate to use AtomicReference class, instead of a custom "JsonContainer" as I explained above, which has a similar interface, but it's designed for multithreaded access, and the internals of the class are not trivial, so I would not recommend that.

Or you can wrap your JSoN collection into a container object:

from a list: [ 'a', 'b', 'c' ] to an object containing a list: { 'items' : [ 'a' , 'b' , 'c' ] }

And change the return type of your Config class accordingly. This should work too.

Some proper solutions to your problem I can think of would be:

But this require changing the codebase of OWNER, and at the moment I can't work on it for personal reasons.
Adding new features to OWNER is not very trivial, and requires a good amount of extra work (testing, documentation, etc), and this is also one of the reasons why recently I didn't do any release, since documentation is incomplete, and test coverage has been slightly lowered on the master branch, and maven release process on sonatype, last time I did, was quite a hell.

Hope this helps. L.

PreXident commented 5 years ago

Hi, are there any news about this? I have implemented a minimalist @CollectionConverterClass by myself and used class shadowing to plug it into Converters. I understand that adding something similar into the library is much more complicated that just adding a few lines of code as I did, but it would be nice to have an official support. Thanks for info & great library!

lviggiano commented 5 years ago

Hi.

There are no plans, since I am working for a private company and I need to verify if they are fine with the open source contribution before legally compromising this project. On the other end, I developed this project by my own, in my spare time, because I needed it. Now I am not using it, since I am fixing bug with legacy code at work, not fun but that's life. I wish some company could sponsor this project or some features of it, but I didn't find so far.

If you want you can contribute your code, and I'll eventually merge it.

Luigi