Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Current state overview

Framework should help the developers to build their apps with Magnolia faster, get access to the components and features, framework though should not be all the time in the way of the developer.

...

How to share context and provide injectable components

  • Rely less on the Guice injection when it comes to the views. 
  • Enhance the views with the 'factory' capabilities that abstract away the communication with the session store

    Code Pro
    languagejava
    titleFrameworkView
    public interface UiFrameworkView extends View {
    
        /**
         * Convenience method implementation.
         */
        @Override
        default Component asVaadinComponent() {
            if (this instanceof Component) {
                return (Component) this;
            } else {
                throw new RuntimeException();
            }
        }
    
        /**
         * Wrapper around {@link ComponentProvider} capabilities.
         */
        @SuppressWarnings("unchecked")
        default <T> T create(Class type, Object... args) {
            return getComponentProvider().newInstance((Class<T>) type, args);
        }
    
        default ViewProvider getViewProvider() {
            return new ViewProvider.Impl(getCurrentViewReference());
        }
    
        default ComponentProvider getComponentProvider() {
            return new ViewComponentProvider(getCurrentViewReference());
        }
    
        default UiContextReference getCurrentViewReference() {
            return ViewContextKeyRegistry.access()
                    .lookUp(this)
                    .orElseGet(() -> CurrentUiContextReference.get().getUiContextReference());
        }
    
        default <T extends ViewContext> T bindContext(Class<? extends T> contextClass) {
            final T context = new ViewContextProxy().createViewContext(contextClass);
            SessionStore.access().getBeanStore(getCurrentViewReference()).put(contextClass, context);
            return context;
        }
    
        default void bindDatasource(Object definition) {
            SessionStore.access().getBeanStore(getCurrentViewReference()).put(DatasourceHolder.class, new DatasourceHolder(definition));
        }
    }
    
    
    

How to bind to different data sources

Code Pro
languagejava
@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);
}


Code Pro
languagejava
titleProvisioning 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;
    }
}


...