Author: remy.maucherat(a)jboss.com
Date: 2012-04-18 04:24:35 -0400 (Wed, 18 Apr 2012)
New Revision: 2027
Modified:
branches/7.0.x/java/org/apache/el/parser/AstValue.java
branches/7.0.x/java/org/apache/el/util/ReflectionUtil.java
branches/7.0.x/java/org/apache/jasper/compiler/Generator.java
branches/7.0.x/java/org/apache/jasper/compiler/Validator.java
branches/7.0.x/java/org/apache/jasper/runtime/JspApplicationContextImpl.java
branches/7.0.x/webapps/docs/changelog.xml
Log:
- Port 3 Jasper patches.
- 52776: Fix cleanup after JspFragment.invoke. Sumitted by Karl von Randow.
- 52970: Fix enum as method invocation argument in EL.
- Use per webapp expression factory.
Modified: branches/7.0.x/java/org/apache/el/parser/AstValue.java
===================================================================
--- branches/7.0.x/java/org/apache/el/parser/AstValue.java 2012-04-16 12:46:31 UTC (rev
2026)
+++ branches/7.0.x/java/org/apache/el/parser/AstValue.java 2012-04-18 08:24:35 UTC (rev
2027)
@@ -230,7 +230,8 @@
@SuppressWarnings("rawtypes") Class[] paramTypes)
throws ELException {
Target t = getTarget(ctx);
- Method m = ReflectionUtil.getMethod(t.base, t.property, paramTypes);
+ Method m = ReflectionUtil.getMethod(
+ t.base, t.property, paramTypes, null);
return new MethodInfo(m.getName(), m.getReturnType(), m
.getParameterTypes());
}
@@ -244,19 +245,20 @@
Target t = getTarget(ctx);
Method m = null;
Object[] values = null;
+ Class<?>[] types = null;
if (isParametersProvided()) {
values = ((AstMethodParameters) this.jjtGetChild(
this.jjtGetNumChildren() - 1)).getParameters(ctx);
- Class<?>[] types = getTypesFromValues(values);
- m = ReflectionUtil.getMethod(t.base, t.property, types);
+ types = getTypesFromValues(values);
} else {
- m = ReflectionUtil.getMethod(t.base, t.property, paramTypes);
values = paramValues;
+ types = paramTypes;
}
- if (m.isVarArgs()) {
- // May need to convert values
- values = toVarArgs(values, m);
- }
+ m = ReflectionUtil.getMethod(t.base, t.property, types, values);
+
+ // Handle varArgs and any co-ercion required
+ values = convertArgs(values, m);
+
Object result = null;
try {
result = m.invoke(t.base, values);
@@ -277,17 +279,34 @@
return result;
}
- private Object[] toVarArgs(Object[] src, Method m) {
- int paramCount = m.getParameterTypes().length;
+ private Object[] convertArgs(Object[] src, Method m) {
+ Class<?>[] types = m.getParameterTypes();
+ if (types.length == 0) {
+ return new Object[0];
+ }
+ int paramCount = types.length;
+
Object[] dest = new Object[paramCount];
- Object[] varArgs = (Object[]) Array.newInstance(
- m.getParameterTypes()[paramCount - 1].getComponentType(),
- src.length - (paramCount - 1));
- System.arraycopy(src, 0, dest, 0, paramCount - 1);
- System.arraycopy(src, paramCount - 1, varArgs, 0,
- src.length - (paramCount - 1));
- dest[paramCount - 1] = varArgs;
+
+ for (int i = 0; i < paramCount - 1; i++) {
+ dest[i] = ELSupport.coerceToType(src[i], types[i]);
+ }
+
+ if (m.isVarArgs()) {
+ Object[] varArgs = (Object[]) Array.newInstance(
+ m.getParameterTypes()[paramCount - 1].getComponentType(),
+ src.length - (paramCount - 1));
+ for (int i = 0; i < src.length - (paramCount - 1); i ++) {
+ varArgs[i] = ELSupport.coerceToType(src[paramCount - 1 + i],
+ types[paramCount - 1].getComponentType());
+ }
+ dest[paramCount - 1] = varArgs;
+ } else {
+ dest[paramCount - 1] = ELSupport.coerceToType(
+ src[paramCount - 1], types[paramCount - 1]);
+ }
+
return dest;
}
Modified: branches/7.0.x/java/org/apache/el/util/ReflectionUtil.java
===================================================================
--- branches/7.0.x/java/org/apache/el/util/ReflectionUtil.java 2012-04-16 12:46:31 UTC
(rev 2026)
+++ branches/7.0.x/java/org/apache/el/util/ReflectionUtil.java 2012-04-18 08:24:35 UTC
(rev 2027)
@@ -23,9 +23,12 @@
import java.util.Map;
import java.util.Set;
+import javax.el.ELException;
import javax.el.MethodNotFoundException;
+import org.apache.el.lang.ELSupport;
+
/**
* Utilities for Managing Serialization and Reflection
*
@@ -106,12 +109,14 @@
* @param base the object that owns the method
* @param property the name of the method
* @param paramTypes the parameter types to use
+ * @param paramValues the parameter values
* @return the method specified
* @throws MethodNotFoundException
*/
@SuppressWarnings("null")
public static Method getMethod(Object base, Object property,
- Class<?>[] paramTypes) throws MethodNotFoundException {
+ Class<?>[] paramTypes, Object[] paramValues)
+ throws MethodNotFoundException {
if (base == null || property == null) {
throw new MethodNotFoundException(MessageFactory.get(
"error.method.notfound", base, property,
@@ -156,21 +161,37 @@
int exactMatch = 0;
boolean noMatch = false;
for (int i = 0; i < mParamCount; i++) {
- if (paramTypes[i] == null || mParamTypes[i].equals(paramTypes[i])) {
+ // Can't be null
+ if (mParamTypes[i].equals(paramTypes[i])) {
exactMatch++;
} else if (i == (mParamCount - 1) && m.isVarArgs()) {
Class<?> varType = mParamTypes[i].getComponentType();
for (int j = i; j < paramCount; j++) {
if (!isAssignableFrom(paramTypes[j], varType)) {
- break;
+ if (paramValues == null) {
+ noMatch = true;
+ break;
+ } else {
+ if (!isCoercibleFrom(paramValues[j], varType)) {
+ noMatch = true;
+ break;
+ }
+ }
}
// Don't treat a varArgs match as an exact match, it can
// lead to a varArgs method matching when the result
// should be ambiguous
}
} else if (!isAssignableFrom(paramTypes[i], mParamTypes[i])) {
- noMatch = true;
- break;
+ if (paramValues == null) {
+ noMatch = true;
+ break;
+ } else {
+ if (!isCoercibleFrom(paramValues[i], mParamTypes[i])) {
+ noMatch = true;
+ break;
+ }
+ }
}
}
if (noMatch) {
@@ -298,6 +319,17 @@
return targetClass.isAssignableFrom(src);
}
+ private static boolean isCoercibleFrom(Object src, Class<?> target) {
+ // TODO: This isn't pretty but it works. Significant refactoring would
+ // be required to avoid the exception.
+ try {
+ ELSupport.coerceToType(src, target);
+ } catch (ELException e) {
+ return false;
+ }
+ return true;
+ }
+
protected static final String paramString(Class<?>[] types) {
if (types != null) {
StringBuilder sb = new StringBuilder();
Modified: branches/7.0.x/java/org/apache/jasper/compiler/Generator.java
===================================================================
--- branches/7.0.x/java/org/apache/jasper/compiler/Generator.java 2012-04-16 12:46:31 UTC
(rev 2026)
+++ branches/7.0.x/java/org/apache/jasper/compiler/Generator.java 2012-04-18 08:24:35 UTC
(rev 2027)
@@ -2098,9 +2098,6 @@
out.println(");");
}
- // Restore EL context
-
out.printil("jspContext.getELContext().putContext(JspContext.class,getJspContext());");
-
n.setEndJavaLine(out.getJavaLine());
}
@@ -4186,6 +4183,7 @@
out.printil("}");
out.printil("try {");
out.pushIndent();
+ out.printil("Object _jspx_saved_JspContext =
this.jspContext.getELContext().getContext(javax.servlet.jsp.JspContext.class);");
out.printil("this.jspContext.getELContext().putContext(JspContext.class,this.jspContext);");
out.printil("switch( this.discriminator ) {");
out.pushIndent();
@@ -4198,6 +4196,10 @@
}
out.popIndent();
out.printil("}"); // switch
+
+ // restore nested JspContext on ELContext
+
out.printil("jspContext.getELContext().putContext(javax.servlet.jsp.JspContext.class,_jspx_saved_JspContext);");
+
out.popIndent();
out.printil("}"); // try
out.printil("catch( Throwable e ) {");
Modified: branches/7.0.x/java/org/apache/jasper/compiler/Validator.java
===================================================================
--- branches/7.0.x/java/org/apache/jasper/compiler/Validator.java 2012-04-16 12:46:31 UTC
(rev 2026)
+++ branches/7.0.x/java/org/apache/jasper/compiler/Validator.java 2012-04-18 08:24:35 UTC
(rev 2027)
@@ -27,6 +27,7 @@
import javax.el.ELException;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
+import javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.tagext.FunctionInfo;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.PageData;
@@ -37,7 +38,6 @@
import javax.servlet.jsp.tagext.TagLibraryInfo;
import javax.servlet.jsp.tagext.ValidationMessage;
-import org.apache.el.lang.ELSupport;
import org.apache.jasper.JasperException;
import org.apache.jasper.el.ELContextImpl;
import org.xml.sax.Attributes;
@@ -497,8 +497,7 @@
new JspUtil.ValidAttribute("doctype-public"),
new JspUtil.ValidAttribute("doctype-system") };
- private static final ExpressionFactory EXPRESSION_FACTORY =
- ExpressionFactory.newInstance();
+ private final ExpressionFactory expressionFactory;
/*
* Constructor
@@ -507,6 +506,11 @@
this.pageInfo = compiler.getPageInfo();
this.err = compiler.getErrorDispatcher();
this.loader = compiler.getCompilationContext().getClassLoader();
+ // Get the cached EL expression factory for this context
+ expressionFactory =
+ JspFactory.getDefaultFactory().getJspApplicationContext(
+ compiler.getCompilationContext().getServletContext()).
+ getExpressionFactory();
}
public void visit(Node.JspRoot n) throws JasperException {
@@ -1166,7 +1170,7 @@
Boolean.TYPE == expectedClass ||
expectedClass.isEnum()) {
try {
-
EXPRESSION_FACTORY.coerceToType(attrs.getValue(i), expectedClass);
+
expressionFactory.coerceToType(attrs.getValue(i), expectedClass);
} catch (Exception e) {
err.jspError
(n,
"jsp.error.coerce_to_type",
Modified: branches/7.0.x/java/org/apache/jasper/runtime/JspApplicationContextImpl.java
===================================================================
---
branches/7.0.x/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 2012-04-16
12:46:31 UTC (rev 2026)
+++
branches/7.0.x/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 2012-04-18
08:24:35 UTC (rev 2027)
@@ -50,8 +50,7 @@
private final static String KEY = JspApplicationContextImpl.class.getName();
- private final static ExpressionFactory expressionFactory =
- ExpressionFactory.newInstance();
+ private final ExpressionFactory expressionFactory = ExpressionFactory.newInstance();
private final List<ELContextListener> contextListeners = new
ArrayList<ELContextListener>();
Modified: branches/7.0.x/webapps/docs/changelog.xml
===================================================================
--- branches/7.0.x/webapps/docs/changelog.xml 2012-04-16 12:46:31 UTC (rev 2026)
+++ branches/7.0.x/webapps/docs/changelog.xml 2012-04-18 08:24:35 UTC (rev 2027)
@@ -15,6 +15,22 @@
</properties>
<body>
+<section name="JBoss Web 7.0.16.Final (remm)">
+ <subsection name="Jasper">
+ <changelog>
+ <fix>
+ <bug>52776</bug>: Fix cleanup after JspFragment.invoke. Sumitted by
Karl von Randow. (markt)
+ </fix>
+ <fix>
+ <bug>52970</bug>: Fix enum as method invocation argument in EL.
(markt)
+ </fix>
+ <fix>
+ Use per webapp expression factory. (markt)
+ </fix>
+ </changelog>
+ </subsection>
+</section>
+
<section name="JBoss Web 7.0.15.Final (remm)">
<subsection name="Catalina">
<changelog>