luehe 2003/01/06 10:57:16 Modified: jasper2/src/share/org/apache/jasper/compiler Generator.java JspUtil.java Node.java Validator.java jasper2/src/share/org/apache/jasper/runtime JspRuntimeLibrary.java Log: Implemented JSTL EL rules for coercing of empty string and null values Revision Changes Path 1.144 +32 -90 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java Index: Generator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v retrieving revision 1.143 retrieving revision 1.144 diff -u -r1.143 -r1.144 --- Generator.java 16 Dec 2002 23:37:59 -0000 1.143 +++ Generator.java 6 Jan 2003 18:57:14 -0000 1.144 @@ -2511,7 +2511,19 @@ } } - private String convertString(Class c, String s, String attrName, + /* + * @param c The target class to which to coerce the given string + * @param s The string value + * @param attrName The name of the attribute whose value is being + * supplied + * @param propEditorClass The property editor for the given attribute + * @param isNamedAttribute true if the given attribute is a named + * attribute (that is, specified using the jsp:attribute standard + * action), and false otherwise + */ + private String convertString(Class c, + String s, + String attrName, Class propEditorClass, boolean isNamedAttribute) throws JasperException { @@ -2530,107 +2542,37 @@ } else if (c == String.class) { return quoted; } else if (c == boolean.class) { - if (isNamedAttribute) - return "Boolean.valueOf(" + s + ").booleanValue()"; - else - return Boolean.valueOf(s).toString(); + return JspUtil.coerceToPrimitiveBoolean(s, isNamedAttribute); } else if (c == Boolean.class) { - if (isNamedAttribute) - return "new Boolean(" + s + ")"; - else - // Detect format error at translation time - return "new Boolean(" + Boolean.valueOf(s).toString() + ")"; + return JspUtil.coerceToBoolean(s, isNamedAttribute); } else if (c == byte.class) { - return "((byte)" + Byte.valueOf(s).toString() + ")"; + return JspUtil.coerceToPrimitiveByte(s, isNamedAttribute); } else if (c == Byte.class) { - if (isNamedAttribute) - return "new Byte(" + s + ")"; - else - // Detect format error at translation time - return "new Byte((byte)" + Byte.valueOf(s).toString() + ")"; + return JspUtil.coerceToByte(s, isNamedAttribute); } else if (c == char.class) { - if (isNamedAttribute) { - return "org.apache.jasper.runtime.JspRuntimeLibrary.getChar(" + s + ")"; - } else { - // non-normative (normative method would fail to compile) - if (s.length() > 0) { - char ch = s.charAt(0); - // this trick avoids escaping issues - return "((char) " + (int) ch + ")"; - } else { - throw new NumberFormatException( - err.getString("jsp.error.bad_string_char")); - } - } + return JspUtil.coerceToChar(s, isNamedAttribute); } else if (c == Character.class) { - if (isNamedAttribute) { - return "org.apache.jasper.runtime.JspRuntimeLibrary.getCharacter(" + s + ")"; - } else { - // non-normative (normative method would fail to compile) - if (s.length() > 0) { - char ch = s.charAt(0); - // this trick avoids escaping issues - return "new Character((char) " + (int) ch + ")"; - } else { - throw new NumberFormatException( - err.getString("jsp.error.bad_string_Character")); - } - } + return JspUtil.coerceToCharacter(s, isNamedAttribute); } else if (c == double.class) { - if (isNamedAttribute) - return "Double.valueOf(" + s + ").doubleValue()"; - else - return Double.valueOf(s).toString(); + return JspUtil.coerceToPrimitiveDouble(s, isNamedAttribute); } else if (c == Double.class) { - if (isNamedAttribute) - return "new Double(" + s + ")"; - else - // Detect format error at translation time - return "new Double(" + Double.valueOf(s).toString() + ")"; + return JspUtil.coerceToDouble(s, isNamedAttribute); } else if (c == float.class) { - if (isNamedAttribute) - return "Float.valueOf(" + s + ").floatValue()"; - else - return Float.valueOf(s).toString() + "f"; + return JspUtil.coerceToPrimitiveFloat(s, isNamedAttribute); } else if (c == Float.class) { - if (isNamedAttribute) - return "new Float(" + s + ")"; - else - // Detect format error at translation time - return "new Float(" + Float.valueOf(s).toString() + "f)"; + return JspUtil.coerceToFloat(s, isNamedAttribute); } else if (c == int.class) { - if (isNamedAttribute) - return "Integer.valueOf(" + s + ").intValue()"; - else - return Integer.valueOf(s).toString(); + return JspUtil.coerceToInt(s, isNamedAttribute); } else if (c == Integer.class) { - if (isNamedAttribute) - return "new Integer(" + s + ")"; - else - // Detect format error at translation time - return "new Integer(" + Integer.valueOf(s).toString() + ")"; + return JspUtil.coerceToInteger(s, isNamedAttribute); } else if (c == short.class) { - if (isNamedAttribute) - return "Short.valueOf(" + s + ").shortValue()"; - else - return "((short) " + Short.valueOf(s).toString() + ")"; + return JspUtil.coerceToPrimitiveShort(s, isNamedAttribute); } else if (c == Short.class) { - if (isNamedAttribute) - return "new Short(" + s + ")"; - else - // Detect format error at translation time - return "new Short(\"" + Short.valueOf(s).toString() + "\")"; + return JspUtil.coerceToShort(s, isNamedAttribute); } else if (c == long.class) { - if (isNamedAttribute) - return "Long.valueOf(" + s + ").longValue()"; - else - return Long.valueOf(s).toString() + "l"; + return JspUtil.coerceToPrimitiveLong(s, isNamedAttribute); } else if (c == Long.class) { - if (isNamedAttribute) - return "new Long(" + s + ")"; - else - // Detect format error at translation time - return "new Long(" + Long.valueOf(s).toString() + "l)"; + return JspUtil.coerceToLong(s, isNamedAttribute); } else if (c == Object.class) { return "new String(" + quoted + ")"; } else { 1.27 +205 -3 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspUtil.java Index: JspUtil.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspUtil.java,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- JspUtil.java 5 Dec 2002 02:41:53 -0000 1.26 +++ JspUtil.java 6 Jan 2003 18:57:15 -0000 1.27 @@ -728,6 +728,208 @@ } } + public static String coerceToPrimitiveBoolean(String s, + boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToBoolean(" + s + ")"; + } else { + if (s == null || s.length() == 0) + return "false"; + else + return Boolean.valueOf(s).toString(); + } + } + + public static String coerceToBoolean(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Boolean) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Boolean.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Boolean(false)"; + } else { + // Detect format error at translation time + return "new Boolean(" + Boolean.valueOf(s).toString() + ")"; + } + } + } + + public static String coerceToPrimitiveByte(String s, + boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToByte(" + s + ")"; + } else { + if (s == null || s.length() == 0) + return "(byte) 0"; + else + return "((byte)" + Byte.valueOf(s).toString() + ")"; + } + } + + public static String coerceToByte(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Byte) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Byte.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Byte((byte) 0)"; + } else { + // Detect format error at translation time + return "new Byte((byte)" + Byte.valueOf(s).toString() + ")"; + } + } + } + + public static String coerceToChar(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToChar(" + s + ")"; + } else { + if (s == null || s.length() == 0) { + return "(char) 0"; + } else { + char ch = s.charAt(0); + // this trick avoids escaping issues + return "((char) " + (int) ch + ")"; + } + } + } + + public static String coerceToCharacter(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Character) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Character.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Character((char) 0)"; + } else { + char ch = s.charAt(0); + // this trick avoids escaping issues + return "new Character((char) " + (int) ch + ")"; + } + } + } + + public static String coerceToPrimitiveDouble(String s, + boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToDouble(" + s + ")"; + } else { + if (s == null || s.length() == 0) + return "(double) 0"; + else + return Double.valueOf(s).toString(); + } + } + + public static String coerceToDouble(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Double) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Double.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Double(0)"; + } else { + // Detect format error at translation time + return "new Double(" + Double.valueOf(s).toString() + ")"; + } + } + } + + public static String coerceToPrimitiveFloat(String s, + boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToFloat(" + s + ")"; + } else { + if (s == null || s.length() == 0) + return "(float) 0"; + else + return Float.valueOf(s).toString() + "f"; + } + } + + public static String coerceToFloat(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Float) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Float.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Float(0)"; + } else { + // Detect format error at translation time + return "new Float(" + Float.valueOf(s).toString() + "f)"; + } + } + } + + public static String coerceToInt(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToInt(" + s + ")"; + } else { + if (s == null || s.length() == 0) + return "0"; + else + return Integer.valueOf(s).toString(); + } + } + + public static String coerceToInteger(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Integer) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Integer.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Integer(0)"; + } else { + // Detect format error at translation time + return "new Integer(" + Integer.valueOf(s).toString() + ")"; + } + } + } + + public static String coerceToPrimitiveShort(String s, + boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToShort(" + s + ")"; + } else { + if (s == null || s.length() == 0) + return "(short) 0"; + else + return "((short) " + Short.valueOf(s).toString() + ")"; + } + } + + public static String coerceToShort(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Short) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Short.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Short((short) 0)"; + } else { + // Detect format error at translation time + return "new Short(\"" + Short.valueOf(s).toString() + "\")"; + } + } + } + + public static String coerceToPrimitiveLong(String s, + boolean isNamedAttribute) { + if (isNamedAttribute) { + return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToLong(" + s + ")"; + } else { + if (s == null || s.length() == 0) + return "(long) 0"; + else + return Long.valueOf(s).toString() + "l"; + } + } + + public static String coerceToLong(String s, boolean isNamedAttribute) { + if (isNamedAttribute) { + return "(Long) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Long.class)"; + } else { + if (s == null || s.length() == 0) { + return "new Long(0)"; + } else { + // Detect format error at translation time + return "new Long(" + Long.valueOf(s).toString() + "l)"; + } + } + } + public static InputStream getInputStream(String fname, JarFile jarFile, JspCompilationContext ctxt, ErrorDispatcher err) 1.50 +8 -5 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java Index: Node.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java,v retrieving revision 1.49 retrieving revision 1.50 diff -u -r1.49 -r1.50 --- Node.java 16 Dec 2002 16:13:28 -0000 1.49 +++ Node.java 6 Jan 2003 18:57:15 -0000 1.50 @@ -1363,8 +1363,11 @@ // Get the attribute value from this named attribute // (<jsp:attribute>). // Since this method is only for attributes that are not rtexpr, - // we can assume the body of the jsp:attribute is a template text - String text = null; + // we can assume the body of the jsp:attribute is a template text. + // According to JSP 2.0, if the body of the <jsp:attribute> + // action is empty, it is equivalent of specifying "" as the value + // of the attribute. + String text = ""; if (getBody() != null) { AttributeVisitor attributeVisitor = new AttributeVisitor(); try { 1.64 +10 -9 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java Index: Validator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java,v retrieving revision 1.63 retrieving revision 1.64 diff -u -r1.63 -r1.64 --- Validator.java 18 Dec 2002 17:37:50 -0000 1.63 +++ Validator.java 6 Jan 2003 18:57:15 -0000 1.64 @@ -820,15 +820,16 @@ if (na.getName().equals(tldAttrs[j].getName())) { jspAttrs[attrs.getLength() + i] = new Node.JspAttribute(na, false); - - NamedAttributeVisitor nav = new NamedAttributeVisitor(); - na.getBody().visit(nav); - if (nav.hasDynamicContent()) { + NamedAttributeVisitor nav = null; + if (na.getBody() != null) { + nav = new NamedAttributeVisitor(); + na.getBody().visit(nav); + } + if (nav != null && nav.hasDynamicContent()) { tagDataAttrs.put(na.getName(), TagData.REQUEST_TIME_VALUE); } else { - tagDataAttrs.put(na.getName(), - na.getText()); + tagDataAttrs.put(na.getName(), na.getText()); } found = true; break; 1.13 +104 -11 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/runtime/JspRuntimeLibrary.java Index: JspRuntimeLibrary.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/runtime/JspRuntimeLibrary.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- JspRuntimeLibrary.java 12 Dec 2002 23:31:51 -0000 1.12 +++ JspRuntimeLibrary.java 6 Jan 2003 18:57:15 -0000 1.13 @@ -135,18 +135,111 @@ } } - public static Character getCharacter(String s) throws JasperException { - if (s.length() == 0) { - err.jspError("jsp.error.bad_string_Character"); + public static boolean coerceToBoolean(String s) { + if (s == null || s.length() == 0) + return false; + else + return Boolean.valueOf(s).booleanValue(); + } + + public static byte coerceToByte(String s) { + if (s == null || s.length() == 0) + return (byte) 0; + else + return Byte.valueOf(s).byteValue(); + } + + public static char coerceToChar(String s) { + if (s == null || s.length() == 0) { + return (char) 0; + } else { + // this trick avoids escaping issues + return (char)(int) s.charAt(0); } - return new Character(s.charAt(0)); } - public static char getChar(String s) throws JasperException { - if (s.length() == 0) { - err.jspError("jsp.error.bad_string_Character"); + public static double coerceToDouble(String s) { + if (s == null || s.length() == 0) + return (double) 0; + else + return Double.valueOf(s).doubleValue(); + } + + public static float coerceToFloat(String s) { + if (s == null || s.length() == 0) + return (float) 0; + else + return Float.valueOf(s).floatValue(); + } + + public static int coerceToInt(String s) { + if (s == null || s.length() == 0) + return 0; + else + return Integer.valueOf(s).intValue(); + } + + public static short coerceToShort(String s) { + if (s == null || s.length() == 0) + return (short) 0; + else + return Short.valueOf(s).shortValue(); + } + + public static long coerceToLong(String s) { + if (s == null || s.length() == 0) + return (long) 0; + else + return Long.valueOf(s).longValue(); + } + + public static Object coerce(String s, Class target) { + + boolean isNullOrEmpty = (s == null || s.length() == 0); + + if (target == Boolean.class) { + if (isNullOrEmpty) { + s = "false"; + } + return new Boolean(s); + } else if (target == Byte.class) { + if (isNullOrEmpty) + return new Byte((byte) 0); + else + return new Byte(s); + } else if (target == Character.class) { + if (isNullOrEmpty) + return new Character((char) 0); + else + return new Character(s.charAt(0)); + } else if (target == Double.class) { + if (isNullOrEmpty) + return new Double(0); + else + return new Double(s); + } else if (target == Float.class) { + if (isNullOrEmpty) + return new Float(0); + else + return new Float(s); + } else if (target == Integer.class) { + if (isNullOrEmpty) + return new Integer(0); + else + return new Integer(s); + } else if (target == Short.class) { + if (isNullOrEmpty) + return new Short((short) 0); + else + return new Short(s); + } else if (target == Long.class) { + if (isNullOrEmpty) + return new Long(0); + else + return new Long(s); + } else { + return null; } - return s.charAt(0); } // __begin convertMethod
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>