domino-jackson icon indicating copy to clipboard operation
domino-jackson copied to clipboard

Generating reader/writer should generate only the supported methods

Open rjeeb opened this issue 5 years ago • 3 comments

When generating reader or writer, the generated mapper should only support related methods.

For example, when generating a reader, then only read methods should be accessible and same goes for the writer.

Possible solution: When generating mapper, it will extend AbstractObjectReader/AbstractObjectWriter and these two abstract classes extend AbstractObjectMapper. By removing this extend, only the supported methods will be available.

rjeeb avatar Nov 11 '20 17:11 rjeeb

If I understand you right, you need to be very careful about this - consider the case where a project has two mappers, and they use some overlapping POJOs, so they share code. If one mapper only reads and the second one reads and writes, you don't want to risk a case where you don't generate the write method.

I don't recall exactly where these are generated, but you also have to take care if the mappers are in a different project, and two different projects generate incompatible implementations, then are both brought into the same classpath. Imagine a DTO jar which just has the POJOs, and two service jars, which each have their own mapper (using the DTO jar), but don't depend on each other, and then an app project which depends on all of the above.

niloc132 avatar Nov 13 '20 17:11 niloc132

Isnt this the same as to services depending on 2 different versions of a jar?

And how does generating a write method for a reader that only throws an exception will solve this issue?!

vegegoku avatar Nov 14 '20 16:11 vegegoku

I don't fully understand the issue, but I ran into a similar problem in gwt-rpc, which is why I just wanted to be sure you are considering it fully. If there is an exception occurring in domino-jackson that I'm not seeing in the issue, I might be misinterpreting what the issue is about.

Assuming that this is about making sure unused code can be pruned, the way I solved this is roughly like this:

  • make a static read and write method, always generate these
  • make three inner classes, which implement that read/write interfaces (if any) - one is readonly, one is writeonly, one is read-write
  • the above type now can be always created, needed or not
  • the mapper will reference only the inner class it cares about
  • the compiler will prune any unneeded one, and any unneeded static methods

rough example:

public class PersonSerializer {
  public static Person read(ReadStream stream) {
    Person p = new Person();
    //...
    return p;
  }
  public static void write(Person object, WriteStream stream) {
    if (object != null) {
      stream.startObject();
      //...
      stream.endObject();
    }
  }
  public static class BaseClass implements Serializer<Person> {
    public Person read(ReadStream stream) { throw new UnsupportedOperationException("Person"); }
    public void write(Person person, WriteStream stream) { throw new UnsupportedOperationException("Person"); }
  }
  public static class ReadOnly extends BaseClass {
    public Person read(ReadStream stream) { return readPerson(stream); }
  }
  public static class WriteOnly extends BaseClass {
    public void write(Person object, ReadStream stream) { return writePerson(object, stream); }
  }
  public static class ReadWrite extends BaseClass {
    public Person read(ReadStream stream) { return readPerson(stream); }
    public void write(Person object, ReadStream stream) { return writePerson(object, stream); }
  }
}

niloc132 avatar Nov 15 '20 16:11 niloc132