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

com.github.brunothg.swing.mvp.components.SpringViewProvider Maven / Gradle / Ivy

The newest version!
package com.github.brunothg.swing.mvp.components;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.github.brunothg.swing.mvp.annotation.SwingPresenter;
import com.github.brunothg.swing.mvp.annotation.SwingView;

/**
 * {@link View} provider for spring applications.
 * 
 * @author Marvin Bruns
 *
 */
@Component
public class SpringViewProvider
{
	private static final Logger LOG = LoggerFactory.getLogger(SpringViewProvider.class);

	@Autowired
	private ApplicationContext applicationContext;

	// @Autowired
	// private BeanDefinitionRegistry beanDefinitionRegistry;

	private final Map> viewNameToBeanNamesMap = new ConcurrentHashMap>();

	/**
	 * Scan for views and build view -> bean dictionary.
	 */
	@PostConstruct
	void init()
	{
		LOG.info("Looking up SpringViews");
		int count = 0;
		String[] viewBeanNames = applicationContext.getBeanNamesForAnnotation(SwingView.class);
		for (String beanName : viewBeanNames)
		{
			Class type = applicationContext.getType(beanName);
			if (View.class.isAssignableFrom(type))
			{
				SwingView annotation = applicationContext.findAnnotationOnBean(beanName, SwingView.class);
				String viewName = getViewNameFromAnnotation(type, annotation);
				LOG.info("Found SpringView bean [{}] with name[{}] with view name [{}]", type.getCanonicalName(),
					beanName, viewName);
				if (applicationContext.isSingleton(beanName))
				{
					throw new IllegalStateException("SpringView bean [" + beanName + "] must not be a singleton");
				}
				Set beanNames = viewNameToBeanNamesMap.get(viewName);
				if (beanNames == null)
				{
					beanNames = new ConcurrentSkipListSet();
					viewNameToBeanNamesMap.put(viewName, beanNames);
				}

				if (beanNames.size() > 0)
				{
					LOG.warn("Multiple beans for view [{}]", viewName);
				}
				beanNames.add(beanName);
				count++;
			}
			else
			{
				LOG.error("The view bean [{}] with name [{}] does not implement View", type.getCanonicalName(),
					beanName);
				throw new IllegalStateException("SpringView bean [" + beanName + "] must implement View");
			}
		}
		LOG.info("{} SpringViews found", count);
	}

	/**
	 * Fetch view from application context.
	 * 
	 * @param viewName The view's name
	 * @param beanName Name of the spring bean for the specific view.
	 * @return The view or null
	 */
	private View getViewFromApplicationContext(String viewName, String beanName)
	{
		View view = null;

		view = getViewFromApplicationContextAndCheckAccess(beanName);

		return view;
	}

	/**
	 * Test application context access and fetch view.
	 * 
	 * @param beanName Name of the spring bean for the specific view.
	 * @return The view or null
	 */
	private View getViewFromApplicationContextAndCheckAccess(String beanName)
	{
		View view = null;

		try
		{
			view = (View) applicationContext.getBean(beanName);
		}
		catch (BeansException e)
		{
			LOG.error("View bean is not a view [{}]", beanName);
		}

		return view;
	}

	/**
	 * Get the view for a specific {@link View}'s name.
	 * 
	 * @param viewName The name of a view
	 * @return The view or null, if no view exists for this name.
	 */
	public View getView(String viewName)
	{
		final Set beanNames = viewNameToBeanNamesMap.get(viewName);
		if (beanNames != null)
		{
			for (String beanName : beanNames)
			{
				return getViewFromApplicationContext(viewName, beanName);
			}
		}
		LOG.warn("No view found with name [{}]", viewName);
		return null;
	}

	/**
	 * Get the view name for a {@link View} class with a specific {@link SwingView} annotation.
	 * 
	 * @param type The {@link View} class
	 * @param annotation The view's {@link SwingView} annotation
	 * @return The view name
	 */
	public static String getViewNameFromAnnotation(Class type, SwingView annotation)
	{
		String name = annotation.name();
		if (name.equals(SwingView.AUTO_CREATION_NAME))
		{
			name = type.getCanonicalName();
		}

		return name;
	}

	/**
	 * Get the view name for a {@link Presenter} class with a specific {@link SwingPresenter}
	 * annotation.
	 * 
	 * @param type The {@link View} class
	 * @param annotation The view's {@link SwingPresenter} annotation
	 * @return The view name
	 */
	public static String getViewNameFromAnnotation(Class type, SwingPresenter annotation)
	{
		String name = annotation.viewName();
		if (name.equals(SwingPresenter.AUTO_CREATION_NAME))
		{
			name = type.getCanonicalName();
		}

		return name;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy