Author: markt
Date: Tue Feb 12 14:50:39 2013
New Revision: 1445190
URL: http://svn.apache.org/r1445190
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54239
Enable applications to use a custom EL interpreter.
Based on a patch by Sheldon Shao.
Added:
tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreter.java (with
props)
tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreterFactory.java
(with props)
tomcat/trunk/test/org/apache/jasper/compiler/TestELInterpreterFactory.java
(with props)
Modified:
tomcat/trunk/java/org/apache/jasper/compiler/Generator.java
tomcat/trunk/java/org/apache/jasper/resources/LocalStrings.properties
tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_es.properties
tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_fr.properties
tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_ja.properties
tomcat/trunk/webapps/docs/jasper-howto.xml
Added: tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreter.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreter.java?rev=1445190&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreter.java (added)
+++ tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreter.java Tue Feb 12
14:50:39 2013
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.jasper.compiler;
+
+import org.apache.jasper.JspCompilationContext;
+
+/**
+ * Defines the interface for the expression language interpreter. This allows
+ * users to provide custom EL interpreter implementations that can optimise
+ * EL processing for an application by , for example, performing code
generation
+ * for simple expressions.
+ */
+public interface ELInterpreter {
+
+ /**
+ * Returns the string representing the code that will be inserted into the
+ * servlet generated for JSP. The default implementation creates a call to
+ * {@link org.apache.jasper.runtime.PageContextImpl#proprietaryEvaluate(
+ * String, Class, javax.servlet.jsp.PageContext,
+ * org.apache.jasper.runtime.ProtectedFunctionMapper, boolean)} but other
+ * implementations may produce more optimised code.
+ *
+ * @param expression a String containing zero or more "${}" expressions
+ * @param expectedType the expected type of the interpreted result
+ * @param fnmapvar Variable pointing to a function map.
+ * @param xmlEscape True if the result should do XML escaping
+ * @return a String representing a call to the EL interpreter.
+ */
+ public String interpreterCall(JspCompilationContext context,
+ boolean isTagFile, String expression,
+ Class<?> expectedType, String fnmapvar, boolean xmlEscape);
+}
Propchange: tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreterFactory.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreterFactory.java?rev=1445190&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreterFactory.java
(added)
+++ tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreterFactory.java Tue
Feb 12 14:50:39 2013
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.jasper.compiler;
+
+import javax.servlet.ServletContext;
+
+import org.apache.jasper.JspCompilationContext;
+
+/**
+ * Provides {@link ELInterpreter} instances for JSP compilation.
+ *
+ * The search order is as follows:
+ * <ol>
+ * <li>ELInterpreter instance or implementation class name provided as a
+ * ServletContext attribute</li>
+ * <li>Implementation class named in a ServletContext initialisation parameter
+ * </li>
+ * <li>Default implementation</li>
+ * </ol>
+ */
+public class ELInterpreterFactory {
+
+ public static final String EL_INTERPRETER_CLASS_NAME =
+ ELInterpreter.class.getName();
+
+ private static final ELInterpreter DEFAULT_INSTANCE =
+ new DefaultELInterpreter();
+
+
+ /**
+ * Obtain the correct EL Interpreter for the given web application.
+ */
+ public static ELInterpreter getELInterpreter(ServletContext context)
+ throws Exception {
+
+ ELInterpreter result = null;
+
+ // Search for an implementation
+ // 1. ServletContext attribute (set by application or cached by a
+ // previous call to this method).
+ Object attribute = context.getAttribute(EL_INTERPRETER_CLASS_NAME);
+ if (attribute instanceof ELInterpreter) {
+ return (ELInterpreter) attribute;
+ } else if (attribute instanceof String) {
+ result = createInstance(context, (String) attribute);
+ }
+
+ // 2. ServletContext init parameter
+ if (result == null) {
+ String className =
+ context.getInitParameter(EL_INTERPRETER_CLASS_NAME);
+ if (className != null) {
+ result = createInstance(context, className);
+ }
+ }
+
+ // 3. Default
+ if (result == null) {
+ result = DEFAULT_INSTANCE;
+ }
+
+ // Cache the result for next time
+ context.setAttribute(EL_INTERPRETER_CLASS_NAME, result);
+ return result;
+ }
+
+
+ private static ELInterpreter createInstance(ServletContext context,
+ String className) throws Exception {
+ return (ELInterpreter) context.getClassLoader().loadClass(
+ className).newInstance();
+ }
+
+
+ private ELInterpreterFactory() {
+ // Utility class. Hide default constructor.
+ }
+
+
+ public static class DefaultELInterpreter implements ELInterpreter {
+
+ @Override
+ public String interpreterCall(JspCompilationContext context,
+ boolean isTagFile, String expression,
+ Class<?> expectedType, String fnmapvar, boolean xmlEscape) {
+ return JspUtil.interpreterCall(isTagFile, expression, expectedType,
+ fnmapvar, xmlEscape);
+ }
+ }
+}
Propchange:
tomcat/trunk/java/org/apache/jasper/compiler/ELInterpreterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/java/org/apache/jasper/compiler/Generator.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/Generator.java?rev=1445190&r1=1445189&r2=1445190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/Generator.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/Generator.java Tue Feb 12
14:50:39 2013
@@ -125,6 +125,8 @@ class Generator {
private final DateFormat timestampFormat;
+ private final ELInterpreter elInterpreter;
+
/**
* @param s
* the input string
@@ -830,8 +832,8 @@ class Generator {
}
return v;
} else if (attr.isELInterpreterInput()) {
- v = JspUtil.interpreterCall(this.isTagFile, v, expectedType,
- attr.getEL().getMapName(), false);
+ v = elInterpreter.interpreterCall(ctxt, this.isTagFile, v,
+ expectedType, attr.getEL().getMapName(), false);
if (encode) {
return
"org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("
+ v + ", request.getCharacterEncoding())";
@@ -916,9 +918,10 @@ class Generator {
n.setBeginJavaLine(out.getJavaLine());
if (!pageInfo.isELIgnored() && (n.getEL() != null)) {
out.printil("out.write("
- + JspUtil.interpreterCall(this.isTagFile, n.getType() +
- "{" + n.getText() + "}", String.class,
- n.getEL().getMapName(), false) + ");");
+ + elInterpreter.interpreterCall(ctxt, this.isTagFile,
+ n.getType() + "{" + n.getText() + "}",
+ String.class, n.getEL().getMapName(), false) +
+ ");");
} else {
out.printil("out.write("
+ quote(n.getType() + "{" + n.getText() + "}") + ");");
@@ -2975,8 +2978,8 @@ class Generator {
// run attrValue through the expression interpreter
String mapName = (attr.getEL() != null) ? attr.getEL()
.getMapName() : null;
- attrValue = JspUtil.interpreterCall(this.isTagFile,
attrValue,
- c[0], mapName, false);
+ attrValue = elInterpreter.interpreterCall(ctxt,
+ this.isTagFile, attrValue, c[0], mapName, false);
}
} else {
attrValue = convertString(c[0], attrValue, localName,
@@ -3414,7 +3417,7 @@ class Generator {
/**
* Constructor.
*/
- Generator(ServletWriter out, Compiler compiler) {
+ Generator(ServletWriter out, Compiler compiler) throws JasperException {
this.out = out;
methodsBuffered = new ArrayList<>();
charArrayBuffer = null;
@@ -3423,6 +3426,16 @@ class Generator {
fragmentHelperClass = new FragmentHelperClass("Helper");
pageInfo = compiler.getPageInfo();
+ ELInterpreter elInterpreter = null;
+ try {
+ elInterpreter = ELInterpreterFactory.getELInterpreter(
+ compiler.getCompilationContext().getServletContext());
+ } catch (Exception e) {
+ err.jspError("jsp.error.el_interpreter_class.instantiation",
+ e.getMessage());
+ }
+ this.elInterpreter = elInterpreter;
+
/*
* Temporary hack. If a JSP page uses the "extends" attribute of the
* page directive, the _jspInit() method of the generated servlet class
Modified: tomcat/trunk/java/org/apache/jasper/resources/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/resources/LocalStrings.properties?rev=1445190&r1=1445189&r2=1445190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/resources/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/jasper/resources/LocalStrings.properties Tue
Feb 12 14:50:39 2013
@@ -387,3 +387,6 @@ xmlParser.skipBomFail=Failed to skip BOM
jsp.tldCache.noTldInJar=No TLD files were found in [{0}]. Consider adding the
JAR to the tomcat.util.scan.DefaultJarScanner.jarsToSkip or
org.apache.catalina.startup.TldConfig.jarsToSkip property in
CATALINA_BASE/conf/catalina.properties file.
jsp.tldCache.noTldSummary=At least one JAR was scanned for TLDs yet contained
no TLDs. Enable debug logging for this logger for a complete list of JARs that
were scanned but no TLDs were found in them. Skipping unneeded JARs during
scanning can improve startup time and JSP compilation time.
+
+#ELInterpreter
+jsp.error.el_interpreter_class.instantiation=Failed to load or instantiate
ELInterpreter class [{0}]
\ No newline at end of file
Modified:
tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_es.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_es.properties?rev=1445190&r1=1445189&r2=1445190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_es.properties
(original)
+++ tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_es.properties
Tue Feb 12 14:50:39 2013
@@ -370,3 +370,6 @@ jsp.message.jsp_unload_check = Revisando
xmlParser.skipBomFail = No pude saltar BOM al analizar flujo de entrada XML
jsp.tldCache.noTldInJar = No se han hallado ficheros TLD en [{0}]. Considera
a\u00F1adir el JAR a la propiedad tomcat.util.scan.DefaultJarScanner.jarsToSkip
en el fichero CATALINA_BASE/conf/catalina.propeperties.
jsp.tldCache.noTldSummary = Al menos un JAR, que se ha explorado buscando
TLDs, a\u00FAn no conten\u00EDa TLDs. Activar historial de depuraci\u00F3n para
este historiador para una completa lista de los JARs que fueron explorados y de
los que nos se hall\u00F3 TLDs. Saltarse JARs no necesarios durante la
exploraci\u00F3n puede dar lugar a una mejora de tiempo significativa en el
arranque y compilaci\u00F3n de JSP .
+
+#ELInterpreter
+jsp.error.el_interpreter_class.instantiation=No se puede cargar la clase
ELInterpreter llamada [{0}]
\ No newline at end of file
Modified:
tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_fr.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_fr.properties?rev=1445190&r1=1445189&r2=1445190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_fr.properties
(original)
+++ tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_fr.properties
Tue Feb 12 14:50:39 2013
@@ -211,3 +211,6 @@ jsp.error.attributes.not.allowed = {0} n
#jsp.error.jspoutput.nonemptybody=
#jsp.error.jspoutput.invalidUse=
#jsp.error.invalid.bean=
+
+#ELInterpreter
+jsp.error.el_interpreter_class.instantiation=Impossible de charger ou
d''instancier la classe ELInterpreter [{0}]
\ No newline at end of file
Modified:
tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_ja.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_ja.properties?rev=1445190&r1=1445189&r2=1445190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_ja.properties
(original)
+++ tomcat/trunk/java/org/apache/jasper/resources/LocalStrings_ja.properties
Tue Feb 12 14:50:39 2013
@@ -313,3 +313,5 @@ jsp.error.unbalanced.endtag=\u7d42\u4e86
jsp.error.invalid.bean=useBean\u306e\u30af\u30e9\u30b9\u5c5e\u6027 {0}
\u306e\u5024\u304c\u7121\u52b9\u3067\u3059
jsp.error.prefix.use_before_dcl=\u3053\u306e\u30bf\u30b0\u6307\u793a\u5b50\u3067\u6307\u5b9a\u3055\u308c\u3066\u3044\u308b\u30d7\u30ea\u30d5\u30a3\u30c3\u30af\u30b9
{0} \u306f\u3001\u3059\u3067\u306b\u30d5\u30a1\u30a4\u30eb {1} \u306e {2}
\u884c\u76ee\u306e\u30a2\u30af\u30b7\u30e7\u30f3\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059
+#ELInterpreter
+jsp.error.el_interpreter_class.instantiation=ELInterpreter
class\u306e\u30ed\u30fc\u30c9\u53c8\u306f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u5316\u306b\u5931\u6557\u3057\u307e\u3057\u305f
[{0}]
\ No newline at end of file
Added:
tomcat/trunk/test/org/apache/jasper/compiler/TestELInterpreterFactory.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/jasper/compiler/TestELInterpreterFactory.java?rev=1445190&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/jasper/compiler/TestELInterpreterFactory.java
(added)
+++ tomcat/trunk/test/org/apache/jasper/compiler/TestELInterpreterFactory.java
Tue Feb 12 14:50:39 2013
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.jasper.compiler;
+
+import java.io.File;
+
+import javax.servlet.ServletContext;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.jasper.JspCompilationContext;
+import org.apache.jasper.compiler.ELInterpreterFactory.DefaultELInterpreter;
+
+public class TestELInterpreterFactory extends TomcatBaseTest {
+
+ public static class SimpleELInterpreter implements ELInterpreter {
+
+ @Override
+ public String interpreterCall(JspCompilationContext context,
+ boolean isTagFile, String expression, Class<?> expectedType,
+ String fnmapvar, boolean xmlEscape) {
+ return expression;
+ }
+ }
+
+ @Test
+ public void testBug54239() throws Exception {
+ Tomcat tomcat = getTomcatInstance();
+
+ File appDir = new File("test/webapp-3.0");
+ Context ctx = tomcat.addWebapp(null, "/test",
appDir.getAbsolutePath());
+ tomcat.start();
+
+ ServletContext context = ctx.getServletContext();
+
+ ELInterpreter interpreter =
+ ELInterpreterFactory.getELInterpreter(context);
+ Assert.assertNotNull(interpreter);
+ Assert.assertTrue(interpreter instanceof DefaultELInterpreter);
+
+ context.removeAttribute(ELInterpreter.class.getName());
+
+ context.setAttribute(ELInterpreter.class.getName(),
+ SimpleELInterpreter.class.getName());
+ interpreter = ELInterpreterFactory.getELInterpreter(context);
+ Assert.assertNotNull(interpreter);
+ Assert.assertTrue(interpreter instanceof SimpleELInterpreter);
+
+ context.removeAttribute(ELInterpreter.class.getName());
+
+ SimpleELInterpreter simpleInterpreter = new SimpleELInterpreter();
+ context.setAttribute(ELInterpreter.class.getName(), simpleInterpreter);
+ interpreter = ELInterpreterFactory.getELInterpreter(context);
+ Assert.assertNotNull(interpreter);
+ Assert.assertTrue(interpreter instanceof SimpleELInterpreter);
+ Assert.assertTrue(interpreter == simpleInterpreter);
+
+ context.removeAttribute(ELInterpreter.class.getName());
+
+
+ context.setInitParameter(ELInterpreter.class.getName(),
+ SimpleELInterpreter.class.getName());
+
+ interpreter = ELInterpreterFactory.getELInterpreter(context);
+ Assert.assertNotNull(interpreter);
+ Assert.assertTrue(interpreter instanceof SimpleELInterpreter);
+
+ context.removeAttribute(ELInterpreter.class.getName());
+ }
+}
Propchange:
tomcat/trunk/test/org/apache/jasper/compiler/TestELInterpreterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/webapps/docs/jasper-howto.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/jasper-howto.xml?rev=1445190&r1=1445189&r2=1445190&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/jasper-howto.xml (original)
+++ tomcat/trunk/webapps/docs/jasper-howto.xml Tue Feb 12 14:50:39 2013
@@ -380,6 +380,28 @@ depending on the application.</li>
</p>
</section>
+<section name="Optimisation">
+<p>
+There are a number of extension points provided within Jasper that enable the
+user to optimise the behaviour for their environment.
+</p>
+
+<p>
+The first of these extension points is the tag plug-in mechanism. This allows
+alternative implementations of tag handlers to be provided for a web
application
+to use. Tag plug-ins are registered via a <code>tagPlugins.xml</code> file
+located under <code>WEB-INF</code>. A sample plug-in for the JSTL is included
+with Jasper.
+</p>
+
+<p>
+The second extension point is the Expression Language interpreter. Alternative
+interpreters may be configured through the <code>ServletContext</code>. See the
+<code>ELInterpreterFactory</code> javadoc for details of how to configure an
+alternative EL interpreter.
+</p>
+</section>
+
</body>
</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]