Java tutorial
/* * Copyright 2016-2016 the original author or authors. * * 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 cn.chenlichao.web.ssm.support.tiles; import org.apache.tiles.Attribute; import org.apache.tiles.Definition; import org.apache.tiles.TilesContainer; import org.apache.tiles.TilesException; import org.apache.tiles.definition.DefinitionsReader; import org.apache.tiles.definition.dao.BaseLocaleUrlDefinitionDAO; import org.apache.tiles.definition.dao.CachingLocaleUrlDefinitionDAO; import org.apache.tiles.definition.dao.ResolvingLocaleUrlDefinitionDAO; import org.apache.tiles.definition.digester.DigesterDefinitionsReader; import org.apache.tiles.el.ELAttributeEvaluator; import org.apache.tiles.el.ScopeELResolver; import org.apache.tiles.el.TilesContextBeanELResolver; import org.apache.tiles.el.TilesContextELResolver; import org.apache.tiles.evaluator.AttributeEvaluator; import org.apache.tiles.evaluator.AttributeEvaluatorFactory; import org.apache.tiles.evaluator.BasicAttributeEvaluatorFactory; import org.apache.tiles.evaluator.impl.DirectAttributeEvaluator; import org.apache.tiles.factory.AbstractTilesContainerFactory; import org.apache.tiles.factory.BasicTilesContainerFactory; import org.apache.tiles.impl.mgmt.CachingTilesContainer; import org.apache.tiles.locale.LocaleResolver; import org.apache.tiles.request.ApplicationContext; import org.apache.tiles.request.ApplicationResource; import org.apache.tiles.startup.DefaultTilesInitializer; import org.apache.tiles.startup.TilesInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.ClassUtils; import org.springframework.web.context.ServletContextAware; import org.springframework.web.servlet.view.tiles3.SpringLocaleResolver; import org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext; import javax.el.*; import javax.servlet.ServletContext; import javax.servlet.jsp.JspFactory; import java.io.File; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * Spring Tiles 3.x ?<a href="http://tiles.apache.org">http://tiles.apache.org</a>?Tiles? * Tiles?, ?JSP??? * * <p>Tiles3Configurertiles definition?, ?TilesContainer, * {@link org.springframework.web.servlet.view.tiles3.TilesView} * ?, tiles definition??definition name, ?, {@link Definition}.</p> * * <p>tiles definition?: </p> * * <pre class="code"> * <bean id="tilesConfigurer" class="cn.chenlichao.web.Tiles3Configurer"> * <property name="definitions"> * <list> * <value>/WEB-INF/defs/templates.xml</value> * <value>/WEB-INF/defs/templates_en_US.xml</value> * </list> * </property> * <property name="pagePrefix" value="/WEB-INF/jsp/" /> * </bean> * </pre> * * <p>definitions, tiles definition?, ?definitions, {@code "/WEB-INF/tiles.xml"}</p> * * <p>pagePrefix, Definition? Definition, ?URI, ????, * Definition * : pagePrefix="/WEB-INF/jsp/", URI/system/user/view, /WEB-INF/jsp/system/user??view.jsp? * ?Defination, ?tiles definition???? system/user/template, system/template, template * ?, ?Definition, * , {@code <put-attribute name="body" value="/WEB-INF/jsp/system/user/view.jsp" />} * </p> * * * <br>author: ? * <br>date: 16/6/13 ?5:17 * <br>version: V1.0.0 * <br>CopyrightCopyright 2016 Chen Lichao. All rights reserved. * @see org.springframework.web.servlet.view.tiles3.TilesView * @see org.springframework.web.servlet.view.tiles3.TilesViewResolver */ public class Tiles3Configurer implements ServletContextAware, InitializingBean, DisposableBean { private static final Logger LOGGER = LoggerFactory.getLogger(Tiles3Configurer.class); private static final boolean tilesElPresent = ClassUtils.isPresent("org.apache.tiles.el.ELAttributeEvaluator", Tiles3Configurer.class.getClassLoader()); private TilesInitializer tilesInitializer; private String[] definitions; private String pagePrefix; private boolean checkRefresh = false; private boolean validateDefinitions = true; private boolean useMutableTilesContainer = false; private ServletContext servletContext; public void setDefinitions(String[] definitions) { this.definitions = definitions; } public void setPagePrefix(String pagePrefix) { this.pagePrefix = pagePrefix; if (!pagePrefix.endsWith("/")) { this.pagePrefix += "/"; } } public void setCheckRefresh(boolean checkRefresh) { this.checkRefresh = checkRefresh; } public void setValidateDefinitions(boolean validateDefinitions) { this.validateDefinitions = validateDefinitions; } public void setUseMutableTilesContainer(boolean useMutableTilesContainer) { this.useMutableTilesContainer = useMutableTilesContainer; } @Override public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } @Override public void afterPropertiesSet() throws TilesException { ApplicationContext preliminaryContext = new SpringWildcardServletTilesApplicationContext( this.servletContext); this.tilesInitializer = new SSMTilesInitializr(); this.tilesInitializer.initialize(preliminaryContext); } @Override public void destroy() throws Exception { this.tilesInitializer.destroy(); } private class SSMTilesInitializr extends DefaultTilesInitializer { @Override protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) { return new SSMTilesContainerFactory(); } } private class SSMTilesContainerFactory extends BasicTilesContainerFactory { @Override public TilesContainer createContainer(ApplicationContext applicationContext) { TilesContainer container = super.createContainer(applicationContext); return (useMutableTilesContainer ? new CachingTilesContainer(container) : container); } @Override protected List<ApplicationResource> getSources(ApplicationContext applicationContext) { if (definitions != null) { List<ApplicationResource> result = new LinkedList<>(); for (String definition : definitions) { Collection<ApplicationResource> resources = applicationContext.getResources(definition); if (resources != null) { result.addAll(resources); } } return result; } else { return super.getSources(applicationContext); } } @Override protected BaseLocaleUrlDefinitionDAO instantiateLocaleDefinitionDao(ApplicationContext applicationContext, LocaleResolver resolver) { BaseLocaleUrlDefinitionDAO dao = new SSMDefinitionDAO(applicationContext); if (checkRefresh) { ((CachingLocaleUrlDefinitionDAO) dao).setCheckRefresh(true); } return dao; } @Override protected DefinitionsReader createDefinitionsReader(ApplicationContext context) { DigesterDefinitionsReader reader = (DigesterDefinitionsReader) super.createDefinitionsReader(context); reader.setValidating(validateDefinitions); return reader; } @Override protected LocaleResolver createLocaleResolver(ApplicationContext context) { return new SpringLocaleResolver(); } @Override protected AttributeEvaluatorFactory createAttributeEvaluatorFactory(ApplicationContext context, LocaleResolver resolver) { AttributeEvaluator evaluator; if (tilesElPresent && JspFactory.getDefaultFactory() != null) { evaluator = new Tiles3Configurer.TilesElActivator().createEvaluator(); } else { evaluator = new DirectAttributeEvaluator(); } return new BasicAttributeEvaluatorFactory(evaluator); } } private class TilesElActivator { public AttributeEvaluator createEvaluator() { ELAttributeEvaluator evaluator = new ELAttributeEvaluator(); evaluator.setExpressionFactory( JspFactory.getDefaultFactory().getJspApplicationContext(servletContext).getExpressionFactory()); evaluator.setResolver(new Tiles3Configurer.CompositeELResolverImpl()); return evaluator; } } private static class CompositeELResolverImpl extends CompositeELResolver { public CompositeELResolverImpl() { add(new ScopeELResolver()); add(new TilesContextELResolver(new TilesContextBeanELResolver())); add(new TilesContextBeanELResolver()); add(new ArrayELResolver(false)); add(new ListELResolver(false)); add(new MapELResolver(false)); add(new ResourceBundleELResolver()); add(new BeanELResolver(false)); } } private class SSMDefinitionDAO extends ResolvingLocaleUrlDefinitionDAO { private Map<Locale, Map<String, Definition>> autoDefinitionMap = new ConcurrentHashMap<>(); SSMDefinitionDAO(ApplicationContext applicationContext) { super(applicationContext); } @Override public Definition getDefinition(String name, Locale customizationKey) { Definition retVal = super.getDefinition(name, customizationKey); if (retVal == null) { if (customizationKey == null) { customizationKey = Locale.ROOT; } Map<String, Definition> definitions = autoDefinitionMap.get(customizationKey); if (definitions == null) { definitions = new ConcurrentHashMap<>(); autoDefinitionMap.put(customizationKey, definitions); } retVal = definitions.get(name); if (retVal == null) { retVal = buildDefinition(name, customizationKey); if (retVal != null) { definitions.put(name, retVal); } } } return retVal; } private Definition buildDefinition(String name, Locale customizationKey) { LOGGER.info("Definition [{}] ... ", name); String webPath = servletContext.getRealPath("/"); if (webPath.endsWith(File.separator)) { webPath = webPath.substring(0, webPath.length() - 1); } String viewPage = webPath + pagePrefix + name + ".jsp"; if (!(new File(viewPage).exists())) { LOGGER.warn("?Definition [{}] ?!!!", viewPage); return null; } Definition definition = new Definition(); definition.setName(name); definition.putAttribute("body", Attribute.createTemplateAttribute(pagePrefix + name + ".jsp")); String templateName = name.substring(0, name.lastIndexOf("/") + 1) + "template"; Definition parent = super.getDefinition(templateName, customizationKey); while (parent == null) { if (templateName.lastIndexOf("/") == -1) { LOGGER.warn("?layout?!"); return null; } templateName = templateName.substring(0, templateName.lastIndexOf("/")); templateName = templateName.substring(0, templateName.lastIndexOf("/") + 1) + "template"; parent = super.getDefinition(templateName, customizationKey); } definition.setExtends(templateName); definition.inherit(parent); return definition; } } }