You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/07/17 01:01:28 UTC
svn commit: r1503937 - in /tomcat/trunk: java/org/apache/el/lang/
java/org/apache/el/parser/ java/org/apache/el/stream/
test/org/apache/el/lang/ webapps/docs/config/
Author: markt
Date: Tue Jul 16 23:01:27 2013
New Revision: 1503937
URL: http://svn.apache.org/r1503937
Log:
Implement non-backwards compatible change to the coercion rules.
Modified:
tomcat/trunk/java/org/apache/el/lang/ELSupport.java
tomcat/trunk/java/org/apache/el/parser/AstAnd.java
tomcat/trunk/java/org/apache/el/parser/AstChoice.java
tomcat/trunk/java/org/apache/el/parser/AstNot.java
tomcat/trunk/java/org/apache/el/parser/AstOr.java
tomcat/trunk/java/org/apache/el/parser/AstValue.java
tomcat/trunk/java/org/apache/el/stream/Stream.java
tomcat/trunk/test/org/apache/el/lang/TestELSupport.java
tomcat/trunk/webapps/docs/config/systemprops.xml
Modified: tomcat/trunk/java/org/apache/el/lang/ELSupport.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/lang/ELSupport.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/lang/ELSupport.java (original)
+++ tomcat/trunk/java/org/apache/el/lang/ELSupport.java Tue Jul 16 23:01:27 2013
@@ -21,6 +21,8 @@ import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@@ -40,6 +42,32 @@ public class ELSupport {
private static final Long ZERO = Long.valueOf(0L);
+ private static final boolean IS_SECURITY_ENABLED =
+ (System.getSecurityManager() != null);
+
+ protected static final boolean COERCE_TO_ZERO;
+
+ static {
+ if (IS_SECURITY_ENABLED) {
+ COERCE_TO_ZERO = AccessController.doPrivileged(
+ new PrivilegedAction<Boolean>(){
+ @Override
+ public Boolean run() {
+ return Boolean.valueOf(System.getProperty(
+ "org.apache.el.parser.COERCE_TO_ZERO",
+ "false"));
+ }
+
+ }
+ ).booleanValue();
+ } else {
+ COERCE_TO_ZERO = Boolean.valueOf(System.getProperty(
+ "org.apache.el.parser.COERCE_TO_ZERO",
+ "false")).booleanValue();
+ }
+ }
+
+
/**
* Compare two objects, after coercing to the same type if appropriate.
*
@@ -147,7 +175,7 @@ public class ELSupport {
Long l1 = (Long) coerceToNumber(obj1, Long.class);
return l0.equals(l1);
} else if (obj0 instanceof Boolean || obj1 instanceof Boolean) {
- return coerceToBoolean(obj0).equals(coerceToBoolean(obj1));
+ return coerceToBoolean(obj0, false).equals(coerceToBoolean(obj1, false));
} else if (obj0.getClass().isEnum()) {
return obj0.equals(coerceToEnum(obj1, obj0.getClass()));
} else if (obj1.getClass().isEnum()) {
@@ -195,8 +223,15 @@ public class ELSupport {
* @return the Boolean value of the object
* @throws ELException if object is not Boolean or String
*/
- public static final Boolean coerceToBoolean(final Object obj)
- throws ELException {
+ public static final Boolean coerceToBoolean(final Object obj,
+ boolean primitive) throws ELException {
+
+ if (!COERCE_TO_ZERO && !primitive) {
+ if (obj == null) {
+ return null;
+ }
+ }
+
if (obj == null || "".equals(obj)) {
return Boolean.FALSE;
}
@@ -211,7 +246,7 @@ public class ELSupport {
obj, obj.getClass(), Boolean.class));
}
- public static final Character coerceToCharacter(final Object obj)
+ private static final Character coerceToCharacter(final Object obj)
throws ELException {
if (obj == null || "".equals(obj)) {
return Character.valueOf((char) 0);
@@ -279,6 +314,13 @@ public class ELSupport {
public static final Number coerceToNumber(final Object obj,
final Class<?> type) throws ELException {
+
+ if (!COERCE_TO_ZERO) {
+ if (obj == null && !type.isPrimitive()) {
+ return null;
+ }
+ }
+
if (obj == null || "".equals(obj)) {
return coerceToNumber(ZERO, type);
}
@@ -388,10 +430,19 @@ public class ELSupport {
public static final Object coerceToType(final Object obj,
final Class<?> type) throws ELException {
+
if (type == null || Object.class.equals(type) ||
(obj != null && type.isAssignableFrom(obj.getClass()))) {
return obj;
}
+
+ if (!COERCE_TO_ZERO) {
+ if (obj == null && !type.isPrimitive() &&
+ !String.class.isAssignableFrom(type)) {
+ return null;
+ }
+ }
+
if (String.class.equals(type)) {
return coerceToString(obj);
}
@@ -402,7 +453,7 @@ public class ELSupport {
return coerceToCharacter(obj);
}
if (Boolean.class.equals(type) || Boolean.TYPE == type) {
- return coerceToBoolean(obj);
+ return coerceToBoolean(obj, Boolean.TYPE == type);
}
if (type.isEnum()) {
return coerceToEnum(obj, type);
Modified: tomcat/trunk/java/org/apache/el/parser/AstAnd.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstAnd.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstAnd.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstAnd.java Tue Jul 16 23:01:27 2013
@@ -36,12 +36,12 @@ public final class AstAnd extends Boolea
public Object getValue(EvaluationContext ctx)
throws ELException {
Object obj = children[0].getValue(ctx);
- Boolean b = coerceToBoolean(obj);
+ Boolean b = coerceToBoolean(obj, true);
if (!b.booleanValue()) {
return b;
}
obj = children[1].getValue(ctx);
- b = coerceToBoolean(obj);
+ b = coerceToBoolean(obj, true);
return b;
}
}
Modified: tomcat/trunk/java/org/apache/el/parser/AstChoice.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstChoice.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstChoice.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstChoice.java Tue Jul 16 23:01:27 2013
@@ -43,7 +43,7 @@ public final class AstChoice extends Sim
public Object getValue(EvaluationContext ctx)
throws ELException {
Object obj0 = this.children[0].getValue(ctx);
- Boolean b0 = coerceToBoolean(obj0);
+ Boolean b0 = coerceToBoolean(obj0, true);
return this.children[((b0.booleanValue() ? 1 : 2))].getValue(ctx);
}
}
Modified: tomcat/trunk/java/org/apache/el/parser/AstNot.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstNot.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstNot.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstNot.java Tue Jul 16 23:01:27 2013
@@ -42,7 +42,7 @@ public final class AstNot extends Simple
public Object getValue(EvaluationContext ctx)
throws ELException {
Object obj = this.children[0].getValue(ctx);
- Boolean b = coerceToBoolean(obj);
+ Boolean b = coerceToBoolean(obj, true);
return Boolean.valueOf(!b.booleanValue());
}
}
Modified: tomcat/trunk/java/org/apache/el/parser/AstOr.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstOr.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstOr.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstOr.java Tue Jul 16 23:01:27 2013
@@ -36,12 +36,12 @@ public final class AstOr extends Boolean
public Object getValue(EvaluationContext ctx)
throws ELException {
Object obj = this.children[0].getValue(ctx);
- Boolean b = coerceToBoolean(obj);
+ Boolean b = coerceToBoolean(obj, true);
if (b.booleanValue()) {
return b;
}
obj = this.children[1].getValue(ctx);
- b = coerceToBoolean(obj);
+ b = coerceToBoolean(obj, true);
return b;
}
}
Modified: tomcat/trunk/java/org/apache/el/parser/AstValue.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstValue.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstValue.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstValue.java Tue Jul 16 23:01:27 2013
@@ -21,8 +21,6 @@ package org.apache.el.parser;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import javax.el.ELException;
import javax.el.ELResolver;
@@ -42,31 +40,6 @@ import org.apache.el.util.ReflectionUtil
*/
public final class AstValue extends SimpleNode {
- private static final boolean IS_SECURITY_ENABLED =
- (System.getSecurityManager() != null);
-
- protected static final boolean COERCE_TO_ZERO;
-
- static {
- if (IS_SECURITY_ENABLED) {
- COERCE_TO_ZERO = AccessController.doPrivileged(
- new PrivilegedAction<Boolean>(){
- @Override
- public Boolean run() {
- return Boolean.valueOf(System.getProperty(
- "org.apache.el.parser.COERCE_TO_ZERO",
- "true"));
- }
-
- }
- ).booleanValue();
- } else {
- COERCE_TO_ZERO = Boolean.valueOf(System.getProperty(
- "org.apache.el.parser.COERCE_TO_ZERO",
- "true")).booleanValue();
- }
- }
-
protected static class Target {
protected Object base;
@@ -213,8 +186,7 @@ public final class AstValue extends Simp
// coerce to the expected type
Class<?> targetClass = resolver.getType(ctx, t.base, t.property);
- if (COERCE_TO_ZERO == true
- || !isAssignable(value, targetClass)) {
+ if (!isAssignable(value, targetClass)) {
resolver.setValue(ctx, t.base, t.property,
ELSupport.coerceToType(value, targetClass));
} else {
Modified: tomcat/trunk/java/org/apache/el/stream/Stream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/stream/Stream.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/stream/Stream.java (original)
+++ tomcat/trunk/java/org/apache/el/stream/Stream.java Tue Jul 16 23:01:27 2013
@@ -47,8 +47,8 @@ public class Stream {
protected void findNext() {
while (iterator.hasNext()) {
Object obj = iterator.next();
- Boolean filter = ELSupport.coerceToBoolean(le.invoke(obj));
- if (filter != null && filter.booleanValue()) {
+ if (ELSupport.coerceToBoolean(le.invoke(obj),
+ true).booleanValue()) {
next = obj;
foundNext = true;
break;
Modified: tomcat/trunk/test/org/apache/el/lang/TestELSupport.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/lang/TestELSupport.java?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/el/lang/TestELSupport.java (original)
+++ tomcat/trunk/test/org/apache/el/lang/TestELSupport.java Tue Jul 16 23:01:27 2013
@@ -20,11 +20,13 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import javax.el.ELException;
+import javax.el.ELManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import org.junit.Assert;
import org.junit.Test;
public class TestELSupport {
@@ -85,7 +87,7 @@ public class TestELSupport {
@Test
public void testCoerceNullToNumber() {
Object output = ELSupport.coerceToType(null, Number.class);
- assertEquals(Long.valueOf(0), output);
+ assertNull(output);
}
@Test
@@ -120,6 +122,116 @@ public class TestELSupport {
assertNull(output);
}
+ @Test
+ public void testCoerceToType01() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, Integer.class);
+ Assert.assertNull("Result: " + result, result);
+ }
+
+ @Test
+ public void testCoerceToType02() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, int.class);
+ Assert.assertEquals(Integer.valueOf(0), result);
+ }
+
+ @Test
+ public void testCoerceToType03() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, boolean.class);
+ Assert.assertEquals(Boolean.valueOf(null), result);
+ }
+
+ @Test
+ public void testCoerceToType04() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, String.class);
+ Assert.assertEquals("", result);
+ }
+
+ @Test
+ public void testCoerceToType05() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, Character.class);
+ Assert.assertNull("Result: " + result, result);
+ }
+
+ @Test
+ public void testCoerceToType06() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ "", Character.class);
+ Assert.assertEquals(Character.valueOf((char) 0), result);
+ }
+
+ @Test
+ public void testCoerceToType07() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, char.class);
+ Assert.assertEquals(Character.valueOf((char) 0), result);
+ }
+
+ @Test
+ public void testCoerceToType08() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ "", char.class);
+ Assert.assertEquals(Character.valueOf((char) 0), result);
+ }
+
+ @Test
+ public void testCoerceToType09() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, Boolean.class);
+ Assert.assertNull("Result: " + result, result);
+ }
+
+ @Test
+ public void testCoerceToType10() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ "", Boolean.class);
+ Assert.assertEquals(Boolean.FALSE, result);
+ }
+
+ @Test
+ public void testCoerceToType11() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ null, boolean.class);
+ Assert.assertEquals(Boolean.FALSE, result);
+ }
+
+ @Test
+ public void testCoerceToType12() {
+ Object result = ELManager.getExpressionFactory().coerceToType(
+ "", boolean.class);
+ Assert.assertEquals(Boolean.FALSE, result);
+ }
+
+ @Test
+ public void testCoerceToNumber01() {
+ Object result = ELSupport.coerceToNumber(
+ (Object) null, Integer.class);
+ Assert.assertNull("Resut: " + result, result);
+ }
+
+ @Test
+ public void testCoerceToNumber02() {
+ Object result = ELSupport.coerceToNumber(
+ (Object) null, int.class);
+ Assert.assertEquals(Integer.valueOf(0), result);
+ }
+
+ @Test
+ public void testCoerceToBoolean01() {
+ Object result = ELSupport.coerceToBoolean(null, true);
+ Assert.assertEquals(Boolean.FALSE, result);
+ }
+
+ @Test
+ public void testCoerceToBoolean02() {
+ Object result = ELSupport.coerceToBoolean(null, false);
+ Assert.assertNull("Resut: " + result, result);
+ }
+
private static void testIsSame(Object value) {
assertEquals(value, ELSupport.coerceToNumber(value, value.getClass()));
}
Modified: tomcat/trunk/webapps/docs/config/systemprops.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/systemprops.xml?rev=1503937&r1=1503936&r2=1503937&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/systemprops.xml (original)
+++ tomcat/trunk/webapps/docs/config/systemprops.xml Tue Jul 16 23:01:27 2013
@@ -79,10 +79,14 @@
</property>
<property name="org.apache.el.parser. COERCE_TO_ZERO">
- <p>If <code>true</code>, when coercing expressions to numbers
- <code>""</code> and <code>null</code> will be coerced to zero as required
- by the specification.</p>
- <p>If not specified, the default value of <code>true</code> will be used.</p>
+ <p>If <code>true</code>, when coercing <code>null</code>s to objects of
+ type Number, Character or Boolean the result will be <code>0</code> for
+ Number and Character types and <code>false</code> for Boolean as required
+ by the EL 2.2 and earlier specifications. If this property is
+ <code>false</code> the result of the coercion will be <code>null</code> as
+ required by the EL 3.0 specification.</p>
+ <p>If not specified, the default value of <code>false</code> will be
+ used.</p>
</property>
<property name="org.apache.el.parser. SKIP_IDENTIFIER_CHECK">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org