Home / Class/ TemplateAvailabilityProviders Class — spring-boot Architecture

TemplateAvailabilityProviders Class — spring-boot Architecture

Architecture documentation for the TemplateAvailabilityProviders class in TemplateAvailabilityProviders.java from the spring-boot codebase.

Entity Profile

Source Code

core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/template/TemplateAvailabilityProviders.java lines 43–176

public class TemplateAvailabilityProviders {

	private final List<TemplateAvailabilityProvider> providers;

	private static final int CACHE_LIMIT = 1024;

	private static final TemplateAvailabilityProvider NONE = new NoTemplateAvailabilityProvider();

	/**
	 * Resolved template views, returning already cached instances without a global lock.
	 */
	private final Map<String, TemplateAvailabilityProvider> resolved = new ConcurrentHashMap<>(CACHE_LIMIT);

	/**
	 * Map from view name resolve template view, synchronized when accessed.
	 */
	private final Map<String, TemplateAvailabilityProvider> cache = new LinkedHashMap<>(CACHE_LIMIT, 0.75f, true) {

		@Override
		protected boolean removeEldestEntry(Map.Entry<String, TemplateAvailabilityProvider> eldest) {
			if (size() > CACHE_LIMIT) {
				TemplateAvailabilityProviders.this.resolved.remove(eldest.getKey());
				return true;
			}
			return false;
		}

	};

	/**
	 * Create a new {@link TemplateAvailabilityProviders} instance.
	 * @param applicationContext the source application context
	 */
	public TemplateAvailabilityProviders(ApplicationContext applicationContext) {
		this(getClassLoader(applicationContext));
	}

	private static ClassLoader getClassLoader(ApplicationContext applicationContext) {
		Assert.notNull(applicationContext, "'applicationContext' must not be null");
		ClassLoader classLoader = applicationContext.getClassLoader();
		Assert.state(classLoader != null, "'classLoader' must not be null");
		return classLoader;
	}

	/**
	 * Create a new {@link TemplateAvailabilityProviders} instance.
	 * @param classLoader the source class loader
	 */
	public TemplateAvailabilityProviders(ClassLoader classLoader) {
		Assert.notNull(classLoader, "'classLoader' must not be null");
		this.providers = SpringFactoriesLoader.loadFactories(TemplateAvailabilityProvider.class, classLoader);
	}

	/**
	 * Create a new {@link TemplateAvailabilityProviders} instance.
	 * @param providers the underlying providers
	 */
	protected TemplateAvailabilityProviders(Collection<? extends TemplateAvailabilityProvider> providers) {
		Assert.notNull(providers, "'providers' must not be null");
		this.providers = new ArrayList<>(providers);
	}

	/**
	 * Return the underlying providers being used.
	 * @return the providers being used
	 */
	public List<TemplateAvailabilityProvider> getProviders() {
		return this.providers;
	}

	/**
	 * Get the provider that can be used to render the given view.
	 * @param view the view to render
	 * @param applicationContext the application context
	 * @return a {@link TemplateAvailabilityProvider} or null
	 */
	public @Nullable TemplateAvailabilityProvider getProvider(String view, ApplicationContext applicationContext) {
		Assert.notNull(applicationContext, "'applicationContext' must not be null");
		ClassLoader classLoader = applicationContext.getClassLoader();
		Assert.state(classLoader != null, "'classLoader' must not be null");
		return getProvider(view, applicationContext.getEnvironment(), classLoader, applicationContext);
	}

	/**
	 * Get the provider that can be used to render the given view.
	 * @param view the view to render
	 * @param environment the environment
	 * @param classLoader the class loader
	 * @param resourceLoader the resource loader
	 * @return a {@link TemplateAvailabilityProvider} or null
	 */
	public @Nullable TemplateAvailabilityProvider getProvider(String view, Environment environment,
			ClassLoader classLoader, ResourceLoader resourceLoader) {
		Assert.notNull(view, "'view' must not be null");
		Assert.notNull(environment, "'environment' must not be null");
		Assert.notNull(classLoader, "'classLoader' must not be null");
		Assert.notNull(resourceLoader, "'resourceLoader' must not be null");
		Boolean useCache = environment.getProperty("spring.template.provider.cache", Boolean.class, true);
		if (!useCache) {
			return findProvider(view, environment, classLoader, resourceLoader);
		}
		TemplateAvailabilityProvider provider = this.resolved.get(view);
		if (provider == null) {
			synchronized (this.cache) {
				provider = findProvider(view, environment, classLoader, resourceLoader);
				provider = (provider != null) ? provider : NONE;
				this.resolved.put(view, provider);
				this.cache.put(view, provider);
			}
		}
		return (provider != NONE) ? provider : null;
	}

	private @Nullable TemplateAvailabilityProvider findProvider(String view, Environment environment,
			ClassLoader classLoader, ResourceLoader resourceLoader) {
		for (TemplateAvailabilityProvider candidate : this.providers) {
			if (candidate.isTemplateAvailable(view, environment, classLoader, resourceLoader)) {
				return candidate;
			}
		}
		return null;
	}

	private static final class NoTemplateAvailabilityProvider implements TemplateAvailabilityProvider {

		@Override
		public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader,
				ResourceLoader resourceLoader) {
			return false;
		}

	}

}

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free