001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.template; 018 019import java.util.List; 020 021import org.springframework.boot.context.properties.bind.Binder; 022import org.springframework.core.env.Environment; 023import org.springframework.core.io.ResourceLoader; 024import org.springframework.util.ClassUtils; 025 026/** 027 * Abstract base class for {@link TemplateAvailabilityProvider} implementations that find 028 * templates from paths. 029 * 030 * @author Andy Wilkinson 031 * @author Phillip Webb 032 * @author Madhura Bhave 033 * @since 1.4.6 034 */ 035public abstract class PathBasedTemplateAvailabilityProvider 036 implements TemplateAvailabilityProvider { 037 038 private final String className; 039 040 private final Class<TemplateAvailabilityProperties> propertiesClass; 041 042 private final String propertyPrefix; 043 044 @SuppressWarnings("unchecked") 045 public PathBasedTemplateAvailabilityProvider(String className, 046 Class<? extends TemplateAvailabilityProperties> propertiesClass, 047 String propertyPrefix) { 048 this.className = className; 049 this.propertiesClass = (Class<TemplateAvailabilityProperties>) propertiesClass; 050 this.propertyPrefix = propertyPrefix; 051 } 052 053 @Override 054 public boolean isTemplateAvailable(String view, Environment environment, 055 ClassLoader classLoader, ResourceLoader resourceLoader) { 056 if (ClassUtils.isPresent(this.className, classLoader)) { 057 Binder binder = Binder.get(environment); 058 TemplateAvailabilityProperties properties = binder 059 .bind(this.propertyPrefix, this.propertiesClass) 060 .orElseCreate(this.propertiesClass); 061 return isTemplateAvailable(view, resourceLoader, properties); 062 } 063 return false; 064 } 065 066 private boolean isTemplateAvailable(String view, ResourceLoader resourceLoader, 067 TemplateAvailabilityProperties properties) { 068 String location = properties.getPrefix() + view + properties.getSuffix(); 069 for (String path : properties.getLoaderPath()) { 070 if (resourceLoader.getResource(path + location).exists()) { 071 return true; 072 } 073 } 074 return false; 075 } 076 077 protected abstract static class TemplateAvailabilityProperties { 078 079 private String prefix; 080 081 private String suffix; 082 083 protected TemplateAvailabilityProperties(String prefix, String suffix) { 084 this.prefix = prefix; 085 this.suffix = suffix; 086 } 087 088 protected abstract List<String> getLoaderPath(); 089 090 public String getPrefix() { 091 return this.prefix; 092 } 093 094 public void setPrefix(String prefix) { 095 this.prefix = prefix; 096 } 097 098 public String getSuffix() { 099 return this.suffix; 100 } 101 102 public void setSuffix(String suffix) { 103 this.suffix = suffix; 104 } 105 106 } 107 108}