This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit faa236fab5f93f8bbb93dd20e6dfd25907cd2ebb Author: Mark Thomas <ma...@apache.org> AuthorDate: Mon Nov 16 17:27:27 2020 +0000 BZ 64872 Optimised ELInterpreter for literal booleans & strings This is not strictly spec compliant hence it isn't enabled by default but it should work for many applicaitons. https://bz.apache.org/bugzilla/show_bug.cgi?id=64872 --- .../optimizations/ELInterpreterTagSetters.java | 268 ++++++++++ .../optimizations/TestELInterpreterTagSetters.java | 547 +++++++++++++++++++++ test/webapp/WEB-INF/tag-setters.tld | 245 +++++++++ test/webapp/bug6nnnn/bug64872-bigdecimal.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-biginteger.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-boolean.jsp | 37 ++ test/webapp/bug6nnnn/bug64872-byte.jsp | 32 ++ test/webapp/bug6nnnn/bug64872-character.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-double.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-float.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-integer.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-long.jsp | 30 ++ .../webapp/bug6nnnn/bug64872-primitive-boolean.jsp | 37 ++ test/webapp/bug6nnnn/bug64872-primitive-byte.jsp | 32 ++ .../bug6nnnn/bug64872-primitive-character.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-primitive-double.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-primitive-float.jsp | 30 ++ .../webapp/bug6nnnn/bug64872-primitive-integer.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-primitive-long.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-primitive-short.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-short.jsp | 30 ++ test/webapp/bug6nnnn/bug64872-string.jsp | 33 ++ test/webapp/bug6nnnn/bug64872-timeunit.jsp | 33 ++ webapps/docs/jasper-howto.xml | 7 +- 24 files changed, 1690 insertions(+), 1 deletion(-) diff --git a/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java b/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java new file mode 100644 index 0000000..38feb96 --- /dev/null +++ b/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java @@ -0,0 +1,268 @@ +/* + * 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.optimizations; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.el.ELResolver; + +import org.apache.jasper.JspCompilationContext; +import org.apache.jasper.compiler.ELInterpreter; +import org.apache.jasper.compiler.JspUtil; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; + +/** + * A non-specification compliant {@link ELInterpreter} that optimizes a subset + * of setters for tag attributes. + * <p> + * The cases optimized by this implementation are: + * <ul> + * <li>expressions that are solely a literal boolean</li> + * <li>expressions that are solely a constant string used (with coercion where + * necessary) with a setter that accepts:</li> + * <ul> + * <li>boolean / Boolean</li> + * <li>char / Character</li> + * <li>BigDecimal</li> + * <li>long / Long</li> + * <li>int / Integer</li> + * <li>short / Short</li> + * <li>byte / Byte</li> + * <li>double / Double</li> + * <li>float / Float</li> + * <li>BigInteger</li> + * <li>Enum</li> + * <li>String</li> + * </ul> + * </ul> + * The specification compliance issue is that it essentially skips the first + * three {@link ELResolver}s listed in section JSP.2.9 and effectively hard + * codes the use of the 4th {@link ELResolver} in that list. + * + * @see "https://bz.apache.org/bugzilla/show_bug.cgi?id=64872" + */ +public class ELInterpreterTagSetters implements ELInterpreter { + + // Can't be static + private final Log log = LogFactory.getLog(ELInterpreterTagSetters.class); + + private final Pattern PATTERN_BOOLEAN = Pattern.compile("[$][{]([\"']?)(true|false)\\1[}]"); + private final Pattern PATTERN_STRING_CONSTANT = Pattern.compile("[$][{]([\"'])(\\w+)\\1[}]"); + private final Pattern PATTERN_NUMERIC = Pattern.compile("[$][{]([\"'])([+-]?\\d+(\\.\\d+)?)\\1[}]"); + + @Override + public String interpreterCall(JspCompilationContext context, + boolean isTagFile, String expression, + Class<?> expectedType, String fnmapvar) { + + String result = null; + + // Boolean + if (Boolean.TYPE == expectedType) { + Matcher m = PATTERN_BOOLEAN.matcher(expression); + if (m.matches()) { + result = m.group(2); + } + } else if (Boolean.class == expectedType) { + Matcher m = PATTERN_BOOLEAN.matcher(expression); + if (m.matches()) { + if ("true".equals(m.group(2))) { + result = "Boolean.TRUE"; + } else { + result = "Boolean.FALSE"; + } + } + // Character + } else if (Character.TYPE == expectedType) { + Matcher m = PATTERN_STRING_CONSTANT.matcher(expression); + if (m.matches()) { + return "\'" + m.group(2).charAt(0) + "\'"; + } + } else if (Character.class == expectedType) { + Matcher m = PATTERN_STRING_CONSTANT.matcher(expression); + if (m.matches()) { + return "Character.valueOf(\'" + m.group(2).charAt(0) + "\')"; + } + // Numeric - BigDecimal + } else if (BigDecimal.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + BigDecimal unused = new BigDecimal(m.group(2)); + result = "new java.math.BigDecimal(\"" + m.group(2) + "\")"; + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to BigDecimal", e); + // Continue and resolve the value at runtime + } + } + // Numeric - long/Long + } else if (Long.TYPE == expectedType || Long.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + Long unused = Long.valueOf(m.group(2)); + if (expectedType.isPrimitive()) { + // Long requires explicit declaration as a long literal + result = m.group(2) + "L"; + } else { + result = "Long.valueOf(\"" + m.group(2) + "\")"; + } + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to Long", e); + // Continue and resolve the value at runtime + } + } + // Numeric - int/Integer + } else if (Integer.TYPE == expectedType || Integer.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + Integer unused = Integer.valueOf(m.group(2)); + if (expectedType.isPrimitive()) { + result = m.group(2); + } else { + result = "Integer.valueOf(\"" + m.group(2) + "\")"; + } + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to Integer", e); + // Continue and resolve the value at runtime + } + } + // Numeric - short/Short + } else if (Short.TYPE == expectedType || Short.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + Short unused = Short.valueOf(m.group(2)); + if (expectedType.isPrimitive()) { + // short requires a downcast + result = "(short) " + m.group(2); + } else { + result = "Short.valueOf(\"" + m.group(2) + "\")"; + } + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to Short", e); + // Continue and resolve the value at runtime + } + } + // Numeric - byte/Byte + } else if (Byte.TYPE == expectedType || Byte.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + Byte unused = Byte.valueOf(m.group(2)); + if (expectedType.isPrimitive()) { + // byte requires a downcast + result = "(byte) " + m.group(2); + } else { + result = "Byte.valueOf(\"" + m.group(2) + "\")"; + } + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to Byte", e); + // Continue and resolve the value at runtime + } + } + // Numeric - double/Double + } else if (Double.TYPE == expectedType || Double.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + Double unused = Double.valueOf(m.group(2)); + if (expectedType.isPrimitive()) { + result = m.group(2); + } else { + result = "Double.valueOf(\"" + m.group(2) + "\")"; + } + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to Double", e); + // Continue and resolve the value at runtime + } + } + // Numeric - float/Float + } else if (Float.TYPE == expectedType || Float.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + Float unused = Float.valueOf(m.group(2)); + if (expectedType.isPrimitive()) { + // Float requires explicit declaration as a float literal + result = m.group(2) + "f"; + } else { + result = "Float.valueOf(\"" + m.group(2) + "\")"; + } + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to Float", e); + // Continue and resolve the value at runtime + } + } + // Numeric - BigInteger + } else if (BigInteger.class == expectedType) { + Matcher m = PATTERN_NUMERIC.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings("unused") + BigInteger unused = new BigInteger(m.group(2)); + result = "new java.math.BigInteger(\"" + m.group(2) + "\")"; + } catch (NumberFormatException e) { + log.debug("Failed to convert [" + m.group(2) + "] to BigInteger", e); + // Continue and resolve the value at runtime + } + } + // Enum + } else if (expectedType.isEnum()){ + Matcher m = PATTERN_STRING_CONSTANT.matcher(expression); + if (m.matches()) { + try { + @SuppressWarnings({ "unchecked", "rawtypes" }) + Enum<?> enumValue = Enum.valueOf((Class<? extends Enum>) expectedType, m.group(2)); + result = expectedType.getName() + "." + enumValue.name(); + } catch (IllegalArgumentException iae) { + log.debug("Failed to convert [" + m.group(2) + "] to Enum type [" + expectedType.getName() + "]", iae); + // Continue and resolve the value at runtime + } + } + // String + } else if (String.class == expectedType) { + Matcher m = PATTERN_STRING_CONSTANT.matcher(expression); + if (m.matches()) { + result = "\"" + m.group(2) + "\""; + } + } + + if (result == null) { + result = JspUtil.interpreterCall(isTagFile, expression, expectedType, + fnmapvar); + } + + if (log.isDebugEnabled()) { + log.debug("Expression [" + expression + "], type [" + expectedType.getName() + "], returns [" + result + "]"); + } + + return result; + } +} diff --git a/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java b/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java new file mode 100644 index 0000000..5a6cf8f --- /dev/null +++ b/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java @@ -0,0 +1,547 @@ +/* + * 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.optimizations; + +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +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.ELInterpreter; +import org.apache.jasper.compiler.ELInterpreterFactory; +import org.apache.tomcat.util.buf.ByteChunk; + +@RunWith(Parameterized.class) +public class TestELInterpreterTagSetters extends TomcatBaseTest { + + private static final Integer ZERO = Integer.valueOf(0); + private static final Integer TWO = Integer.valueOf(2); + private static final Integer THREE = Integer.valueOf(3); + + @Parameters(name="{index}: {0} {1} {3},{4}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + + ELInterpreter[] elInterpreters = new ELInterpreter[] { + // Warm-up + // First call will trigger compilation (and therefore be slower) + // Call both to ensure both are warmed up + new ELInterpreterWrapper(true, "TagSetters"), + new ELInterpreterWrapper(false, "Default"), + // Compare times of these test runs + new ELInterpreterWrapper(true, "TagSetters"), + new ELInterpreterWrapper(false, "Default"), + }; + + for (ELInterpreter elInterpreter : elInterpreters) { + parameterSets.add(new Object[] { elInterpreter, "boolean", "false", ZERO, THREE }); + parameterSets.add(new Object[] { elInterpreter, "boolean", "true", THREE, THREE }); + parameterSets.add(new Object[] { elInterpreter, "primitive-boolean", "false", ZERO, THREE }); + parameterSets.add(new Object[] { elInterpreter, "primitive-boolean", "true", THREE, THREE }); + parameterSets.add(new Object[] { elInterpreter, "character", "b", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-character", "b", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "bigdecimal", "12.34", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "biginteger", "1234", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "long", "1234", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-long", "1234", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "integer", "1234", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-integer", "1234", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "short", "1234", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-short", "1234", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "byte", "12", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "byte", "-12", TWO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-byte", "12", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-byte", "-12", TWO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "double", "12.34", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-double", "12.34", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "float", "12.34", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "primitive-float", "12.34", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "timeunit", "SECONDS", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "string", "bar", ZERO, TWO }); + } + return parameterSets; + } + + + @Parameter(0) + public ELInterpreter elInterpreter; + @Parameter(1) + public String target; + @Parameter(2) + public String expectedValue; + @Parameter(3) + public int offset; + @Parameter(4) + public int len; + + + @Test + public void testTag() throws Exception { + Tomcat tomcat = getTomcatInstanceTestWebapp(false, true); + Context ctxt = (Context) tomcat.getHost().findChild("/test"); + ctxt.getServletContext().setAttribute(ELInterpreter.class.getCanonicalName(), elInterpreter); + + ByteChunk bc = getUrl("http://localhost:" + getPort() + "/test/bug6nnnn/bug64872-" + target + ".jsp"); + + String actual = bc.toString(); + + for (int i = offset; i < offset + len; i++) { + String expected = String.format("%02d The value of foo is [%s]", Integer.valueOf(i+1), expectedValue); + Assert.assertTrue(actual, actual.contains(expected)); + } + } + + + public static class TagPrimitiveBoolean extends SimpleTagSupport { + + private boolean foo; + + public boolean getFoo() { + return foo; + } + + public void setFoo(boolean foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagBoolean extends SimpleTagSupport { + + private Boolean foo; + + public Boolean getFoo() { + return foo; + } + + public void setFoo(Boolean foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagPrimitiveCharacter extends SimpleTagSupport { + + private char foo; + + public char getFoo() { + return foo; + } + + public void setFoo(char foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagCharacter extends SimpleTagSupport { + + private Character foo; + + public Character getFoo() { + return foo; + } + + public void setFoo(Character foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagPrimitiveLong extends SimpleTagSupport { + + private long foo; + + public long getFoo() { + return foo; + } + + public void setFoo(long foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagLong extends SimpleTagSupport { + + private Long foo; + + public Long getFoo() { + return foo; + } + + public void setFoo(Long foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagPrimitiveInteger extends SimpleTagSupport { + + private int foo; + + public int getFoo() { + return foo; + } + + public void setFoo(int foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagInteger extends SimpleTagSupport { + + private Integer foo; + + public Integer getFoo() { + return foo; + } + + public void setFoo(Integer foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagPrimitiveShort extends SimpleTagSupport { + + private short foo; + + public short getFoo() { + return foo; + } + + public void setFoo(short foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagShort extends SimpleTagSupport { + + private Short foo; + + public Short getFoo() { + return foo; + } + + public void setFoo(Short foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagPrimitiveByte extends SimpleTagSupport { + + private byte foo; + + public byte getFoo() { + return foo; + } + + public void setFoo(byte foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagByte extends SimpleTagSupport { + + private Byte foo; + + public Byte getFoo() { + return foo; + } + + public void setFoo(Byte foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagPrimitiveDouble extends SimpleTagSupport { + + private double foo; + + public double getFoo() { + return foo; + } + + public void setFoo(double foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagDouble extends SimpleTagSupport { + + private Double foo; + + public Double getFoo() { + return foo; + } + + public void setFoo(Double foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagPrimitiveFloat extends SimpleTagSupport { + + private float foo; + + public float getFoo() { + return foo; + } + + public void setFoo(float foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagFloat extends SimpleTagSupport { + + private Float foo; + + public Float getFoo() { + return foo; + } + + public void setFoo(Float foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagString extends SimpleTagSupport { + + private String foo; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagTimeUnit extends SimpleTagSupport { + + private TimeUnit foo; + + public TimeUnit getFoo() { + return foo; + } + + public void setFoo(TimeUnit foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagBigDecimal extends SimpleTagSupport { + + private BigDecimal foo; + + public BigDecimal getFoo() { + return foo; + } + + public void setFoo(BigDecimal foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + public static class TagBigInteger extends SimpleTagSupport { + + private BigInteger foo; + + public BigInteger getFoo() { + return foo; + } + + public void setFoo(BigInteger foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + + /* + * Wrapper so we can use sensible names in the test labels + */ + private static class ELInterpreterWrapper implements ELInterpreter { + + private final boolean optimised; + private final String name; + private volatile ELInterpreter elInterpreter = null; + + public ELInterpreterWrapper(boolean optimised, String name) { + this.optimised = optimised; + this.name = name; + } + + @Override + public String interpreterCall(JspCompilationContext context, boolean isTagFile, + String expression, Class<?> expectedType, String fnmapvar) { + return getElInterpreter().interpreterCall(context, isTagFile, expression, expectedType, fnmapvar); + } + + @Override + public String toString() { + return name; + } + + // Lazy init to avoid LogManager init issues when running parameterized tests + private ELInterpreter getElInterpreter() { + if (elInterpreter == null) { + synchronized (this) { + if (elInterpreter == null) { + if (optimised) { + elInterpreter = new ELInterpreterTagSetters(); + } else { + elInterpreter = new ELInterpreterFactory.DefaultELInterpreter(); + } + } + } + } + return elInterpreter; + } + } +} diff --git a/test/webapp/WEB-INF/tag-setters.tld b/test/webapp/WEB-INF/tag-setters.tld new file mode 100644 index 0000000..e02ae14 --- /dev/null +++ b/test/webapp/WEB-INF/tag-setters.tld @@ -0,0 +1,245 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<taglib xmlns="http://java.sun.com/xml/ns/j2ee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" + version="2.0"> + <tlib-version>1.0</tlib-version> + <short-name>tag-setters</short-name> + <uri>http://tomcat.apache.org/tag-setters</uri> + <tag> + <name>tagPrimitiveBoolean</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveBoolean</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>boolean</type> + </attribute> + </tag> + <tag> + <name>tagBoolean</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagBoolean</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Boolean</type> + </attribute> + </tag> + <tag> + <name>tagPrimitiveCharacter</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveCharacter</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>char</type> + </attribute> + </tag> + <tag> + <name>tagCharacter</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagCharacter</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Character</type> + </attribute> + </tag> + <tag> + <name>tagPrimitiveLong</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveLong</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>long</type> + </attribute> + </tag> + <tag> + <name>tagLong</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagLong</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Long</type> + </attribute> + </tag> + <tag> + <name>tagPrimitiveInteger</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveInteger</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>int</type> + </attribute> + </tag> + <tag> + <name>tagInteger</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagInteger</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Integer</type> + </attribute> + </tag> + <tag> + <name>tagPrimitiveShort</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveShort</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>short</type> + </attribute> + </tag> + <tag> + <name>tagShort</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagShort</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Short</type> + </attribute> + </tag> + <tag> + <name>tagPrimitiveByte</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveByte</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>byte</type> + </attribute> + </tag> + <tag> + <name>tagByte</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagByte</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Byte</type> + </attribute> + </tag> + <tag> + <name>tagPrimitiveDouble</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveDouble</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>double</type> + </attribute> + </tag> + <tag> + <name>tagDouble</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagDouble</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Double</type> + </attribute> + </tag> + <tag> + <name>tagPrimitiveFloat</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagPrimitiveFloat</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>float</type> + </attribute> + </tag> + <tag> + <name>tagFloat</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagFloat</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>Float</type> + </attribute> + </tag> + <tag> + <name>tagBigDecimal</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagBigDecimal</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>BigDecimal</type> + </attribute> + </tag> + <tag> + <name>tagBigInteger</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagBigInteger</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>BigInteger</type> + </attribute> + </tag> + <tag> + <name>tagString</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagString</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>String</type> + </attribute> + </tag> + <tag> + <name>tagTimeUnit</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagTimeUnit</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>java.util.concurrent.TimeUnit</type> + </attribute> + </tag> +</taglib> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-bigdecimal.jsp b/test/webapp/bug6nnnn/bug64872-bigdecimal.jsp new file mode 100644 index 0000000..9bd18ed --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-bigdecimal.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 BigDecimal test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagBigDecimal foo="${'12.34'}" />]</p> + <p>02 The value of foo is [<ts:tagBigDecimal foo='${"12.34"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-biginteger.jsp b/test/webapp/bug6nnnn/bug64872-biginteger.jsp new file mode 100644 index 0000000..0fcd1c6 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-biginteger.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 BigInteger test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagBigInteger foo="${'1234'}" />]</p> + <p>02 The value of foo is [<ts:tagBigInteger foo='${"1234"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-boolean.jsp b/test/webapp/bug6nnnn/bug64872-boolean.jsp new file mode 100644 index 0000000..7bdc126 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-boolean.jsp @@ -0,0 +1,37 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Boolean.TRUE test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagBoolean foo="${false}" />]</p> + <p>02 The value of foo is [<ts:tagBoolean foo="${'false'}" />]</p> + <p>03 The value of foo is [<ts:tagBoolean foo='${"false"}' />]</p> + <p>04 The value of foo is [<ts:tagBoolean foo="${true}" />]</p> + <p>05 The value of foo is [<ts:tagBoolean foo="${'true'}" />]</p> + <p>06 The value of foo is [<ts:tagBoolean foo='${"true"}' />]</p> + <%-- + <p>04 The value of foo is [<ts:tagBoolean foo="true" />]</p> + --%> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-byte.jsp b/test/webapp/bug6nnnn/bug64872-byte.jsp new file mode 100644 index 0000000..8696a0a --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-byte.jsp @@ -0,0 +1,32 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Byte test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagByte foo="${'12'}" />]</p> + <p>02 The value of foo is [<ts:tagByte foo='${"12"}' />]</p> + <p>03 The value of foo is [<ts:tagByte foo="${'-12'}" />]</p> + <p>04 The value of foo is [<ts:tagByte foo='${"-12"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-character.jsp b/test/webapp/bug6nnnn/bug64872-character.jsp new file mode 100644 index 0000000..0f6ec23 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-character.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Character test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagCharacter foo="${'bar'}" />]</p> + <p>02 The value of foo is [<ts:tagCharacter foo='${"bar"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-double.jsp b/test/webapp/bug6nnnn/bug64872-double.jsp new file mode 100644 index 0000000..799a0c0 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-double.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Double test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagDouble foo="${'12.34'}" />]</p> + <p>02 The value of foo is [<ts:tagDouble foo='${"12.34"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-float.jsp b/test/webapp/bug6nnnn/bug64872-float.jsp new file mode 100644 index 0000000..19d6226 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-float.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Float test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagFloat foo="${'12.34'}" />]</p> + <p>02 The value of foo is [<ts:tagFloat foo='${"12.34"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-integer.jsp b/test/webapp/bug6nnnn/bug64872-integer.jsp new file mode 100644 index 0000000..255d716 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-integer.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Integer test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagInteger foo="${'1234'}" />]</p> + <p>02 The value of foo is [<ts:tagInteger foo='${"1234"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-long.jsp b/test/webapp/bug6nnnn/bug64872-long.jsp new file mode 100644 index 0000000..2b7b4c8 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-long.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Long test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagLong foo="${'1234'}" />]</p> + <p>02 The value of foo is [<ts:tagLong foo='${"1234"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-boolean.jsp b/test/webapp/bug6nnnn/bug64872-primitive-boolean.jsp new file mode 100644 index 0000000..1f0073a --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-boolean.jsp @@ -0,0 +1,37 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 boolean false test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveBoolean foo="${false}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveBoolean foo="${'false'}" />]</p> + <p>03 The value of foo is [<ts:tagPrimitiveBoolean foo='${"false"}' />]</p> + <p>04 The value of foo is [<ts:tagPrimitiveBoolean foo="${true}" />]</p> + <p>05 The value of foo is [<ts:tagPrimitiveBoolean foo="${'true'}" />]</p> + <p>06 The value of foo is [<ts:tagPrimitiveBoolean foo='${"true"}' />]</p> + <%-- + <p>04 The value of foo is [<ts:tagBoolean foo="false" />]</p> + --%> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-byte.jsp b/test/webapp/bug6nnnn/bug64872-primitive-byte.jsp new file mode 100644 index 0000000..aed0705 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-byte.jsp @@ -0,0 +1,32 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 byte test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveByte foo="${'12'}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveByte foo='${"12"}' />]</p> + <p>03 The value of foo is [<ts:tagPrimitiveByte foo="${'-12'}" />]</p> + <p>04 The value of foo is [<ts:tagPrimitiveByte foo='${"-12"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-character.jsp b/test/webapp/bug6nnnn/bug64872-primitive-character.jsp new file mode 100644 index 0000000..03762a6 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-character.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 char test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveCharacter foo="${'bar'}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveCharacter foo='${"bar"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-double.jsp b/test/webapp/bug6nnnn/bug64872-primitive-double.jsp new file mode 100644 index 0000000..b1cd64b --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-double.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 double test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveDouble foo="${'12.34'}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveDouble foo='${"12.34"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-float.jsp b/test/webapp/bug6nnnn/bug64872-primitive-float.jsp new file mode 100644 index 0000000..c574a845 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-float.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 float test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveFloat foo="${'12.34'}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveFloat foo='${"12.34"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-integer.jsp b/test/webapp/bug6nnnn/bug64872-primitive-integer.jsp new file mode 100644 index 0000000..059f217 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-integer.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 int test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveInteger foo="${'1234'}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveInteger foo='${"1234"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-long.jsp b/test/webapp/bug6nnnn/bug64872-primitive-long.jsp new file mode 100644 index 0000000..bf900f2 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-long.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 long test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveLong foo="${'1234'}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveLong foo='${"1234"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-primitive-short.jsp b/test/webapp/bug6nnnn/bug64872-primitive-short.jsp new file mode 100644 index 0000000..275ca58 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-primitive-short.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 short test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagPrimitiveShort foo="${'1234'}" />]</p> + <p>02 The value of foo is [<ts:tagPrimitiveShort foo='${"1234"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-short.jsp b/test/webapp/bug6nnnn/bug64872-short.jsp new file mode 100644 index 0000000..cd4e19e --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-short.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 Short test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagShort foo="${'1234'}" />]</p> + <p>02 The value of foo is [<ts:tagShort foo='${"1234"}' />]</p> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-string.jsp b/test/webapp/bug6nnnn/bug64872-string.jsp new file mode 100644 index 0000000..4dfa711 --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-string.jsp @@ -0,0 +1,33 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 String test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagString foo="${'bar'}" />]</p> + <p>02 The value of foo is [<ts:tagString foo='${"bar"}' />]</p> + <%-- + <p>03 The value of foo is [<ts:tagString foo="bar" />]</p> + --%> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-timeunit.jsp b/test/webapp/bug6nnnn/bug64872-timeunit.jsp new file mode 100644 index 0000000..e21bc2d --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-timeunit.jsp @@ -0,0 +1,33 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 TimeUnit test case</title></head> + <body> + <% + for (int i=0; i < 1000000; i++) { + %> + <p>01 The value of foo is [<ts:tagTimeUnit foo="${'SECONDS'}" />]</p> + <p>02 The value of foo is [<ts:tagTimeUnit foo='${"SECONDS"}' />]</p> + <%-- + <p>03 The value of foo is [<ts:tagTimeUnit foo="SECONDS" />]</p> + --%> + <% + } + %> + </body> +</html> \ No newline at end of file diff --git a/webapps/docs/jasper-howto.xml b/webapps/docs/jasper-howto.xml index 56e731f..aea993c 100644 --- a/webapps/docs/jasper-howto.xml +++ b/webapps/docs/jasper-howto.xml @@ -399,8 +399,13 @@ with Jasper. 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. +alternative EL interpreter. A alternative interpreter primarily targetting tag +settings is provided at +<code>org.apache.jasper.optimizations.ELInterpreterTagSetters</code>. See the +javadoc for details of the optimisations and the impact they have on +specification compliance. </p> + </section> </body> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org