io.devbench.uibuilder.spring.page.UIBuilderPageScope Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of uibuilder-spring Show documentation
Show all versions of uibuilder-spring Show documentation
Spring support for the UIBuilder Framework
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));
}
}