So i have two database tables which hold different types of beans. The first table named: Export
is made up of a number of different bean names which are implement the Exporter
interface defined as:
public interface Exporter<ExportType> {
List<ExportType> export();
}
The second table, named Export Action
is made up of action beans that operate on the exported objects that are returned from the Exporter
bean. There are two types of action beans, TRANSFORM
beans which basically take as input the output from the exporter bean, and transform it into a different object, as defined by the second generic parameter type. The interface for this bean is defined as:
public interface ExportTransform<ExportType, TransformType> {
List<TransformType> transform(List<ExportType> exportObjects);
}
The other type of action bean is a PROCESS
bean. These beans take the output from the transformation and process them (persists them) and returns the entity objects back. This process interface is defined as:
public interface ExportPostProcess<TransformType, ProcessResult> {
List<ProcessResult> postProcess(List<TransformType> transformObjects);
}
For this example, here's some example data for these two tables:
Table: Export
|----------------------------------------------------------------------------------|
| ID | Bean Name | Creation Time | Modification Time |
|----------------------------------------------------------------------------------|
| 1 | documentExporter | 2010-10-09 10:10:09 | 2010-10-10 12:09:10 |
|----------------------------------------------------------------------------------|
Table: Export Action
|------------------------------------------------------------------|
| ID | Type | Bean Name | Export ID |
|------------------------------------------------------------------|
| 1 | TRANSFORM | documentRulesetTransformer | 1 |
| 1 | PROCESS | rulesetProcessor | 1 |
|------------------------------------------------------------------|
These beans have been implemented the corresponding interfaces as follows:
@Component
public class DocumentExporter implements Exporter<Document> {
public List<Document> export() {
// export
return Collections.emptyList();
}
}
@Component
public class DocumentRulesetTransformer implements ExportTransform<Document, RulesetVO> {
public List<RulesetVO> transform(List<Document> transformObjects) {
// transform
return Collections.emptyList();
}
}
@Component
public class RulesetProcessor implements ExportPostProcess<RulesetVO, Ruleset> {
public List<Ruleset> postProcess(List<RulesetVO> transformObjects) {
// process
return Collections.emptyList();
}
}
Finally... My question is.. what is the best way to manage this in terms of generics without needing a bunch of explicit casts or @SupressWarnings("unchecked")
everywhere? Considering this data is dynamic, and so are the bean implementations.
Currently I have code like the following (simplified for readability):
Set<Export> exportBeans = exportRepository.findAll();
exportBeans.forEach(export -> {
Exporter<?> exporter = applicationContext.getBean(export.getBeanName(), Exporter<?>.class);
List<?> exportObjects = exporter.export();
ExportTransform<?, ?> transformer = export.getActions.get(ActionType.TRANSFORM);
List<?> transformedObjects = transformer.transform(exportObjects);
ExportPostProcess<?, ?> postProcessor = export.getActions.get(ActionType.PROCESS);
List<?> processedObjects = postProcessor.postProcess(transformObjects);
});
At the moment, I have to use reflection to validate the bean implementations are supported as per their generic types. I.E the rulesetProcess¬ bean is able to accept the result of the
documentResultTransformer` bean. Which is cumbersome and nasty. I would love to think there was something I could utilize which takes care of this for me to some degree.
Any help would be greatly appreciated.
Aucun commentaire:
Enregistrer un commentaire