Page tree
Skip to end of metadata
Go to start of metadata

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?
  • (question) optional HierarchicalDataProvider and potentially additional Hierarchy support for parent resolution (not covered by HDP interface in Vaadin).
  • (question) utilities to "serialise"/"deserialise" items to and from URL fragments.
  • (question) 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;
    }
}

  • No labels