The following could be a looser and more flexible replacement for the ContentConnector
abstraction. Instead of having the monolithic interface, we rather could facilitate a DatasourceSupport
that could provide data-binding implementations based on the exposed configuration by e.g. delegating to the registered reference implementations.
How to bind to different data sources
Questions:
- It is pretty clear that DataProvider and PropertySet domain-specific implementaions are required. But what else?
- optional HierarchicalDataProvider and potentially additional Hierarchy support for parent resolution (not covered by HDP interface in Vaadin).
- utilities to "serialise"/"deserialise" items to and from URL fragments.
- utility to "describe" the items (for status purposes and such).
@Singleton public class DatasourceSupport { private final Map<Class, DatasourceBundle> bundles; @Inject public DatasourceSupport(Set<DatasourceBundle> bundles) { this.bundles = bundles .stream() .collect(toMap( DatasourceBundle::supportedDataSourceType, identity())); } @SuppressWarnings("unchecked") public <DEF> DatasourceBundle<DEF> getDatasourceBundle(DEF def) { Objects.requireNonNull(def); return Optional.ofNullable(bundles.get(def.getClass())).orElseThrow(() -> new IllegalArgumentException("No such bundle for the type " + def.getClass())); } } @Multibinding public abstract class DatasourceBundle<DEF> { private final Class<DEF> type; public DatasourceBundle(Class<DEF> type) { this.type = type; } public Class<DEF> supportedDataSourceType() { return this.type; } public abstract <T> T lookup(Class<T> type, DEF definition); }
Provisioning of datasource components
public class DatasourceComponentParameterResolver implements ParameterResolver { private final DatasourceSupport datasourceSupport; private final Object datasourceDefinition; public DatasourceComponentParameterResolver(DatasourceSupport datasourceSupport, Object datasourceDefinition) { this.datasourceSupport = datasourceSupport; this.datasourceDefinition = datasourceDefinition; } @Override public Object resolveParameter(ParameterInfo parameter) { boolean isDatasourceComponent = Stream.of(parameter.getParameterAnnotations()).anyMatch(DatasourceComponent.class::isInstance); if (isDatasourceComponent) { return datasourceSupport .getDatasourceBundle(datasourceDefinition) .lookup(parameter.getParameterType(), datasourceDefinition); } return UNRESOLVED; } }
Overview
Content Tools