Skip to content

Using Beans in composite #526

Open
Open
@F43nd1r

Description

@F43nd1r

I have a class like this

@SpringComponent
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class CardView extends Div {

    @Autowired
    public CardView(...some services...) {
        ...
    }
}

which I would like to use in a composite:

public class SpringCompositeDemo extends Composite<CardView> {

This is currently not possible. My workaround is to extend Composite:

@SpringComponent
public abstract class SpringComposite<T extends Component> extends Composite<T> {
    private ApplicationContext applicationContext;

    @SuppressWarnings("unchecked")
    @Override
    protected T initContent() {
        Class<? extends Component> contentType = findContentType((Class<? extends Composite<?>>) getClass());
        if (AnnotationUtils.findAnnotation(contentType, org.springframework.stereotype.Component.class) != null)
            if (applicationContext != null) {
                return (T) applicationContext.getBean(contentType);
            } else {
                throw new IllegalStateException("Cannot access Composite content before bean initialization");
            }
        return (T) ReflectTools.createInstance(contentType);
    }

    @Autowired
    public final void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    /*
     * copied from Composite#findContentType(Class)
     */
    private static Class<? extends Component> findContentType(
            Class<? extends Composite<?>> compositeClass) {
        Type type = GenericTypeReflector.getTypeParameter(
                compositeClass.getGenericSuperclass(),
                Composite.class.getTypeParameters()[0]);
        if (type instanceof Class || type instanceof ParameterizedType) {
            return GenericTypeReflector.erase(type).asSubclass(Component.class);
        }
        throw new IllegalStateException(getExceptionMessage(type));
    }

    /*
     * copied from Composite#getExceptionMessage(Type)
     */
    private static String getExceptionMessage(Type type) {
        if (type == null) {
            return "Composite is used as raw type: either add type information or override initContent().";
        }

        if (type instanceof TypeVariable) {
            return String.format(
                    "Could not determine the composite content type for TypeVariable '%s'. "
                            + "Either specify exact type or override initContent().",
                    type.getTypeName());
        }
        return String.format(
                "Could not determine the composite content type for %s. Override initContent().",
                type.getTypeName());
    }
}

It would be nice to have this work out of the box.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions