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

com.holonplatform.vaadin.spring.internal.SpringViewClassProvider Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * Copyright 2016-2018 Axioma srl.
 * 
 * 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 com.holonplatform.vaadin.spring.internal;

import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;

import com.holonplatform.core.internal.Logger;
import com.holonplatform.core.internal.utils.ObjectUtils;
import com.holonplatform.vaadin.internal.VaadinLogger;
import com.holonplatform.vaadin.navigator.ViewClassProvider;
import com.vaadin.navigator.View;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.internal.Conventions;
import com.vaadin.ui.UI;

/**
 * Spring {@link ViewClassProvider}.
 *
 * @since 5.1.3
 */
public class SpringViewClassProvider implements ViewClassProvider {

	private final static Logger LOGGER = VaadinLogger.create();

	private final Map>> viewClasses = new ConcurrentHashMap<>();
	private final Map, Map>>> uiViewClasses = new WeakHashMap<>();

	private final transient ApplicationContext applicationContext;

	/**
	 * Constructor.
	 * @param applicationContext ApplicationContext (not null)
	 */
	public SpringViewClassProvider(ApplicationContext applicationContext) {
		super();
		ObjectUtils.argumentNotNull(applicationContext, "ApplicationContext must be not null");
		this.applicationContext = applicationContext;
	}

	/**
	 * Init the provider, detecting all the View classes bound to the available View type beans.
	 */
	public void init() {
		LOGGER.info("SpringViewClassProvider: Detecting View classes");
		final String[] viewBeanNames = applicationContext.getBeanNamesForAnnotation(SpringView.class);
		for (String beanName : viewBeanNames) {
			try {
				final Class type = applicationContext.getType(beanName);
				if (View.class.isAssignableFrom(type)) {

					@SuppressWarnings("unchecked")
					final Class viewType = (Class) type;

					final SpringView annotation = AnnotatedElementUtils.findMergedAnnotation(type, SpringView.class);

					if (annotation != null) {
						// View name
						final String viewName = getViewNameFromAnnotation(type, annotation);
						// UIs
						Class[] uis = annotation.ui();
						if (uis.length == 0) {
							viewClasses.put(viewName, new WeakReference<>(viewType));
							LOGGER.debug(() -> "View class [" + viewType + "] detected for the view name [" + viewName
									+ "]");
						} else {
							for (Class ui : uis) {
								uiViewClasses.computeIfAbsent(ui, key -> new HashMap<>()).put(viewName,
										new WeakReference<>(viewType));
								LOGGER.debug(() -> "View class [" + viewType + "] detected for the view name ["
										+ viewName + "] - bound to the UI class [" + ui + "]");
							}
						}
					}
				}
			} catch (@SuppressWarnings("unused") NoSuchBeanDefinitionException e) {
				// ignore
			}
		}
	}

	private String getViewNameFromAnnotation(Class beanClass, SpringView annotation) {
		String viewName = Conventions.deriveMappingForView(beanClass, annotation);
		return applicationContext.getEnvironment().resolvePlaceholders(viewName);
	}

	/*
	 * (non-Javadoc)
	 * @see com.holonplatform.vaadin.navigator.ViewClassProvider#getViewClass(java.lang.String)
	 */
	@Override
	public Optional> getViewClass(String viewName) {
		if (viewName != null) {
			// check all UIs
			WeakReference> viewClass = viewClasses.get(viewName);
			if (viewClass != null) {
				return Optional.ofNullable(viewClass.get());
			}
			// check specific UI
			final UI currentUI = UI.getCurrent();
			if (currentUI != null) {
				// check
				viewClass = uiViewClasses.getOrDefault(currentUI.getClass(), Collections.emptyMap()).get(viewName);
				if (viewClass != null) {
					return Optional.ofNullable(viewClass.get());
				}
			}
		}
		return Optional.empty();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy