Author: remy.maucherat(a)jboss.com
Date: 2012-11-09 10:13:33 -0500 (Fri, 09 Nov 2012)
New Revision: 2118
Added:
branches/7.2.x/src/main/java/org/apache/jasper/el/JasperELResolver.java
Modified:
branches/7.2.x/src/main/java/org/apache/jasper/compiler/Compiler.java
branches/7.2.x/src/main/java/org/apache/jasper/compiler/Generator.java
branches/7.2.x/src/main/java/org/apache/jasper/compiler/PageInfo.java
branches/7.2.x/src/main/java/org/apache/jasper/compiler/TagPluginManager.java
branches/7.2.x/src/main/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java
branches/7.2.x/src/main/java/org/apache/jasper/runtime/JspApplicationContextImpl.java
branches/7.2.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java
branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Out.java
branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Set.java
branches/7.2.x/webapps/docs/changelog.xml
Log:
- 54012: Allow tagplugins compatibility with tag files
- Misc minor optimizations
Modified: branches/7.2.x/src/main/java/org/apache/jasper/compiler/Compiler.java
===================================================================
--- branches/7.2.x/src/main/java/org/apache/jasper/compiler/Compiler.java 2012-11-07
22:53:07 UTC (rev 2117)
+++ branches/7.2.x/src/main/java/org/apache/jasper/compiler/Compiler.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -106,7 +106,7 @@
// Setup page info area
pageInfo = new PageInfo(new BeanRepository(ctxt.getClassLoader(),
- errDispatcher), ctxt.getJspFile());
+ errDispatcher), ctxt.getJspFile(), ctxt.isTagFile());
JspConfig jspConfig = options.getJspConfig();
JspConfig.JspProperty jspProperty = jspConfig.findJspProperty(ctxt
Modified: branches/7.2.x/src/main/java/org/apache/jasper/compiler/Generator.java
===================================================================
--- branches/7.2.x/src/main/java/org/apache/jasper/compiler/Generator.java 2012-11-07
22:53:07 UTC (rev 2117)
+++ branches/7.2.x/src/main/java/org/apache/jasper/compiler/Generator.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -3146,7 +3146,7 @@
} else if (c == Long.class) {
return JspUtil.coerceToLong(s, isNamedAttribute);
} else if (c == Object.class) {
- return "new String(" + quoted + ")";
+ return quoted;
} else {
String className = JspUtil.getCanonicalName(c);
return "("
Modified: branches/7.2.x/src/main/java/org/apache/jasper/compiler/PageInfo.java
===================================================================
--- branches/7.2.x/src/main/java/org/apache/jasper/compiler/PageInfo.java 2012-11-07
22:53:07 UTC (rev 2117)
+++ branches/7.2.x/src/main/java/org/apache/jasper/compiler/PageInfo.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -100,10 +100,12 @@
private ArrayList<String> includeCoda;
private Vector pluginDcls; // Id's for tagplugin declarations
+ private boolean isTagFile = false;
- PageInfo(BeanRepository beanRepository, String jspFile) {
+ PageInfo(BeanRepository beanRepository, String jspFile, boolean isTagFile) {
this.jspFile = jspFile;
+ this.isTagFile = isTagFile;
this.beanRepository = beanRepository;
this.varInfoNames = new HashSet<String>();
this.taglibsMap = new HashMap();
@@ -122,6 +124,10 @@
imports.add(Constants.STANDARD_IMPORTS[i]);
}
+ public boolean isTagFile() {
+ return isTagFile;
+ }
+
/**
* Check if the plugin ID has been previously declared. Make a not
* that this Id is now declared.
Modified: branches/7.2.x/src/main/java/org/apache/jasper/compiler/TagPluginManager.java
===================================================================
---
branches/7.2.x/src/main/java/org/apache/jasper/compiler/TagPluginManager.java 2012-11-07
22:53:07 UTC (rev 2117)
+++
branches/7.2.x/src/main/java/org/apache/jasper/compiler/TagPluginManager.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -256,6 +256,11 @@
curNodes = node.getAtETag();
}
+ @Override
+ public boolean isTagFile() {
+ return pageInfo.isTagFile();
+ }
+
private Node.JspAttribute getNodeAttribute(String attribute) {
Node.JspAttribute[] attrs = node.getJspAttributes();
for (int i=0; attrs != null && i < attrs.length; i++) {
Modified:
branches/7.2.x/src/main/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java
===================================================================
---
branches/7.2.x/src/main/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java 2012-11-07
22:53:07 UTC (rev 2117)
+++
branches/7.2.x/src/main/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -120,5 +120,10 @@
* Get the value of an attribute in the current tagplugin context.
*/
Object getPluginAttribute(String attr);
+
+ /**
+ * Is the tag being used inside a tag file?
+ */
+ boolean isTagFile();
}
Added: branches/7.2.x/src/main/java/org/apache/jasper/el/JasperELResolver.java
===================================================================
--- branches/7.2.x/src/main/java/org/apache/jasper/el/JasperELResolver.java
(rev 0)
+++ branches/7.2.x/src/main/java/org/apache/jasper/el/JasperELResolver.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -0,0 +1,159 @@
+/*
+ * 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.el;
+
+import java.util.List;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.ResourceBundleELResolver;
+import javax.servlet.jsp.el.ImplicitObjectELResolver;
+import javax.servlet.jsp.el.ScopedAttributeELResolver;
+
+/**
+ * Jasper-specific CompositeELResolver that optimizes certain functions to avoid
+ * unnecessary resolver calls.
+ */
+public class JasperELResolver extends CompositeELResolver {
+
+ private int size;
+ private ELResolver[] resolvers;
+ private int appResolversSize;
+
+ public JasperELResolver(List<ELResolver> appResolvers) {
+ appResolversSize = appResolvers.size();
+ resolvers = new ELResolver[0];
+ size = resolvers.length;
+
+ add(new ImplicitObjectELResolver());
+ for (ELResolver appResolver : appResolvers) {
+ add(appResolver);
+ }
+ add(new MapELResolver());
+ add(new ResourceBundleELResolver());
+ add(new ListELResolver());
+ add(new ArrayELResolver());
+ add(new BeanELResolver());
+ add(new ScopedAttributeELResolver());
+ }
+
+ @Override
+ public synchronized void add(ELResolver elResolver) {
+ super.add(elResolver);
+
+ ELResolver[] nr = new ELResolver[size + 1];
+ System.arraycopy(resolvers, 0, nr, 0, size);
+ nr[size] = elResolver;
+
+ resolvers = nr;
+ size ++;
+ }
+
+ @Override
+ public Object getValue(ELContext context, Object base, Object property)
+ throws NullPointerException, PropertyNotFoundException, ELException {
+ context.setPropertyResolved(false);
+
+ int start;
+ Object result = null;
+
+ if (base == null) {
+ // call implicit and app resolvers
+ int index = 1 /* implicit */ + appResolversSize;
+ for (int i = 0; i < index; i++) {
+ result = resolvers[i].getValue(context, base, property);
+ if (context.isPropertyResolved()) {
+ return result;
+ }
+ }
+ // skip collection-based resolvers (map, resource, list, array, and
+ // bean)
+ start = index + 5;
+ } else {
+ // skip implicit resolver only
+ start = 1;
+ }
+
+ for (int i = start; i < size; i++) {
+ result = resolvers[i].getValue(context, base, property);
+ if (context.isPropertyResolved()) {
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Object invoke(ELContext context, Object base, Object method,
+ Class<?>[] paramTypes, Object[] params) {
+ String targetMethod = coerceToString(method);
+ if (targetMethod.length() == 0) {
+ throw new ELException(new NoSuchMethodException());
+ }
+
+ context.setPropertyResolved(false);
+
+ Object result = null;
+
+ // skip implicit and call app resolvers
+ int index = 1 /* implicit */ + appResolversSize;
+ for (int i = 1; i < index; i++) {
+ result = resolvers[i].invoke(
+ context, base, targetMethod, paramTypes, params);
+ if (context.isPropertyResolved()) {
+ return result;
+ }
+ }
+
+ // skip map, resource, list, and array resolvers
+ index += 4;
+ // call bean and the rest of resolvers
+ for (int i = index; i < size; i++) {
+ result = resolvers[i].invoke(
+ context, base, targetMethod, paramTypes, params);
+ if (context.isPropertyResolved()) {
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Copied from {@link org.apache.el.lang.ELSupport#coerceToString(Object)}.
+ */
+ private static final String coerceToString(final Object obj) {
+ if (obj == null) {
+ return "";
+ } else if (obj instanceof String) {
+ return (String) obj;
+ } else if (obj instanceof Enum<?>) {
+ return ((Enum<?>) obj).name();
+ } else {
+ return obj.toString();
+ }
+ }
+}
\ No newline at end of file
Modified:
branches/7.2.x/src/main/java/org/apache/jasper/runtime/JspApplicationContextImpl.java
===================================================================
---
branches/7.2.x/src/main/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 2012-11-07
22:53:07 UTC (rev 2117)
+++
branches/7.2.x/src/main/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -21,27 +21,20 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
-import javax.el.ArrayELResolver;
-import javax.el.BeanELResolver;
import javax.el.CompositeELResolver;
import javax.el.ELContextEvent;
import javax.el.ELContextListener;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
-import javax.el.ListELResolver;
-import javax.el.MapELResolver;
-import javax.el.ResourceBundleELResolver;
import javax.servlet.ServletContext;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.jsp.JspContext;
-import javax.servlet.jsp.el.ImplicitObjectELResolver;
-import javax.servlet.jsp.el.ScopedAttributeELResolver;
import org.apache.jasper.Constants;
import org.apache.jasper.el.ELContextImpl;
+import org.apache.jasper.el.JasperELResolver;
/**
* Implementation of JspApplicationContext
@@ -119,17 +112,7 @@
private ELResolver createELResolver() {
this.instantiated = true;
if (this.resolver == null) {
- CompositeELResolver r = new CompositeELResolver();
- r.add(new ImplicitObjectELResolver());
- for (Iterator itr = this.resolvers.iterator(); itr.hasNext();) {
- r.add((ELResolver) itr.next());
- }
- r.add(new MapELResolver());
- r.add(new ResourceBundleELResolver());
- r.add(new ListELResolver());
- r.add(new ArrayELResolver());
- r.add(new BeanELResolver());
- r.add(new ScopedAttributeELResolver());
+ CompositeELResolver r = new JasperELResolver(this.resolvers);
this.resolver = r;
}
return this.resolver;
Modified: branches/7.2.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java
===================================================================
--- branches/7.2.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java 2012-11-07
22:53:07 UTC (rev 2117)
+++ branches/7.2.x/src/main/java/org/apache/jasper/runtime/PageContextImpl.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -846,30 +846,70 @@
}
}
- private static String XmlEscape(String s) {
- if (s == null)
- return null;
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '<') {
- sb.append("<");
- } else if (c == '>') {
- sb.append(">");
- } else if (c == '\'') {
- sb.append("'"); // '
- } else if (c == '&') {
- sb.append("&");
- } else if (c == '"') {
- sb.append("""); // "
- } else {
- sb.append(c);
- }
- }
- return sb.toString();
- }
+ protected static String XmlEscape(String s) {
+ if (s == null) {
+ return null;
+ }
+ int len = s.length();
- /**
+ /*
+ * Look for any "bad" characters, Escape "bad" character was
found
+ */
+ // ASCII " 34 & 38 ' 39 < 60 > 62
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (c >= '\"' && c <= '>' &&
+ (c == '<' || c == '>' || c == '\''
|| c == '&' || c == '"')) {
+ // need to escape them and then quote the whole string
+ StringBuilder sb = new StringBuilder((int) (len * 1.2));
+ sb.append(s, 0, i);
+ int pos = i + 1;
+ for (int j = i; j < len; j++) {
+ c = s.charAt(j);
+ if (c >= '\"' && c <= '>') {
+ if (c == '<') {
+ if (j > pos) {
+ sb.append(s, pos, j);
+ }
+ sb.append("<");
+ pos = j + 1;
+ } else if (c == '>') {
+ if (j > pos) {
+ sb.append(s, pos, j);
+ }
+ sb.append(">");
+ pos = j + 1;
+ } else if (c == '\'') {
+ if (j > pos) {
+ sb.append(s, pos, j);
+ }
+ sb.append("'"); // '
+ pos = j + 1;
+ } else if (c == '&') {
+ if (j > pos) {
+ sb.append(s, pos, j);
+ }
+ sb.append("&");
+ pos = j + 1;
+ } else if (c == '"') {
+ if (j > pos) {
+ sb.append(s, pos, j);
+ }
+ sb.append("""); // "
+ pos = j + 1;
+ }
+ }
+ }
+ if (pos < len) {
+ sb.append(s, pos, len);
+ }
+ return sb.toString();
+ }
+ }
+ return s;
+ }
+
+ /**
* Proprietary method to evaluate EL expressions. XXX - This method should
* go away once the EL interpreter moves out of JSTL and into its own
* project. For now, this is necessary because the standard machinery is too
Modified: branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Out.java
===================================================================
---
branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Out.java 2012-11-07
22:53:07 UTC (rev 2117)
+++
branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Out.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -18,6 +18,10 @@
package org.apache.jasper.tagplugins.jstl.core;
+import java.io.IOException;
+
+import javax.servlet.jsp.JspWriter;
+
import org.apache.jasper.compiler.tagplugin.TagPlugin;
import org.apache.jasper.compiler.tagplugin.TagPluginContext;
@@ -65,26 +69,26 @@
//if the escapeXml is specified, assign the value to it;
ctxt.generateJavaSource("boolean " + strEscapeXmlName + " =
true;");
if(hasEscapeXml){
- ctxt.generateJavaSource(strEscapeXmlName + " =
Boolean.parseBoolean((");
- ctxt.generateAttribute("default");
- ctxt.generateJavaSource(").toString());");
+ ctxt.generateJavaSource(strEscapeXmlName + " = ");
+ ctxt.generateAttribute("escapeXml");
+ ctxt.generateJavaSource(";");
}
//main part.
- ctxt.generateJavaSource("if(null != " + strValName +"){");
- ctxt.generateJavaSource(" if(" + strEscapeXmlName +
"){");
- ctxt.generateJavaSource(" " + strValName + " =
org.apache.jasper.tagplugins.jstl.Util.escapeXml(" + strValName + ");");
- ctxt.generateJavaSource(" }");
- ctxt.generateJavaSource(" out.write(" + strValName +
");");
- ctxt.generateJavaSource("}else{");
- ctxt.generateJavaSource(" if(null != " + strDefName +
"){");
- ctxt.generateJavaSource(" if(" + strEscapeXmlName +
"){");
- ctxt.generateJavaSource(" " + strDefName + " =
org.apache.jasper.tagplugins.jstl.Util.escapeXml(" + strDefName + ");");
- ctxt.generateJavaSource(" }");
- ctxt.generateJavaSource(" out.write(" + strDefName +
");");
- ctxt.generateJavaSource(" }else{");
- ctxt.generateBody();
- ctxt.generateJavaSource(" }");
- ctxt.generateJavaSource("}");
+ ctxt.generateJavaSource(
+ "org.apache.jasper.tagplugins.jstl.core.Out.output(out, " +
+ strValName + ", " + strDefName + ", " +
strEscapeXmlName +
+ ");");
}
+
+ public static void output(JspWriter out, String value, String defaultValue,
+ boolean escapeXml) throws IOException {
+ String v = value != null ? value : defaultValue;
+ if (v != null) {
+ if(escapeXml){
+ v = org.apache.jasper.tagplugins.jstl.Util.escapeXml(v);
+ }
+ out.write(v);
+ }
+ }
}
Modified: branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Set.java
===================================================================
---
branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Set.java 2012-11-07
22:53:07 UTC (rev 2117)
+++
branches/7.2.x/src/main/java/org/apache/jasper/tagplugins/jstl/core/Set.java 2012-11-09
15:13:33 UTC (rev 2118)
@@ -69,14 +69,20 @@
//if the attribute var has been specified then assign the result to the var;
if(hasVar){
+ String jspCtxt = null;
+ if (ctxt.isTagFile()) {
+ jspCtxt = "this.getJspContext()";
+ } else {
+ jspCtxt = "_jspx_page_context";
+ }
String strVar = ctxt.getConstantAttribute("var");
ctxt.generateJavaSource("if(null != " + resultName +
"){");
- ctxt.generateJavaSource(" pageContext.setAttribute(\"" +
strVar + "\"," + resultName + "," + iScope + ");");
+ ctxt.generateJavaSource(" " + jspCtxt +
".setAttribute(\"" + strVar + "\"," + resultName +
"," + iScope + ");");
ctxt.generateJavaSource("} else {");
if(hasScope){
- ctxt.generateJavaSource("
pageContext.removeAttribute(\"" + strVar + "\"," + iScope +
");");
+ ctxt.generateJavaSource(" " + jspCtxt +
".removeAttribute(\"" + strVar + "\"," + iScope +
");");
}else{
- ctxt.generateJavaSource("
pageContext.removeAttribute(\"" + strVar + "\");");
+ ctxt.generateJavaSource(" " + jspCtxt +
".removeAttribute(\"" + strVar + "\");");
}
ctxt.generateJavaSource("}");
Modified: branches/7.2.x/webapps/docs/changelog.xml
===================================================================
--- branches/7.2.x/webapps/docs/changelog.xml 2012-11-07 22:53:07 UTC (rev 2117)
+++ branches/7.2.x/webapps/docs/changelog.xml 2012-11-09 15:13:33 UTC (rev 2118)
@@ -40,6 +40,12 @@
<fix>
<jira>251</jira>: Drop localization related class preload. (remm)
</fix>
+ <fix>
+ <bug>54012</bug>: Allow tagplugins compatibility with tag files.
(markt)
+ </fix>
+ <fix>
+ Misc minor optimizations. (markt)
+ </fix>
</changelog>
</subsection>
</section>