Add Spring Framework integration with Tiles 3
Tiles 3 has modified packages and classes as well as additional
dependencies, notably "tiles-request-api", which is a request/response
abstraction independent of Servlet and JSP APIs.
In order to have both Tiles 2 and Tiles 3 integrations, the source for
the Tiles 3 integration is in a separate project spring-webmvc-tiles3.
The build process merges the compiled Tiles 3 integration classes into
the spring-webmvc module so in effect it contains both the Tiles 2 and
the Tiles 3 integrations.
This change originated as a pull request at spring-framework-issues:
https://github.com/SpringSource/spring-framework-issues/pull/30
And was additionally updated:
1f64be4aa5
Issue: SPR-8825
			
			
This commit is contained in:
		
							parent
							
								
									63ca14c33e
								
							
						
					
					
						commit
						2a11007a04
					
				
							
								
								
									
										27
									
								
								build.gradle
								
								
								
								
							
							
						
						
									
										27
									
								
								build.gradle
								
								
								
								
							| 
						 | 
				
			
			@ -396,7 +396,7 @@ project('spring-web') {
 | 
			
		|||
        compile("javax.el:el-api:1.0", optional)
 | 
			
		||||
        compile("javax.faces:jsf-api:1.2_08", optional)
 | 
			
		||||
        compile("javax.portlet:portlet-api:2.0", provided)
 | 
			
		||||
        compile("org.apache.tomcat:tomcat-servlet-api:7.0.8", provided) // servlet-api 3.0
 | 
			
		||||
        compile("org.apache.tomcat:tomcat-servlet-api:7.0.32", provided) // servlet-api 3.0
 | 
			
		||||
        compile("javax.servlet.jsp:jsp-api:2.1", provided)
 | 
			
		||||
        compile("javax.xml.soap:saaj-api:1.3", provided)
 | 
			
		||||
        compile("axis:axis:1.4", optional)
 | 
			
		||||
| 
						 | 
				
			
			@ -482,7 +482,7 @@ project('spring-webmvc') {
 | 
			
		|||
            exclude group: 'log4j', module: 'log4j'
 | 
			
		||||
        }
 | 
			
		||||
        compile("javax.servlet:jstl:1.1.2", provided)
 | 
			
		||||
        compile("org.apache.tomcat:tomcat-servlet-api:7.0.8", provided) // servlet-api 3.0
 | 
			
		||||
        compile("org.apache.tomcat:tomcat-servlet-api:7.0.32", provided) // servlet-api 3.0
 | 
			
		||||
        testCompile project(":spring-aop")
 | 
			
		||||
        testCompile("org.slf4j:slf4j-log4j12:1.6.1") {
 | 
			
		||||
            exclude group: 'log4j', module: 'log4j'
 | 
			
		||||
| 
						 | 
				
			
			@ -503,6 +503,27 @@ project('spring-webmvc') {
 | 
			
		|||
    sourceSets.main.resources.srcDirs += 'src/main/java'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
project('spring-webmvc-tiles3') {
 | 
			
		||||
    description = 'Spring Framework Tiles3 Integration'
 | 
			
		||||
    apply from: 'tiles3.gradle'
 | 
			
		||||
    dependencies {
 | 
			
		||||
        compile project(":spring-context")
 | 
			
		||||
        compile project(":spring-webmvc").sourceSets.main.output
 | 
			
		||||
        compile("javax.el:el-api:1.0", provided)
 | 
			
		||||
        compile("javax.servlet:jstl:1.1.2", provided)
 | 
			
		||||
        compile("javax.servlet.jsp:jsp-api:2.1", provided)
 | 
			
		||||
        compile("org.apache.tiles:tiles-request-api:1.0.1", optional)
 | 
			
		||||
        compile("org.apache.tiles:tiles-request-servlet-wildcard:1.0.1", optional)
 | 
			
		||||
        compile("org.apache.tiles:tiles-api:3.0.1", optional)
 | 
			
		||||
        compile("org.apache.tiles:tiles-core:3.0.1", optional)
 | 
			
		||||
        compile("org.apache.tiles:tiles-servlet:3.0.1", optional)
 | 
			
		||||
        compile("org.apache.tiles:tiles-jsp:3.0.1", optional)
 | 
			
		||||
        compile("org.apache.tiles:tiles-el:3.0.1", optional)
 | 
			
		||||
        compile("org.apache.tomcat:tomcat-servlet-api:7.0.32", provided) // servlet-api 3.0
 | 
			
		||||
        testCompile project(":spring-web").sourceSets*.output // mock request & response
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
project('spring-webmvc-portlet') {
 | 
			
		||||
    description = 'Spring Web Portlet'
 | 
			
		||||
    dependencies {
 | 
			
		||||
| 
						 | 
				
			
			@ -556,7 +577,7 @@ project('spring-test-mvc') {
 | 
			
		|||
        compile project(":spring-context")
 | 
			
		||||
        compile project(":spring-webmvc")
 | 
			
		||||
        compile project(":spring-test").sourceSets.main.output
 | 
			
		||||
        compile("org.apache.tomcat:tomcat-servlet-api:7.0.8", provided)
 | 
			
		||||
        compile("org.apache.tomcat:tomcat-servlet-api:7.0.32", provided)
 | 
			
		||||
        compile("org.hamcrest:hamcrest-core:1.3", optional)
 | 
			
		||||
        compile("com.jayway.jsonpath:json-path:0.8.1", optional)
 | 
			
		||||
        compile("xmlunit:xmlunit:1.2", optional)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,3 +20,4 @@ include 'spring-tx'
 | 
			
		|||
include 'spring-web'
 | 
			
		||||
include 'spring-webmvc'
 | 
			
		||||
include 'spring-webmvc-portlet'
 | 
			
		||||
include 'spring-webmvc-tiles3'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.TilesException;
 | 
			
		||||
import org.apache.tiles.preparer.ViewPreparer;
 | 
			
		||||
import org.apache.tiles.preparer.factory.PreparerFactory;
 | 
			
		||||
import org.apache.tiles.request.Request;
 | 
			
		||||
import org.springframework.web.context.WebApplicationContext;
 | 
			
		||||
import org.springframework.web.servlet.DispatcherServlet;
 | 
			
		||||
import org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract implementation of the Tiles3 {@link org.apache.tiles.preparer.PreparerFactory}
 | 
			
		||||
 * interface, obtaining the current Spring WebApplicationContext and delegating to
 | 
			
		||||
 * {@link #getPreparer(String, org.springframework.web.context.WebApplicationContext)}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 3.2
 | 
			
		||||
 * @see #getPreparer(String, org.springframework.web.context.WebApplicationContext)
 | 
			
		||||
 * @see SimpleSpringPreparerFactory
 | 
			
		||||
 * @see SpringBeanPreparerFactory
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractSpringPreparerFactory implements PreparerFactory {
 | 
			
		||||
 | 
			
		||||
	public ViewPreparer getPreparer(String name, Request context) {
 | 
			
		||||
		WebApplicationContext webApplicationContext = (WebApplicationContext) context.getContext("request").get(
 | 
			
		||||
				DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);
 | 
			
		||||
		if (webApplicationContext == null) {
 | 
			
		||||
			webApplicationContext = (WebApplicationContext) context.getContext("application").get(
 | 
			
		||||
					WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
 | 
			
		||||
			if (webApplicationContext == null) {
 | 
			
		||||
				throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return getPreparer(name, webApplicationContext);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Obtain a preparer instance for the given preparer name,
 | 
			
		||||
	 * based on the given Spring WebApplicationContext.
 | 
			
		||||
	 * @param name the name of the preparer
 | 
			
		||||
	 * @param context the current Spring WebApplicationContext
 | 
			
		||||
	 * @return the preparer instance
 | 
			
		||||
	 * @throws TilesException in case of failure
 | 
			
		||||
	 */
 | 
			
		||||
	protected abstract ViewPreparer getPreparer(String name, WebApplicationContext context) throws TilesException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.TilesException;
 | 
			
		||||
import org.apache.tiles.preparer.PreparerException;
 | 
			
		||||
import org.apache.tiles.preparer.ViewPreparer;
 | 
			
		||||
import org.apache.tiles.preparer.factory.NoSuchPreparerException;
 | 
			
		||||
import org.springframework.web.context.WebApplicationContext;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tiles2 {@link org.apache.tiles.preparer.PreparerFactory} implementation
 | 
			
		||||
 * that expects preparer class names and builds preparer instances for those,
 | 
			
		||||
 * creating them through the Spring ApplicationContext in order to apply
 | 
			
		||||
 * Spring container callbacks and configured Spring BeanPostProcessors.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 3.2
 | 
			
		||||
 * @see SpringBeanPreparerFactory
 | 
			
		||||
 */
 | 
			
		||||
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
 | 
			
		||||
 | 
			
		||||
	/** Cache of shared ViewPreparer instances: bean name --> bean instance */
 | 
			
		||||
	private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected ViewPreparer getPreparer(String name, WebApplicationContext context) throws TilesException {
 | 
			
		||||
		// Quick check on the concurrent map first, with minimal locking.
 | 
			
		||||
		ViewPreparer preparer = this.sharedPreparers.get(name);
 | 
			
		||||
		if (preparer == null) {
 | 
			
		||||
			synchronized (this.sharedPreparers) {
 | 
			
		||||
				preparer = this.sharedPreparers.get(name);
 | 
			
		||||
				if (preparer == null) {
 | 
			
		||||
					try {
 | 
			
		||||
						Class<?> beanClass = context.getClassLoader().loadClass(name);
 | 
			
		||||
						if (!ViewPreparer.class.isAssignableFrom(beanClass)) {
 | 
			
		||||
							throw new PreparerException(
 | 
			
		||||
									"Invalid preparer class [" + name + "]: does not implement ViewPreparer interface");
 | 
			
		||||
						}
 | 
			
		||||
						preparer = (ViewPreparer) context.getAutowireCapableBeanFactory().createBean(beanClass);
 | 
			
		||||
						this.sharedPreparers.put(name, preparer);
 | 
			
		||||
					}
 | 
			
		||||
					catch (ClassNotFoundException ex) {
 | 
			
		||||
						throw new NoSuchPreparerException("Preparer class [" + name + "] not found", ex);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return preparer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.TilesException;
 | 
			
		||||
import org.apache.tiles.preparer.ViewPreparer;
 | 
			
		||||
 | 
			
		||||
import org.springframework.web.context.WebApplicationContext;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tiles3 {@link org.apache.tiles.preparer.PreparerFactory} implementation
 | 
			
		||||
 * that expects preparer bean names and obtains preparer beans from the
 | 
			
		||||
 * Spring ApplicationContext. The full bean creation process will be in
 | 
			
		||||
 * the control of the Spring application context in this case, allowing
 | 
			
		||||
 * for the use of scoped beans etc.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 3.2
 | 
			
		||||
 * @see SimpleSpringPreparerFactory
 | 
			
		||||
 */
 | 
			
		||||
public class SpringBeanPreparerFactory extends AbstractSpringPreparerFactory {
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected ViewPreparer getPreparer(String name, WebApplicationContext context) throws TilesException {
 | 
			
		||||
		return context.getBean(name, ViewPreparer.class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import org.apache.tiles.locale.impl.DefaultLocaleResolver;
 | 
			
		||||
import org.apache.tiles.request.Request;
 | 
			
		||||
import org.apache.tiles.request.servlet.NotAServletEnvironmentException;
 | 
			
		||||
import org.apache.tiles.request.servlet.ServletUtil;
 | 
			
		||||
import org.springframework.web.servlet.support.RequestContextUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tiles LocaleResolver adapter that delegates to a Spring
 | 
			
		||||
 * {@link org.springframework.web.servlet.LocaleResolver}, exposing the
 | 
			
		||||
 * DispatcherServlet-managed locale.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This adapter gets automatically registered by {@link TilesConfigurer}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Nicolas Le Bas
 | 
			
		||||
 * @since 3.2
 | 
			
		||||
 * @see org.apache.tiles.definition.UrlDefinitionsFactory#LOCALE_RESOLVER_IMPL_PROPERTY
 | 
			
		||||
 */
 | 
			
		||||
public class SpringLocaleResolver extends DefaultLocaleResolver {
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public Locale resolveLocale(Request request) {
 | 
			
		||||
		try {
 | 
			
		||||
			HttpServletRequest servletRequest = ServletUtil.getServletRequest(request).getRequest();
 | 
			
		||||
			if (servletRequest != null) {
 | 
			
		||||
				return RequestContextUtils.getLocale(servletRequest);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (NotAServletEnvironmentException e) {
 | 
			
		||||
			// Ignore
 | 
			
		||||
		}
 | 
			
		||||
		return super.resolveLocale(request);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,419 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import javax.el.ArrayELResolver;
 | 
			
		||||
import javax.el.BeanELResolver;
 | 
			
		||||
import javax.el.CompositeELResolver;
 | 
			
		||||
import javax.el.ListELResolver;
 | 
			
		||||
import javax.el.MapELResolver;
 | 
			
		||||
import javax.el.ResourceBundleELResolver;
 | 
			
		||||
import javax.servlet.ServletContext;
 | 
			
		||||
import javax.servlet.jsp.JspFactory;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.TilesContainer;
 | 
			
		||||
import org.apache.tiles.TilesException;
 | 
			
		||||
import org.apache.tiles.access.TilesAccess;
 | 
			
		||||
import org.apache.tiles.definition.DefinitionsFactory;
 | 
			
		||||
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.digester.DigesterDefinitionsReader;
 | 
			
		||||
import org.apache.tiles.el.ELAttributeEvaluator;
 | 
			
		||||
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.BasicTilesContainer;
 | 
			
		||||
import org.apache.tiles.impl.mgmt.CachingTilesContainer;
 | 
			
		||||
import org.apache.tiles.locale.LocaleResolver;
 | 
			
		||||
import org.apache.tiles.preparer.factory.PreparerFactory;
 | 
			
		||||
import org.apache.tiles.request.ApplicationContext;
 | 
			
		||||
import org.apache.tiles.request.ApplicationResource;
 | 
			
		||||
import org.apache.tiles.request.servlet.wildcard.WildcardServletApplicationContext;
 | 
			
		||||
import org.apache.tiles.startup.DefaultTilesInitializer;
 | 
			
		||||
import org.apache.tiles.startup.TilesInitializer;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.beans.BeanUtils;
 | 
			
		||||
import org.springframework.beans.BeanWrapper;
 | 
			
		||||
import org.springframework.beans.PropertyAccessorFactory;
 | 
			
		||||
import org.springframework.beans.factory.DisposableBean;
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
import org.springframework.util.ClassUtils;
 | 
			
		||||
import org.springframework.web.context.ServletContextAware;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper class to configure Tiles 3.x for the Spring Framework. See
 | 
			
		||||
 * <a href="http://tiles.apache.org">http://tiles.apache.org</a>
 | 
			
		||||
 * for more information about Tiles, which basically is a templating mechanism
 | 
			
		||||
 * for web applications using JSPs and other template engines.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The TilesConfigurer simply configures a TilesContainer using a set of files
 | 
			
		||||
 * containing definitions, to be accessed by {@link TilesView} instances. This is a
 | 
			
		||||
 * Spring-based alternative (for usage in Spring configuration) to the Tiles-provided
 | 
			
		||||
 * {@link org.apache.tiles.web.startup.TilesListener} (for usage in <code>web.xml</code>).
 | 
			
		||||
 *
 | 
			
		||||
 * <p>TilesViews can be managed by any {@link org.springframework.web.servlet.ViewResolver}.
 | 
			
		||||
 * For simple convention-based view resolution, consider using {@link TilesViewResolver}.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A typical TilesConfigurer bean definition looks as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
 | 
			
		||||
 *   <property name="definitions">
 | 
			
		||||
 *     <list>
 | 
			
		||||
 *       <value>/WEB-INF/defs/general.xml</value>
 | 
			
		||||
 *       <value>/WEB-INF/defs/widgets.xml</value>
 | 
			
		||||
 *       <value>/WEB-INF/defs/administrator.xml</value>
 | 
			
		||||
 *       <value>/WEB-INF/defs/customer.xml</value>
 | 
			
		||||
 *       <value>/WEB-INF/defs/templates.xml</value>
 | 
			
		||||
 *     </list>
 | 
			
		||||
 *   </property>
 | 
			
		||||
 * </bean>
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * The values in the list are the actual Tiles XML files containing the definitions.
 | 
			
		||||
 * If the list is not specified, the default is {@code "/WEB-INF/tiles.xml"}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author mick semb wever
 | 
			
		||||
 * @author Rossen Stoyanchev
 | 
			
		||||
 * @since 3.2
 | 
			
		||||
 */
 | 
			
		||||
public class TilesConfigurer implements ServletContextAware, InitializingBean, DisposableBean {
 | 
			
		||||
 | 
			
		||||
	private static final boolean tilesElPresent =  // requires JSP 2.1 as well as Tiles EL module
 | 
			
		||||
			ClassUtils.isPresent("javax.servlet.jsp.JspApplicationContext", TilesConfigurer.class.getClassLoader()) &&
 | 
			
		||||
			ClassUtils.isPresent("org.apache.tiles.el.ELAttributeEvaluator", TilesConfigurer.class.getClassLoader());
 | 
			
		||||
 | 
			
		||||
	protected final Logger logger = LoggerFactory.getLogger(getClass());
 | 
			
		||||
 | 
			
		||||
	private TilesInitializer tilesInitializer;
 | 
			
		||||
 | 
			
		||||
	private boolean completeAutoload = false;
 | 
			
		||||
 | 
			
		||||
	private String[] definitions;
 | 
			
		||||
 | 
			
		||||
	private boolean checkRefresh = false;
 | 
			
		||||
 | 
			
		||||
	private boolean validateDefinitions = true;
 | 
			
		||||
 | 
			
		||||
	private Class<? extends DefinitionsFactory> definitionsFactoryClass;
 | 
			
		||||
 | 
			
		||||
	private Class<? extends PreparerFactory> preparerFactoryClass;
 | 
			
		||||
 | 
			
		||||
	private boolean useMutableTilesContainer = false;
 | 
			
		||||
 | 
			
		||||
	private ServletContext servletContext;
 | 
			
		||||
 | 
			
		||||
	public TilesConfigurer() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Configure Tiles using a custom TilesInitializer, typically specified as an inner bean.
 | 
			
		||||
	 * <p>Default is a variant of {@link org.apache.tiles.startup.DefaultTilesInitializer},
 | 
			
		||||
	 * respecting the "definitions", "preparerFactoryClass" etc properties on this configurer.
 | 
			
		||||
	 * <p><b>NOTE: Specifying a custom TilesInitializer effectively disables all other bean
 | 
			
		||||
	 * properties on this configurer.</b> The entire initialization procedure is then left
 | 
			
		||||
	 * to the TilesInitializer as specified.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setTilesInitializer(TilesInitializer tilesInitializer) {
 | 
			
		||||
		this.tilesInitializer = tilesInitializer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether to apply Tiles 3.0's "complete-autoload" configuration.
 | 
			
		||||
	 * <p>See {@link org.apache.tiles.extras.complete.CompleteAutoloadTilesContainerFactory}
 | 
			
		||||
	 * for details on the complete-autoload mode.
 | 
			
		||||
	 * <p><b>NOTE: Specifying the complete-autoload mode effectively disables all other bean
 | 
			
		||||
	 * properties on this configurer.</b> The entire initialization procedure is then left
 | 
			
		||||
	 * to {@link org.apache.tiles.extras.complete.CompleteAutoloadTilesInitializer}.
 | 
			
		||||
	 * @see org.apache.tiles.extras.complete.CompleteAutoloadTilesContainerFactory
 | 
			
		||||
	 * @see org.apache.tiles.extras.complete.CompleteAutoloadTilesInitializer
 | 
			
		||||
	 */
 | 
			
		||||
	public void setCompleteAutoload(boolean completeAutoload) {
 | 
			
		||||
		if (completeAutoload) {
 | 
			
		||||
			try {
 | 
			
		||||
				Class<?> clazz = getClass().getClassLoader().loadClass(
 | 
			
		||||
						"org.apache.tiles.extras.complete.CompleteAutoloadTilesInitializer");
 | 
			
		||||
				this.tilesInitializer = (TilesInitializer) clazz.newInstance();
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex) {
 | 
			
		||||
				throw new IllegalStateException("Tiles-Extras 3.0 not available", ex);
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			this.tilesInitializer = null;
 | 
			
		||||
		}
 | 
			
		||||
		this.completeAutoload = completeAutoload;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the Tiles definitions, i.e. the list of files containing the definitions.
 | 
			
		||||
	 * Default is "/WEB-INF/tiles.xml".
 | 
			
		||||
	 */
 | 
			
		||||
	public void setDefinitions(String[] definitions) {
 | 
			
		||||
		this.definitions = definitions;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether to check Tiles definition files for a refresh at runtime.
 | 
			
		||||
	 * Default is "false".
 | 
			
		||||
	 */
 | 
			
		||||
	public void setCheckRefresh(boolean checkRefresh) {
 | 
			
		||||
		this.checkRefresh = checkRefresh;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether to validate the Tiles XML definitions. Default is "true".
 | 
			
		||||
	 */
 | 
			
		||||
	public void setValidateDefinitions(boolean validateDefinitions) {
 | 
			
		||||
		this.validateDefinitions = validateDefinitions;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the {@link org.apache.tiles.definition.DefinitionsFactory} implementation to use.
 | 
			
		||||
	 * Default is {@link org.apache.tiles.definition.UrlDefinitionsFactory},
 | 
			
		||||
	 * operating on definition resource URLs.
 | 
			
		||||
	 * <p>Specify a custom DefinitionsFactory, e.g. a UrlDefinitionsFactory subclass,
 | 
			
		||||
	 * to customize the creation of Tiles Definition objects. Note that such a
 | 
			
		||||
	 * DefinitionsFactory has to be able to handle {@link java.net.URL} source objects,
 | 
			
		||||
	 * unless you configure a different TilesContainerFactory.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setDefinitionsFactoryClass(Class<? extends DefinitionsFactory> definitionsFactoryClass) {
 | 
			
		||||
		this.definitionsFactoryClass = definitionsFactoryClass;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the {@link org.apache.tiles.preparer.PreparerFactory} implementation to use.
 | 
			
		||||
	 * Default is {@link org.apache.tiles.preparer.BasicPreparerFactory}, creating
 | 
			
		||||
	 * shared instances for specified preparer classes.
 | 
			
		||||
	 * <p>Specify {@link SimpleSpringPreparerFactory} to autowire
 | 
			
		||||
	 * {@link org.apache.tiles.preparer.ViewPreparer} instances based on specified
 | 
			
		||||
	 * preparer classes, applying Spring's container callbacks as well as applying
 | 
			
		||||
	 * configured Spring BeanPostProcessors. If Spring's context-wide annotation-config
 | 
			
		||||
	 * has been activated, annotations in ViewPreparer classes will be automatically
 | 
			
		||||
	 * detected and applied.
 | 
			
		||||
	 * <p>Specify {@link SpringBeanPreparerFactory} to operate on specified preparer
 | 
			
		||||
	 * <i>names</i> instead of classes, obtaining the corresponding Spring bean from
 | 
			
		||||
	 * the DispatcherServlet's application context. The full bean creation process
 | 
			
		||||
	 * will be in the control of the Spring application context in this case,
 | 
			
		||||
	 * allowing for the use of scoped beans etc. Note that you need to define one
 | 
			
		||||
	 * Spring bean definition per preparer name (as used in your Tiles definitions).
 | 
			
		||||
	 * @see SimpleSpringPreparerFactory
 | 
			
		||||
	 * @see SpringBeanPreparerFactory
 | 
			
		||||
	 */
 | 
			
		||||
	public void setPreparerFactoryClass(Class<? extends PreparerFactory> preparerFactoryClass) {
 | 
			
		||||
		this.preparerFactoryClass = preparerFactoryClass;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether to use a MutableTilesContainer (typically the CachingTilesContainer
 | 
			
		||||
	 * implementation) for this application. Default is "false".
 | 
			
		||||
	 * @see org.apache.tiles.mgmt.MutableTilesContainer
 | 
			
		||||
	 * @see org.apache.tiles.mgmt.CachingTilesContainer
 | 
			
		||||
	 */
 | 
			
		||||
	public void setUseMutableTilesContainer(boolean useMutableTilesContainer) {
 | 
			
		||||
		this.useMutableTilesContainer = useMutableTilesContainer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setServletContext(ServletContext servletContext) {
 | 
			
		||||
		this.servletContext = servletContext;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Creates and exposes a TilesContainer for this web application,
 | 
			
		||||
	 * delegating to the TilesInitializer.
 | 
			
		||||
	 * @throws TilesException in case of setup failure
 | 
			
		||||
	 * @see #createTilesInitializer()
 | 
			
		||||
	 */
 | 
			
		||||
	public void afterPropertiesSet() throws TilesException {
 | 
			
		||||
 | 
			
		||||
		WildcardServletApplicationContext preliminaryContext =
 | 
			
		||||
				new WildcardServletApplicationContext(this.servletContext);
 | 
			
		||||
 | 
			
		||||
		if (this.tilesInitializer == null) {
 | 
			
		||||
			this.tilesInitializer = new SpringTilesInitializer();
 | 
			
		||||
		}
 | 
			
		||||
		this.tilesInitializer.initialize(preliminaryContext);
 | 
			
		||||
 | 
			
		||||
		if (this.completeAutoload) {
 | 
			
		||||
			// We need to do this after initialization simply because we're reusing the
 | 
			
		||||
			// original CompleteAutoloadTilesInitializer above. We cannot subclass
 | 
			
		||||
			// CompleteAutoloadTilesInitializer when compiling against Tiles 2.1...
 | 
			
		||||
			logger.debug("Registering Tiles 3.0 SpringLocaleResolver for complete-autoload setup");
 | 
			
		||||
			BasicTilesContainer container = (BasicTilesContainer) TilesAccess.getContainer(preliminaryContext);
 | 
			
		||||
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(container.getDefinitionsFactory());
 | 
			
		||||
			if (bw.isWritableProperty("localeResolver")) {
 | 
			
		||||
				bw.setPropertyValue("localeResolver", new SpringLocaleResolver());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Removes the TilesContainer from this web application.
 | 
			
		||||
	 * @throws TilesException in case of cleanup failure
 | 
			
		||||
	 */
 | 
			
		||||
	public void destroy() throws TilesException {
 | 
			
		||||
		this.tilesInitializer.destroy();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private class SpringTilesInitializer extends DefaultTilesInitializer {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) {
 | 
			
		||||
			return new SpringTilesContainerFactory();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private class SpringTilesContainerFactory extends BasicTilesContainerFactory {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public TilesContainer createContainer(ApplicationContext context) {
 | 
			
		||||
			TilesContainer container = super.createContainer(context);
 | 
			
		||||
			return (useMutableTilesContainer ? new CachingTilesContainer(container) : container);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
 | 
			
		||||
			if (definitions != null) {
 | 
			
		||||
				List<ApplicationResource> result = new LinkedList<ApplicationResource>();
 | 
			
		||||
				for (String definition : definitions) {
 | 
			
		||||
					result.addAll(applicationContext.getResources(definition));
 | 
			
		||||
				}
 | 
			
		||||
				return result;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				return super.getSources(applicationContext);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected BaseLocaleUrlDefinitionDAO instantiateLocaleDefinitionDao(ApplicationContext applicationContext,
 | 
			
		||||
				LocaleResolver resolver) {
 | 
			
		||||
			BaseLocaleUrlDefinitionDAO dao = super.instantiateLocaleDefinitionDao(applicationContext, resolver);
 | 
			
		||||
			if (checkRefresh && dao instanceof CachingLocaleUrlDefinitionDAO) {
 | 
			
		||||
				((CachingLocaleUrlDefinitionDAO) dao).setCheckRefresh(checkRefresh);
 | 
			
		||||
			}
 | 
			
		||||
			return dao;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected DefinitionsReader createDefinitionsReader(ApplicationContext context) {
 | 
			
		||||
			DigesterDefinitionsReader reader = (DigesterDefinitionsReader) super.createDefinitionsReader(context);
 | 
			
		||||
			reader.setValidating(validateDefinitions);
 | 
			
		||||
			return reader;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected DefinitionsFactory createDefinitionsFactory(ApplicationContext applicationContext,
 | 
			
		||||
				LocaleResolver resolver) {
 | 
			
		||||
 | 
			
		||||
			if (definitionsFactoryClass != null) {
 | 
			
		||||
				DefinitionsFactory factory = BeanUtils.instantiate(definitionsFactoryClass);
 | 
			
		||||
				if (factory instanceof org.apache.tiles.request.ApplicationContextAware) {
 | 
			
		||||
					((org.apache.tiles.request.ApplicationContextAware) factory)
 | 
			
		||||
							.setApplicationContext(applicationContext);
 | 
			
		||||
				}
 | 
			
		||||
				BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(factory);
 | 
			
		||||
				if (bw.isWritableProperty("localeResolver")) {
 | 
			
		||||
					bw.setPropertyValue("localeResolver", resolver);
 | 
			
		||||
				}
 | 
			
		||||
				if (bw.isWritableProperty("definitionDAO")) {
 | 
			
		||||
					bw.setPropertyValue("definitionDAO", createLocaleDefinitionDao(applicationContext, resolver));
 | 
			
		||||
				}
 | 
			
		||||
				return factory;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				return super.createDefinitionsFactory(applicationContext, resolver);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected PreparerFactory createPreparerFactory(ApplicationContext context) {
 | 
			
		||||
			if (preparerFactoryClass != null) {
 | 
			
		||||
				return BeanUtils.instantiate(preparerFactoryClass);
 | 
			
		||||
			} else {
 | 
			
		||||
				return super.createPreparerFactory(context);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected LocaleResolver createLocaleResolver(ApplicationContext context) {
 | 
			
		||||
			return new SpringLocaleResolver();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected AttributeEvaluatorFactory createAttributeEvaluatorFactory(ApplicationContext context,
 | 
			
		||||
				LocaleResolver resolver) {
 | 
			
		||||
			return new BasicAttributeEvaluatorFactory(createELEvaluator(context));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private AttributeEvaluator createELEvaluator(ApplicationContext context) {
 | 
			
		||||
			if (tilesElPresent) {
 | 
			
		||||
				AttributeEvaluator evaluator = new TilesElActivator().createEvaluator();
 | 
			
		||||
				if (evaluator != null) {
 | 
			
		||||
					return evaluator;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return new DirectAttributeEvaluator();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private class TilesElActivator {
 | 
			
		||||
 | 
			
		||||
		public AttributeEvaluator createEvaluator() {
 | 
			
		||||
			try {
 | 
			
		||||
				// jsp-api-2.1 doesn't default instantiate a factory for us
 | 
			
		||||
				JspFactory factory = JspFactory.getDefaultFactory();
 | 
			
		||||
				if ((factory != null) && (factory.getJspApplicationContext(servletContext).getExpressionFactory() != null)) {
 | 
			
		||||
					logger.info("Found JSP 2.1 ExpressionFactory");
 | 
			
		||||
					ELAttributeEvaluator evaluator = new ELAttributeEvaluator();
 | 
			
		||||
					evaluator.setExpressionFactory(factory.getJspApplicationContext(servletContext).getExpressionFactory());
 | 
			
		||||
					evaluator.setResolver(new CompositeELResolverImpl());
 | 
			
		||||
					return evaluator;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch (Throwable ex) {
 | 
			
		||||
				logger.warn("Could not obtain JSP 2.1 ExpressionFactory", ex);
 | 
			
		||||
			}
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static class CompositeELResolverImpl extends CompositeELResolver {
 | 
			
		||||
 | 
			
		||||
		public CompositeELResolverImpl() {
 | 
			
		||||
			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));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,157 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.ServletContext;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.TilesContainer;
 | 
			
		||||
import org.apache.tiles.access.TilesAccess;
 | 
			
		||||
import org.apache.tiles.renderer.DefinitionRenderer;
 | 
			
		||||
import org.apache.tiles.request.ApplicationContext;
 | 
			
		||||
import org.apache.tiles.request.Request;
 | 
			
		||||
import org.apache.tiles.request.render.Renderer;
 | 
			
		||||
import org.apache.tiles.request.servlet.ServletRequest;
 | 
			
		||||
import org.apache.tiles.request.servlet.ServletUtil;
 | 
			
		||||
import org.springframework.web.servlet.support.JstlUtils;
 | 
			
		||||
import org.springframework.web.servlet.support.RequestContext;
 | 
			
		||||
import org.springframework.web.servlet.support.RequestContextUtils;
 | 
			
		||||
import org.springframework.web.servlet.view.AbstractUrlBasedView;
 | 
			
		||||
import org.springframework.web.util.WebUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link org.springframework.web.servlet.View} implementation that renders
 | 
			
		||||
 * through the Tiles Request API. The "url" property is interpreted as name of a
 | 
			
		||||
 * Tiles definition.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Nicolas Le Bas
 | 
			
		||||
 * @author mick semb wever
 | 
			
		||||
 * @author Rossen Stoyanchev
 | 
			
		||||
 * @since 3.2
 | 
			
		||||
 */
 | 
			
		||||
public class TilesView extends AbstractUrlBasedView {
 | 
			
		||||
 | 
			
		||||
	private Renderer renderer;
 | 
			
		||||
 | 
			
		||||
	private boolean exposeForwardAttributes = false;
 | 
			
		||||
 | 
			
		||||
	private boolean exposeJstlAttributes = true;
 | 
			
		||||
 | 
			
		||||
	private ApplicationContext applicationContext;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the {@link Renderer} to use.
 | 
			
		||||
	 * If not set, by default {@link DefinitionRenderer} is used.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setRenderer(Renderer renderer) {
 | 
			
		||||
		this.renderer = renderer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Whether to expose JSTL attributes. By default set to {@code true}.
 | 
			
		||||
	 * @see JstlUtils#exposeLocalizationContext(RequestContext)
 | 
			
		||||
	 */
 | 
			
		||||
	protected void setExposeJstlAttributes(boolean exposeJstlAttributes) {
 | 
			
		||||
		this.exposeJstlAttributes = exposeJstlAttributes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void initServletContext(ServletContext servletContext) {
 | 
			
		||||
		super.initServletContext(servletContext);
 | 
			
		||||
		if (servletContext.getMajorVersion() == 2 && servletContext.getMinorVersion() < 5) {
 | 
			
		||||
			this.exposeForwardAttributes = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void afterPropertiesSet() throws Exception {
 | 
			
		||||
		super.afterPropertiesSet();
 | 
			
		||||
 | 
			
		||||
		this.applicationContext = ServletUtil.getApplicationContext(getServletContext());
 | 
			
		||||
 | 
			
		||||
		if (this.renderer == null) {
 | 
			
		||||
			TilesContainer container = TilesAccess.getContainer(this.applicationContext);
 | 
			
		||||
			this.renderer = new DefinitionRenderer(container);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean checkResource(final Locale locale) throws Exception {
 | 
			
		||||
		Request request = new ServletRequest(this.applicationContext, null, null) {
 | 
			
		||||
			@Override
 | 
			
		||||
			public Locale getRequestLocale() {
 | 
			
		||||
				return locale;
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		return this.renderer.isRenderable(getUrl(), request);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
 | 
			
		||||
			HttpServletResponse response) throws Exception {
 | 
			
		||||
 | 
			
		||||
		exposeModelAsRequestAttributes(model, request);
 | 
			
		||||
 | 
			
		||||
		if (this.exposeJstlAttributes) {
 | 
			
		||||
			ServletContext servletContext = getServletContext();
 | 
			
		||||
			JstlUtils.exposeLocalizationContext(new RequestContext(request, servletContext));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!response.isCommitted()) {
 | 
			
		||||
			// Tiles is going to use a forward, but some web containers (e.g.
 | 
			
		||||
			// OC4J 10.1.3)
 | 
			
		||||
			// do not properly expose the Servlet 2.4 forward request
 | 
			
		||||
			// attributes... However,
 | 
			
		||||
			// must not do this on Servlet 2.5 or above, mainly for GlassFish
 | 
			
		||||
			// compatibility.
 | 
			
		||||
			if (this.exposeForwardAttributes) {
 | 
			
		||||
				try {
 | 
			
		||||
					WebUtils.exposeForwardRequestAttributes(request);
 | 
			
		||||
				} catch (Exception ex) {
 | 
			
		||||
					// Servlet container rejected to set internal attributes,
 | 
			
		||||
					// e.g. on TriFork.
 | 
			
		||||
					this.exposeForwardAttributes = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Request tilesRequest = createTilesRequest(request, response);
 | 
			
		||||
		this.renderer.render(getUrl(), tilesRequest);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a Tiles {@link Request}. This implementation creates a
 | 
			
		||||
	 * {@link ServletRequest}.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param request the current request
 | 
			
		||||
	 * @param response the current response
 | 
			
		||||
	 * @return the Tiles request
 | 
			
		||||
	 */
 | 
			
		||||
	protected Request createTilesRequest(final HttpServletRequest request, HttpServletResponse response) {
 | 
			
		||||
		return new ServletRequest(this.applicationContext, request, response) {
 | 
			
		||||
			@Override
 | 
			
		||||
			public Locale getRequestLocale() {
 | 
			
		||||
				return RequestContextUtils.getLocale(request);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.request.render.Renderer;
 | 
			
		||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convenience subclass of {@link UrlBasedViewResolver} that supports
 | 
			
		||||
 * {@link TilesView} (i.e. Tiles definitions) and custom subclasses of it.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Nicolas Le Bas
 | 
			
		||||
 * @author Rossen Stoyanchev
 | 
			
		||||
 * @since 3.2
 | 
			
		||||
 */
 | 
			
		||||
public class TilesViewResolver extends UrlBasedViewResolver {
 | 
			
		||||
 | 
			
		||||
	private Renderer renderer;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	@SuppressWarnings("rawtypes")
 | 
			
		||||
	protected Class getViewClass() {
 | 
			
		||||
		return TilesView.class;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the {@link Renderer} to use.
 | 
			
		||||
	 * If not set, by default {@link DefinitionRenderer} is used.
 | 
			
		||||
	 * @see TilesView#setRenderer(Renderer)
 | 
			
		||||
	 */
 | 
			
		||||
	public void setRenderer(Renderer renderer) {
 | 
			
		||||
		this.renderer = renderer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected TilesView buildView(String viewName) throws Exception {
 | 
			
		||||
		TilesView view = (TilesView) super.buildView(viewName);
 | 
			
		||||
		view.setRenderer(this.renderer);
 | 
			
		||||
		return view;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Support classes for the integration of
 | 
			
		||||
 * <a href="http://tiles.apache.org">Tiles3</a>
 | 
			
		||||
 * (the standalone version of Tiles) as Spring web view technology.
 | 
			
		||||
 * Contains a View implementation for Tiles definitions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
package org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertNotNull;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.access.TilesAccess;
 | 
			
		||||
import org.apache.tiles.impl.BasicTilesContainer;
 | 
			
		||||
import org.apache.tiles.request.ApplicationContext;
 | 
			
		||||
import org.apache.tiles.request.Request;
 | 
			
		||||
import org.apache.tiles.request.servlet.ServletRequest;
 | 
			
		||||
import org.apache.tiles.request.servlet.ServletUtil;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletResponse;
 | 
			
		||||
import org.springframework.mock.web.MockServletContext;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test fixture for {@link TilesConfigurer}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Nicolas Le Bas
 | 
			
		||||
 */
 | 
			
		||||
public class TilesConfigurerTests {
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void simpleBootstrap() {
 | 
			
		||||
		MockServletContext servletContext = new MockServletContext();
 | 
			
		||||
 | 
			
		||||
		TilesConfigurer tc = new TilesConfigurer();
 | 
			
		||||
		tc.setDefinitions(new String[] { "/org/springframework/web/servlet/view/tiles3/tiles-definitions.xml" });
 | 
			
		||||
		tc.setCheckRefresh(true);
 | 
			
		||||
		tc.setServletContext(servletContext);
 | 
			
		||||
		tc.afterPropertiesSet();
 | 
			
		||||
 | 
			
		||||
		ApplicationContext tilesContext = ServletUtil.getApplicationContext(servletContext);
 | 
			
		||||
 | 
			
		||||
		BasicTilesContainer container = (BasicTilesContainer) TilesAccess.getContainer(tilesContext);
 | 
			
		||||
		Request requestContext = new ServletRequest(container.getApplicationContext(),
 | 
			
		||||
				new MockHttpServletRequest(), new MockHttpServletResponse());
 | 
			
		||||
		assertNotNull(container.getDefinitionsFactory().getDefinition("test", requestContext));
 | 
			
		||||
 | 
			
		||||
		tc.destroy();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration
 | 
			
		||||
	public static class AppConfig {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import static org.easymock.EasyMock.eq;
 | 
			
		||||
import static org.easymock.EasyMock.expect;
 | 
			
		||||
import static org.easymock.EasyMock.isA;
 | 
			
		||||
import static org.easymock.EasyMock.replay;
 | 
			
		||||
import static org.easymock.EasyMock.verify;
 | 
			
		||||
import static org.junit.Assert.assertNull;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.request.Request;
 | 
			
		||||
import org.apache.tiles.request.render.Renderer;
 | 
			
		||||
import org.easymock.EasyMock;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.springframework.mock.web.MockServletContext;
 | 
			
		||||
import org.springframework.web.context.support.StaticWebApplicationContext;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test fixture for {@link TilesViewResolver}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author mick semb wever
 | 
			
		||||
 */
 | 
			
		||||
public class TilesViewResolverTests {
 | 
			
		||||
 | 
			
		||||
	private TilesViewResolver viewResolver;
 | 
			
		||||
 | 
			
		||||
	private Renderer renderer;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Before
 | 
			
		||||
	public void setUp() {
 | 
			
		||||
		StaticWebApplicationContext wac = new StaticWebApplicationContext();
 | 
			
		||||
		wac.setServletContext(new MockServletContext());
 | 
			
		||||
		wac.refresh();
 | 
			
		||||
 | 
			
		||||
		this.renderer = EasyMock.createMock(Renderer.class);
 | 
			
		||||
 | 
			
		||||
		this.viewResolver = new TilesViewResolver();
 | 
			
		||||
		this.viewResolver.setRenderer(this.renderer);
 | 
			
		||||
		this.viewResolver.setApplicationContext(wac);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testResolve() throws Exception {
 | 
			
		||||
		expect(this.renderer.isRenderable(eq("/template.test"), isA(Request.class))).andReturn(true);
 | 
			
		||||
		expect(this.renderer.isRenderable(eq("/nonexistent.test"), isA(Request.class))).andReturn(false);
 | 
			
		||||
		replay(this.renderer);
 | 
			
		||||
 | 
			
		||||
		assertTrue(this.viewResolver.resolveViewName("/template.test", Locale.ITALY) instanceof TilesView);
 | 
			
		||||
		assertNull(this.viewResolver.resolveViewName("/nonexistent.test", Locale.ITALY));
 | 
			
		||||
 | 
			
		||||
		verify(this.renderer);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2012 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 org.springframework.web.servlet.view.tiles3;
 | 
			
		||||
 | 
			
		||||
import static org.easymock.EasyMock.and;
 | 
			
		||||
import static org.easymock.EasyMock.createMock;
 | 
			
		||||
import static org.easymock.EasyMock.eq;
 | 
			
		||||
import static org.easymock.EasyMock.isA;
 | 
			
		||||
import static org.easymock.EasyMock.replay;
 | 
			
		||||
import static org.easymock.EasyMock.verify;
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.apache.tiles.request.ApplicationContext;
 | 
			
		||||
import org.apache.tiles.request.Request;
 | 
			
		||||
import org.apache.tiles.request.render.Renderer;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletResponse;
 | 
			
		||||
import org.springframework.mock.web.MockServletContext;
 | 
			
		||||
import org.springframework.web.context.support.StaticWebApplicationContext;
 | 
			
		||||
import org.springframework.web.servlet.DispatcherServlet;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test fixture for {@link TilesView}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author mick semb wever
 | 
			
		||||
 */
 | 
			
		||||
public class TilesViewTests {
 | 
			
		||||
 | 
			
		||||
	private static final String VIEW_PATH = "template.test";
 | 
			
		||||
 | 
			
		||||
	private TilesView view;
 | 
			
		||||
 | 
			
		||||
	private Renderer renderer;
 | 
			
		||||
 | 
			
		||||
	private MockHttpServletRequest request;
 | 
			
		||||
 | 
			
		||||
	private MockHttpServletResponse response;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Before
 | 
			
		||||
	public void setUp() throws Exception {
 | 
			
		||||
		MockServletContext servletContext = new MockServletContext();
 | 
			
		||||
		StaticWebApplicationContext wac = new StaticWebApplicationContext();
 | 
			
		||||
		wac.setServletContext(servletContext);
 | 
			
		||||
		wac.refresh();
 | 
			
		||||
 | 
			
		||||
		request = new MockHttpServletRequest();
 | 
			
		||||
		request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
 | 
			
		||||
 | 
			
		||||
		response = new MockHttpServletResponse();
 | 
			
		||||
 | 
			
		||||
		renderer = createMock(Renderer.class);
 | 
			
		||||
 | 
			
		||||
		view = new TilesView();
 | 
			
		||||
		view.setServletContext(servletContext);
 | 
			
		||||
		view.setRenderer(renderer);
 | 
			
		||||
		view.setUrl(VIEW_PATH);
 | 
			
		||||
		view.afterPropertiesSet();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testRender() throws Exception {
 | 
			
		||||
		Map<String, Object> model = new HashMap<String, Object>();
 | 
			
		||||
		model.put("modelAttribute", "modelValue");
 | 
			
		||||
 | 
			
		||||
		ApplicationContext tilesContext = createMock(ApplicationContext.class);
 | 
			
		||||
 | 
			
		||||
		renderer.render(eq(VIEW_PATH), and(isA(Request.class), isA(Request.class)));
 | 
			
		||||
		replay(tilesContext, renderer);
 | 
			
		||||
 | 
			
		||||
		view.render(model, request, response);
 | 
			
		||||
 | 
			
		||||
		assertEquals("modelValue", request.getAttribute("modelAttribute"));
 | 
			
		||||
		verify(tilesContext, renderer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
log4j.rootCategory=INFO, stdout
 | 
			
		||||
 | 
			
		||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 | 
			
		||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 | 
			
		||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
 | 
			
		||||
 | 
			
		||||
log4j.category.org.springframework.web=DEBUG
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8" ?>
 | 
			
		||||
<!DOCTYPE tiles-definitions PUBLIC
 | 
			
		||||
		"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
 | 
			
		||||
		"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
 | 
			
		||||
 | 
			
		||||
<tiles-definitions>
 | 
			
		||||
 | 
			
		||||
	<definition name="test" template="/WEB-INF/tiles/test.jsp"/>
 | 
			
		||||
 | 
			
		||||
</tiles-definitions>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
ext.mergeIntoProject = project(':spring-webmvc')
 | 
			
		||||
apply from: "${rootProject.projectDir}/merge-dist.gradle"
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ Changes in version 3.2 RC1 (2012-11-04)
 | 
			
		|||
* use concurrent cache to improve performance of GenericTypeResolver (SPR-8701)
 | 
			
		||||
* cache and late resolve annotations on bean properties to improve performance (SPR-9166)
 | 
			
		||||
* allow PropertyResolver implementations to ignore unresolvable ${placeholders} (SPR-9569)
 | 
			
		||||
 | 
			
		||||
* add integration with Tiles 3
 | 
			
		||||
 | 
			
		||||
Changes in version 3.2 M2 (2012-09-11)
 | 
			
		||||
--------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -839,7 +839,9 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
 | 
			
		|||
 | 
			
		||||
    <para><emphasis>NOTE:</emphasis> This section focuses on Spring's support
 | 
			
		||||
    for Tiles 2 (the standalone version of Tiles, requiring Java 5+) in the
 | 
			
		||||
    <literal>org.springframework.web.servlet.view.tiles2</literal> package.
 | 
			
		||||
    <literal>org.springframework.web.servlet.view.tiles2</literal> package as
 | 
			
		||||
    as well as Tiles 3 in the
 | 
			
		||||
    <literal>org.springframework.web.servlet.view.tiles3</literal> package.
 | 
			
		||||
    Spring also continues to support Tiles 1.x (a.k.a. "Struts Tiles", as
 | 
			
		||||
    shipped with Struts 1.1+; compatible with Java 1.4) in the original
 | 
			
		||||
    <literal>org.springframework.web.servlet.view.tiles</literal>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue