The automapper I'm using, AutoMatter, allows inheritance, e.g.
@AutoMatter
public interface BaseClass {
Foo foo();
Bar bar();
}
@AutoMatter
public interface DerivedClass extends BaseClass {
Baz baz();
}
but its generated builders are not polymorphic, i.e. they are
@Generated("io.norberg.automatter.processor.AutoMatterProcessor")
public final class DerivedClassBuilder {
private Foo foo;
private Bar bar;
private Baz baz;
public DerivedClassBuilder() {}
private DerivedClassBuilder(DerivedClass v) {
this.foo = v.foo();
this.bar = v.bar();
this.baz = v.baz();
}
private DerivedClassBuilder(DerivedClassBuilder v) {
this.foo = v.foo;
this.bar = v.bar;
this.baz = v.baz;
}
// (getters and setters for the builder)
public DerivedClass build() {
// ...
}
public DerivedClassBuilder from(DerivedClass v) {
return new DerivedClassBuilder(v);
}
public DerivedClassBuilder from(DerivedClassBuilder v) {
return new DerivedClassBuilder(v);
}
// a few more things like hash(), equals(), etc.
}
The thing I need but isn't there is
public DerivedClassBuilder from(BaseClass v) {
// ...
}
This means, for example, if I have many common fields in the base class, but several different derived classes, I have to build all the common fields manually at some point, e.g.
DerivedClassBuilder builder = new DerivedClassBuilder();
builder.foo(foo);
builder.bar(bar);
builder.baz(baz);
instead of being able to do
DerivedClassBuilder builder = new DerivedClassBuilder(baseClassBuilder);
builder.baz(baz);
...which somewhat destroys the purpose of inheritance in the first place.
If I'm constrained to using this library, is there a pattern that can help me genericize this bit?
I've played around with adding a static helper method in the base interface, using generics to try to represent any derived class, but I seem to get stuck due to type erasure. And there is nothing like derivedClass.BuilderType
to help me even if I try to use a copy-intersect library like Dozer.
Admittedly I'm new to Java, so I think either I'm missing something obvious, or it's simply impossible to do what I want to do, given builders that have no relation whatsoever to one another.