I'm new to generics. I have an abstract class (1) with an abstract method. I have another abstract class (2) with a few abstract methods that I want shared in some DTOs (3,4). I want a concrete extension of (1) to work on anything that extends (2).
1.
//I want R to be anything here
public abstract class AggregatedEmailerRoute<R> extends RouteBuilder {
public static String EMAILER_ROUTE = "direct:aggregated-emailer-route";
@Override
public void configure() throws Exception {
from(EMAILER_ROUTE)
.bean(this, "convertToEmailBody(${body},${headers})")
.to("mock:wherever");
}
protected abstract String convertToEmailBody(List<R> body, Map<String,Object> headers);
public abstract class StagingError { //or should this be an interface?
public abstract Integer getId();
public abstract String getErrorNote();
public abstract LocalDateTime getErrorDate();
}
Two classes that extend StagingError: 3.
public class Bill extends StagingError {
private Integer id;
private String errorNote;
private LocalDateTime getErrorDate;
//other fields, getters/setters
public class Payment extends StagingError {
private Integer id;
private String errorNote;
private LocalDateTime getErrorDate;
//other fields, getters/setters
public class StagingEmailErrorRoute extends AggregatedEmailerRoute<R extends StagingError> {
@Override
public void configure() throws Exception {
super.configure();
from(jpa(Bill.class.getName())
.query("some query")
)
.to(EMAILER_ROUTE);
from(jpa(Payment.class.getName())
.query("some other query")
)
.to(EMAILER_ROUTE);
}
@Override //But here I want to work on anything that implements StagingError so this method can work on Payment OR Bill
protected String convertToEmailBody(List<T extends StagingError> body, Map<String,Object> headers) {
return
body
.stream()
.map(e -> "Staging entity ID: " + e.getId() +
"\n\tError: " + e.getErrorNote() +
"\n\tWhen: " + format("%tc",e.getErrorDate().atZone(EST.get())) +
"\n")
.collect(joining("\n"));