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

io.devbench.uibuilder.spring.page.UIBuilderPageScope Maven / Gradle / Ivy

The newest version!
/*
 *
 * 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.page;

import com.vaadin.flow.component.UI;
import com.vaadin.flow.server.VaadinSession;
import io.devbench.uibuilder.core.flow.FlowManager;
import io.devbench.uibuilder.core.page.PageLoader;
import io.devbench.uibuilder.core.page.PageLoaderContext;
import io.devbench.uibuilder.core.page.pageloaderprocessors.PageUnloadProcessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.context.annotation.Configuration;

import java.util.Objects;

@Configuration
public class UIBuilderPageScope implements Scope, BeanFactoryPostProcessor {

    public static final String UIBUILDER_PAGE_SCOPE = "uibuilder-page";

    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(@NotNull ConfigurableListableBeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
        this.beanFactory.registerScope(UIBUILDER_PAGE_SCOPE, this);
        PageLoader.registerUnloadProcessor(new PageUnloadProcessor() {
            @Override
            public void process(PageLoaderContext context) {
                context.getPageContextIds().forEach(contextId -> unloadPage(contextId));
            }
        });
    }

    @Override
    @NotNull
    @SuppressWarnings("checkstyle:RegexpSinglelineJava")
    public Object get(@NotNull String name, @NotNull ObjectFactory objectFactory) {
        PageScopeBeanId beanId = getBeanIdForBean(name);
        if (!isPageContextPresent(beanId)) {
            throw new IllegalStateException(
                String.format("PageScope for contextId (`%s`) is not active, because the page is not loaded.", beanId.getPageName())
            );
        }
        return getBeanStore().get(beanId, objectFactory);
    }

    private boolean isPageContextPresent(PageScopeBeanId beanId) {
        return FlowManager
            .getCurrent()
            .getPageLoaders()
            .stream()
            .flatMap(it -> it.getPageContextIds().stream())
            .anyMatch(beanId.getPageName()::equals);
    }

    private PageScopeBeanId getBeanIdForBean(String name) {
        try {
            String beanClassName = beanFactory.getBeanDefinition(name).getBeanClassName();
            Class beanClass = Class.forName(beanClassName);
            PageScope annotation = beanClass.getAnnotation(PageScope.class);
            return PageScopeBeanId.of(name, annotation.value());
        } catch (ClassNotFoundException e) {
            throw new BeanClassNotFoundException(e);
        }
    }

    private BeanStore getBeanStore() {
        VaadinSession session = VaadinSession.getCurrent();
        try {
            session.lock();
            BeanStoreWrapper attribute = session.getAttribute(BeanStoreWrapper.class);
            if (attribute == null) {
                attribute = new BeanStoreWrapper(session);
                session.setAttribute(BeanStoreWrapper.class, attribute);
            }
            return attribute.getBeanStore(UI.getCurrent(), PageScopeBeanId.class);
        } finally {
            session.unlock();
        }
    }

    @Override
    @Nullable
    public Object remove(@NotNull String name) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
        getBeanStore().registerDestructionCallback(getBeanIdForBean(name), callback);
    }

    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }

    @Override
    public String getConversationId() {
        return null;
    }

    public void unloadPage(String pageId) {
        getBeanStore().destroyBeans(id -> Objects.equals(id.getPageName(), pageId));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy