All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.devbench.uibuilder.spring.component.ControllerBeanComponentInjectionBeanFactory Maven / Gradle / Ivy

/*
 *
 * Copyright © 2018 Webvalto Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.devbench.uibuilder.spring.component;

import com.vaadin.flow.component.Component;
import io.devbench.uibuilder.api.controllerbean.UIComponent;
import io.devbench.uibuilder.core.controllerbean.ControllerBeanManager;
import io.devbench.uibuilder.core.utils.reflection.PropertyMetadata;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Nonnull;
import javax.inject.Provider;
import java.util.function.Supplier;

@Service
public class ControllerBeanComponentInjectionBeanFactory implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class beanClass = bean.getClass();
        ReflectionUtils.doWithFields(beanClass, field -> {
            String componentId = field.getAnnotation(UIComponent.class).value();
            boolean accessible = field.isAccessible();
            field.setAccessible(true);
            Class fieldType = field.getType();

            if (ObjectProvider.class.isAssignableFrom(fieldType) || Provider.class.isAssignableFrom(fieldType)) {
                @SuppressWarnings("unchecked")
                Class componentType = (Class) PropertyMetadata.findGenericType(field)
                    .filter(Component.class::isAssignableFrom)
                    .orElse(null);

                if (componentType != null) {
                    field.set(bean, new ComponentObjectProvider<>(() -> findComponentById(componentId, componentType)));
                }
            }

            field.setAccessible(accessible);
        }, field -> field.getAnnotation(UIComponent.class) != null);
        return bean;
    }

    private Component findComponentById(@NotNull String componentId, @NotNull Class componentClass) {
        return ControllerBeanManager
            .getInstance()
            .getAllCachedComponentInjectionPoint()
            .stream()
            .filter(componentInjectionPoint -> componentId.equals(componentInjectionPoint.getId()))
            .findFirst()
            .map(componentInjectionPoint -> componentInjectionPoint.getValueForType(componentClass))
            .orElse(null);
    }

    public static class ComponentObjectProvider implements ObjectProvider, Provider {

        private final Supplier objectSupplier;

        public ComponentObjectProvider(Supplier objectSupplier) {
            this.objectSupplier = objectSupplier;
        }

        @Nonnull
        @Override
        public C getObject(@Nonnull Object... args) throws BeansException {
            return objectSupplier.get();
        }

        @Override
        public C getIfAvailable() throws BeansException {
            return objectSupplier.get();
        }

        @Override
        public C getIfUnique() throws BeansException {
            return objectSupplier.get();
        }

        @Nonnull
        @Override
        public C getObject() throws BeansException {
            return objectSupplier.get();
        }

        @Override
        public C get() {
            return objectSupplier.get();
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy