From 36940c5fc8ec34e56775d17152b34b136c80d9b8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 17 Feb 2010 21:54:21 +0000 Subject: [PATCH] only activate EL support if JSP ExpressionFactory actually available (SPR-6852) --- .../servlet/view/tiles2/TilesConfigurer.java | 41 ++++++++++++++++--- .../view/tiles2/TilesConfigurerTests.java | 7 ---- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/TilesConfigurer.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/TilesConfigurer.java index 609aa8992b6..f851362e352 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/TilesConfigurer.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/TilesConfigurer.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import javax.servlet.ServletContext; +import javax.servlet.jsp.JspFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -143,8 +144,6 @@ public class TilesConfigurer implements ServletContextAware, InitializingBean, D Boolean.toString(false)); this.tilesPropertyMap.put(DefinitionsFactory.LOCALE_RESOLVER_IMPL_PROPERTY, SpringLocaleResolver.class.getName()); - this.tilesPropertyMap.put(TilesContainerFactory.ATTRIBUTE_EVALUATOR_INIT_PARAM, tilesElPresent ? - "org.apache.tiles.evaluator.el.ELAttributeEvaluator" : DirectAttributeEvaluator.class.getName()); } @@ -288,6 +287,15 @@ public class TilesConfigurer implements ServletContextAware, InitializingBean, D * @see #createTilesInitializer() */ public void afterPropertiesSet() throws TilesException { + boolean activateEl = false; + if (tilesElPresent) { + activateEl = new JspExpressionChecker().isExpressionFactoryAvailable(); + if (!this.tilesPropertyMap.containsKey(TilesContainerFactory.ATTRIBUTE_EVALUATOR_INIT_PARAM)) { + this.tilesPropertyMap.put(TilesContainerFactory.ATTRIBUTE_EVALUATOR_INIT_PARAM, activateEl ? + "org.apache.tiles.evaluator.el.ELAttributeEvaluator" : DirectAttributeEvaluator.class.getName()); + } + } + SpringTilesApplicationContextFactory factory = new SpringTilesApplicationContextFactory(); factory.init(this.tilesPropertyMap); TilesApplicationContext preliminaryContext = factory.createApplicationContext(this.servletContext); @@ -300,6 +308,7 @@ public class TilesConfigurer implements ServletContextAware, InitializingBean, D // 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 2.2 LocaleResolver for complete-autoload setup"); try { BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getContainer(this.servletContext); DefinitionsFactory definitionsFactory = container.getDefinitionsFactory(); @@ -311,12 +320,12 @@ public class TilesConfigurer implements ServletContextAware, InitializingBean, D } } - if (tilesElPresent && this.tilesInitializer instanceof SpringTilesInitializer) { + if (activateEl && this.tilesInitializer instanceof SpringTilesInitializer) { // Again, we need to do this after initialization since SpringTilesContainerFactory // cannot override template methods that refer to Tiles 2.2 classes: in this case, // AttributeEvaluatorFactory as createAttributeEvaluatorFactory return type. BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getContainer(this.servletContext); - TilesElActivator.registerEvaluator(container); + new TilesElActivator().registerEvaluator(container); } } @@ -423,9 +432,29 @@ public class TilesConfigurer implements ServletContextAware, InitializingBean, D } - private static class TilesElActivator { + private class JspExpressionChecker { - public static void registerEvaluator(BasicTilesContainer container) { + public boolean isExpressionFactoryAvailable() { + try { + JspFactory factory = JspFactory.getDefaultFactory(); + if (factory != null && + factory.getJspApplicationContext(servletContext).getExpressionFactory() != null) { + logger.info("Found JSP 2.1 ExpressionFactory"); + return true; + } + } + catch (Throwable ex) { + logger.warn("Could not obtain JSP 2.1 ExpressionFactory", ex); + } + return false; + } + } + + + private class TilesElActivator { + + public void registerEvaluator(BasicTilesContainer container) { + logger.debug("Registering Tiles 2.2 AttributeEvaluatorFactory for JSP 2.1"); try { ClassLoader cl = TilesElActivator.class.getClassLoader(); Class aef = cl.loadClass("org.apache.tiles.evaluator.AttributeEvaluatorFactory"); diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java index bb230d04be1..05ad89e7dbd 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java @@ -16,11 +16,7 @@ package org.springframework.web.servlet.view.tiles2; -import java.util.Properties; - import org.apache.tiles.context.TilesRequestContext; -import org.apache.tiles.evaluator.impl.DirectAttributeEvaluator; -import org.apache.tiles.factory.TilesContainerFactory; import org.apache.tiles.impl.BasicTilesContainer; import org.apache.tiles.servlet.context.ServletTilesRequestContext; import org.apache.tiles.servlet.context.ServletUtil; @@ -41,9 +37,6 @@ public class TilesConfigurerTests { MockServletContext sc = new MockServletContext(); TilesConfigurer tc = new TilesConfigurer(); tc.setDefinitions(new String[] {"/org/springframework/web/servlet/view/tiles2/tiles-definitions.xml"}); - Properties props = new Properties(); - props.setProperty(TilesContainerFactory.ATTRIBUTE_EVALUATOR_INIT_PARAM, DirectAttributeEvaluator.class.getName()); - tc.setTilesProperties(props); tc.setServletContext(sc); tc.afterPropertiesSet();