com.caucho.el.Expr Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resin Show documentation
Show all versions of resin Show documentation
Resin Java Application Server
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.el;
import com.caucho.config.types.Period;
import com.caucho.util.BeanUtil;
import com.caucho.util.IntMap;
import com.caucho.util.L10N;
import com.caucho.vfs.ReadStream;
import com.caucho.vfs.WriteStream;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.MethodInfo;
import javax.el.PropertyNotFoundException;
import javax.el.PropertyNotWritableException;
import javax.el.ValueExpression;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspException;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Abstract implementation class for an expression.
*/
public abstract class Expr extends ValueExpression {
protected static final Logger log
= Logger.getLogger(Expr.class.getName());
protected static final L10N L = new L10N(Expr.class);
private static final BigDecimal BIG_DECIMAL_ZERO = new BigDecimal("0");
private static final BigInteger BIG_INTEGER_ZERO = new BigInteger("0");
private static final HashMap,CoerceType> _coerceMap
= new HashMap,CoerceType>();
// lexeme codes
final static int ADD = 1;
final static int SUB = ADD + 1;
final static int MUL = SUB + 1;
final static int DIV = MUL + 1;
final static int MOD = DIV + 1;
final static int EQ = MOD + 1;
final static int NE = EQ + 1;
final static int LT = NE + 1;
final static int LE = LT + 1;
final static int GT = LE + 1;
final static int GE = GT + 1;
final static int AND = GE + 1;
final static int OR = AND + 1;
final static int NOT = OR + 1;
final static int MINUS = NOT + 1;
final static int EMPTY = MINUS + 1;
final static int COND_BINARY = EMPTY + 1;
final static int OBJECT = 0;
final static int BOOLEAN = OBJECT + 1;
final static int BYTE = BOOLEAN + 1;
final static int SHORT = BYTE + 1;
final static int INT = SHORT + 1;
final static int LONG = INT + 1;
final static int FLOAT = LONG + 1;
final static int DOUBLE = FLOAT + 1;
final static int BOOLEAN_OBJ = DOUBLE + 1;
final static int BYTE_OBJ = BOOLEAN_OBJ + 1;
final static int SHORT_OBJ = BYTE_OBJ + 1;
final static int INT_OBJ = SHORT_OBJ + 1;
final static int LONG_OBJ = INT_OBJ + 1;
final static int FLOAT_OBJ = LONG_OBJ + 1;
final static int DOUBLE_OBJ = FLOAT_OBJ + 1;
final static int STRING = DOUBLE_OBJ + 1;
final static int MATCHES = STRING + 1;
final static IntMap _typeMap = new IntMap();
/**
* Returns true if the expression is constant.
*/
public boolean isConstant()
{
return false;
}
/**
* Returns true if the expression is read-only.
*/
public boolean isReadOnly(ELContext env)
{
return true;
}
/**
* Returns true if the expression is literal text
*/
public boolean isLiteralText()
{
return false;
}
/**
* Creates a field reference using this expression as the base object.
*
* @param field the expression for the field.
*/
public Expr createField(Expr field)
{
return new ArrayResolverExpr(this, field);
}
/**
* Creates a field reference using this expression as the base object.
*
* @param field the string reference for the field.
*/
public Expr createField(String field)
{
return createField(new StringLiteral(field));
}
/**
* Creates a method call using this as the obj.method
* expression
*
* @param args the arguments for the method
*/
public Expr createMethod(Expr []args)
{
return new FunctionExpr(this, args);
}
/**
* Evaluates the expression, returning an object.
*
* @param env the variable environment
*
* @return the value of the expression as an object
*/
abstract public Object getValue(ELContext env)
throws ELException;
/**
* Evaluates the expression, returning an object.
*
* @param env the variable environment
*
* @return the value of the expression as an object
*/
public MethodInfo getMethodInfo(ELContext env,
Class> returnType,
Class> []argTypes)
throws ELException
{
throw new ELException(L.l("'{0}' is an illegal method expression." + getClass(),
toString()));
}
/**
* Evaluates the expression, returning an object.
*
* @param env the variable environment
*
* @return the value of the expression as an object
*/
public Object invoke(ELContext env, Class> []argTypes, Object []args)
throws ELException
{
throw new ELException(L.l("'{0}' is an illegal method expression on {1}",
toString(), getClass().getName()));
}
/**
* Evaluates the expression, returning an object.
*
* @param env the variable environment
*
* @return the value of the expression as an object
*/
public final Object evalObject(ELContext env)
throws ELException
{
return getValue(env);
}
/**
* Evaluate the expression, knowing the value should be a boolean.
*
* @param env the variable environment
*
* @return the value of the expression as a boolean
*/
public boolean evalBoolean(ELContext env)
throws ELException
{
return toBoolean(getValue(env), env);
}
/**
* Evaluate the expression, knowing the value should be a double.
*
* @param env the variable environment
*
* @return the value of the expression as a double
*/
public double evalDouble(ELContext env)
throws ELException
{
return toDouble(getValue(env), env);
}
/**
* Evaluate the expression, knowing the value should be a long
*
* @param env the variable environment
*
* @return the value of the expression as a double
*/
public long evalLong(ELContext env)
throws ELException
{
return toLong(getValue(env), env);
}
/**
* Evaluate the expression, knowing the value should be a string
*
* @param env the variable environment
*
* @return the value of the expression as a string
*/
public String evalString(ELContext env)
throws ELException
{
return toString(getValue(env), env);
}
/**
* Evaluate the expression, knowing the value should be a string
*
* @param env the variable environment
*
* @return the value of the expression as a string
*/
public String evalStringWithNull(ELContext env)
throws ELException
{
return toStringWithNull(getValue(env), env);
}
/**
* Evaluate the expression, knowing the value should be a string
*
* @param env the variable environment
*
* @return the value of the expression as a string
*/
public char evalCharacter(ELContext env)
throws ELException
{
return toCharacter(getValue(env), env);
}
/**
* Evaluate the expression, knowing the value should be a period
*
* @param env the variable environment
*
* @return the value of the expression as a period
*/
public long evalPeriod(ELContext env)
throws ELException
{
try {
Object obj = getValue(env);
if (obj instanceof Number)
return 1000L * ((Number) obj).longValue();
else
return Period.toPeriod(toString(obj, env));
} catch (Exception e) {
throw new ELException(e.getMessage());
}
}
/**
* Evaluate the expression, knowing the value should be a BigInteger.
*
* @param env the variable environment
*
* @return the value of the expression as a BigInteger
*/
public BigInteger evalBigInteger(ELContext env)
throws ELException
{
return toBigInteger(getValue(env), env);
}
/**
* Evaluate the expression, knowing the value should be a BigDecimal.
*
* @param env the variable environment
*
* @return the value of the expression as a BigDecimal
*/
public BigDecimal evalBigDecimal(ELContext env)
throws ELException
{
return toBigDecimal(getValue(env), env);
}
/**
* Evaluates the expression, setting an object.
*
* @param env the variable environment
*
* @return the value of the expression as an object
*/
@Override
public void setValue(ELContext env, Object value)
throws PropertyNotFoundException,
PropertyNotWritableException,
ELException
{
throw new PropertyNotWritableException(getClass().getName() + ": " + toString());
}
/**
* Evaluates directly to the output. The method returns true
* if the default value should be printed instead.
*
* @param out the output writer
* @param env the variable environment
* @param escapeXml if true, escape reserved XML
*
* @return true if the object is null, otherwise false
*/
public boolean print(WriteStream out,
ELContext env,
boolean escapeXml)
throws IOException, ELException
{
Object obj = getValue(env);
if (obj == null)
return true;
else if (escapeXml) {
toStreamEscaped(out, obj);
return false;
}
else {
toStream(out, obj);
return false;
}
}
/**
* Evaluates directly to the output. The method returns true
* if the default value should be printed instead.
*
* @param out the output writer
* @param env the variable environment
* @param escapeXml if true, escape reserved XML
*
* @return true if the object is null, otherwise false
*/
public boolean print(JspWriter out,
ELContext env,
boolean escapeXml)
throws IOException, ELException
{
//try {
Object obj = getValue(env);
if (obj == null)
return true;
else if (escapeXml) {
toStreamEscaped(out, obj);
return false;
}
else {
toStream(out, obj);
return false;
}
/*
} catch (ELException e) {
// jsp/3253
log.log(Level.WARNING, e.toString(), e);
return false;
}
*/
}
/**
* Generates the code to regenerate the expression.
*
* @param os the stream to the *.java page
*/
public void printCreate(WriteStream os)
throws IOException
{
throw new UnsupportedOperationException(getClass().getName());
}
//
// EL methods
//
@Override
public String getExpressionString()
{
return toString();
}
@Override
public Class> getExpectedType()
{
return Object.class;
}
@Override
public Class> getType(ELContext context)
throws PropertyNotFoundException,
ELException
{
Object value = getValue(context);
if (value == null)
return null;
else
return value.getClass();
}
//
// Static convenience methods
//
/**
* Returns true for a double or double-equivalent.
*/
public static boolean isDouble(Object o)
{
if (o instanceof Double)
return true;
else if (o instanceof Float)
return true;
else if (! (o instanceof String))
return false;
else {
String s = (String) o;
int len = s.length();
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
if (ch == '.' || ch == 'e' || ch == 'E')
return true;
}
return false;
}
}
/**
* Converts some unknown value to a string.
*
* @param value the value to be converted.
*
* @return the string-converted value.
*/
public static String toStringWithNull(Object value, ELContext env)
{
if (value == null || value instanceof String)
return (String) value;
else
return value.toString();
}
/**
* Converts some unknown value to a string.
*
* @param value the value to be converted.
*
* @return the string-converted value.
*/
public static String toString(Object value, ELContext env)
{
if (value == null)
return "";
else if (value instanceof String)
return (String) value;
else
return value.toString();
}
/**
* Converts some unknown value to a string.
*
* @param value the value to be converted.
*
* @return the string-converted value.
*/
public static String toString(long value, ELContext env)
{
return String.valueOf(value);
}
/**
* Converts some unknown value to a string.
*
* @param value the value to be converted.
*
* @return the string-converted value.
*/
public static String toString(double value, ELContext env)
{
return String.valueOf(value);
}
/**
* Converts some unknown value to a string.
*
* @param value the value to be converted.
*
* @return the string-converted value.
*/
public static String toString(boolean value, ELContext env)
{
return String.valueOf(value);
}
/**
* Converts some unknown value to a string.
*
* @param value the value to be converted.
*
* @return the string-converted value.
*/
public static String toString(char value, ELContext env)
{
return String.valueOf(value);
}
/**
* Converts some unknown value to a string.
*
* @param value the value to be converted.
*
* @return the string-converted value.
*/
public static char toCharacter(Object value, ELContext env)
throws ELException
{
if (value == null)
return (char) 0;
else if (value instanceof Character) {
return ((Character) value).charValue();
}
else if (value instanceof String) {
String s = (String) value;
if (s == null || s.length() == 0)
return (char) 0;
else
return s.charAt(0);
}
else if (value instanceof Number) {
Number number = (Number) value;
return (char) number.intValue();
}
else if (value instanceof Boolean) {
ELException e = new ELException(L.l("can't convert {0} to character.",
value.getClass().getName()));
throw e;
/*
error(e, env);
return (char) 0;
*/
}
else
return (char) toLong(value, env);
}
/**
* Converts some unknown value to a boolean.
*
* @param value the value to be converted.
*
* @return the boolean-converted value.
*/
public static boolean toBoolean(Object value, ELContext env)
throws ELException
{
if (value == null || value.equals(""))
return false;
else if (value instanceof Boolean)
return ((Boolean) value).booleanValue();
else if (value instanceof String)
return value.equals("true") || value.equals("yes");
else {
ELException e = new ELException(L.l("can't convert {0} to boolean.",
value.getClass().getName()));
// jsp/18s1
throw e;
/*
error(e, env);
return false;
*/
}
}
/**
* Converts some unknown value to a double.
*
* @param value the value to be converted.
*
* @return the double-converted value.
*/
public static double toDouble(Object value, ELContext env)
throws ELException
{
try {
if (value == null)
return 0;
else if (value instanceof Number) {
double dValue = ((Number) value).doubleValue();
if (Double.isNaN(dValue))
return 0;
else
return dValue;
}
else if (value.equals(""))
return 0;
else if (value instanceof String) {
double dValue = Double.parseDouble((String) value);
if (Double.isNaN(dValue))
return 0;
else
return dValue;
}
else if (value instanceof Character) {
// jsp/18s7
return ((Character) value).charValue();
}
else {
ELException e = new ELException(L.l("can't convert {0} to double.",
value.getClass().getName()));
// error(e, env);
// return 0;
throw e;
}
} catch (NumberFormatException e) {
throw new ELException(L.l("can't convert '{0}' to double.", value));
}
}
/**
* Converts some unknown value to a big decimal
*
* @param value the value to be converted.
*
* @return the BigDecimal-converted value.
*/
public static BigDecimal toBigDecimal(Object value, ELContext env)
throws ELException
{
if (value == null)
return BIG_DECIMAL_ZERO;
else if (value instanceof BigDecimal)
return (BigDecimal) value;
else if (value instanceof Number) {
double dValue = ((Number) value).doubleValue();
return new BigDecimal(dValue);
}
else if (value.equals(""))
return BIG_DECIMAL_ZERO;
else if (value instanceof String) {
return new BigDecimal((String) value);
}
else if (value instanceof Character) {
return new BigDecimal(((Character) value).charValue());
}
else {
ELException e = new ELException(L.l("can't convert {0} to BigDecimal.",
value.getClass().getName()));
error(e, env);
return BIG_DECIMAL_ZERO;
}
}
/**
* Converts some unknown value to a big integer
*
* @param value the value to be converted.
*
* @return the BigInteger-converted value.
*/
public static BigInteger toBigInteger(Object value, ELContext env)
throws ELException
{
if (value == null)
return BIG_INTEGER_ZERO;
else if (value instanceof BigInteger)
return (BigInteger) value;
else if (value instanceof Number) {
// return new BigInteger(value.toString());
return new BigDecimal(value.toString()).toBigInteger();
}
else if (value.equals(""))
return BIG_INTEGER_ZERO;
else if (value instanceof String) {
return new BigInteger((String) value);
}
else if (value instanceof Character) {
return new BigInteger(String.valueOf((int) ((Character) value).charValue()));
}
else {
ELException e = new ELException(L.l("can't convert {0} to BigInteger.",
value.getClass().getName()));
error(e, env);
return BIG_INTEGER_ZERO;
}
}
/**
* Converts some unknown value to a long.
*
* @param value the value to be converted.
*
* @return the long-converted value.
*/
public static long toLong(Object value, ELContext env)
throws ELException
{
if (value == null)
return 0;
else if (value instanceof Number)
return ((Number) value).longValue();
else if (value.equals(""))
return 0;
else if (value instanceof String) {
try {
String string = (String) value;
// jsp/32a2
return Long.parseLong(string);
} catch (Exception e) {
throw new ELException(e);
}
}
else if (value instanceof Character) {
// jsp/18s6
return ((Character) value).charValue();
}
else {
ELException e = new ELException(L.l("can't convert {0} to long.",
value.getClass().getName()));
// error(e, env);
// return 0;
throw e;
}
}
/**
* Write to the stream.
*
* @param out the output stream
* @param value the value to be written.
*
* @return true for null
*/
public static boolean toStream(JspWriter out,
Object value,
boolean isEscaped)
throws IOException
{
if (value == null)
return true;
if (isEscaped)
toStreamEscaped(out, value);
else
toStream(out, value);
return false;
}
/**
* Write to the stream.
*
* @param out the output stream
* @param value the value to be written.
*/
public static void toStream(WriteStream out, Object value)
throws IOException
{
if (value == null)
return;
else if (value instanceof String)
out.print((String) value);
else if (value instanceof Reader) {
out.writeStream((Reader) value);
}
else
out.print(value.toString());
}
/**
* Write to the stream.
*
* @param out the output stream
* @param value the value to be written.
*/
public static void toStream(JspWriter out, Object value)
throws IOException
{
if (value == null)
return;
else if (value instanceof String)
out.print((String) value);
else if (value instanceof Reader) {
Reader reader = (Reader) value;
int ch;
while ((ch = reader.read()) > 0) {
out.print((char) ch);
}
}
else
out.print(value.toString());
}
/**
* Write to the *.java stream escaping Java reserved characters.
*
* @param os the output stream to the *.java code.
*
* @param string the value to be converted.
*/
public static void printEscapedString(WriteStream os, String string)
throws IOException
{
int length = string.length();
for (int i = 0; i < length; i++) {
char ch = string.charAt(i);
switch (ch) {
case '\\':
os.print("\\\\");
break;
case '\n':
os.print("\\n");
break;
case '\r':
os.print("\\r");
break;
case '\"':
os.print("\\\"");
break;
default:
os.print((char) ch);
break;
}
}
}
/**
* Write to the stream.
*
* @param out the output stream
* @param value the value to be written.
*/
public static void toStreamEscaped(Writer out, Object value)
throws IOException
{
if (value == null)
return;
else if (value instanceof Reader) {
toStreamEscaped(out, (Reader) value);
return;
}
String string = value.toString();
int length = string.length();
for (int i = 0; i < length; i++) {
int ch = string.charAt(i);
switch (ch) {
case '<':
out.write("<");
break;
case '>':
out.write(">");
break;
case '&':
out.write("&");
break;
case '\'':
out.write("'");
break;
case '"':
out.write(""");
break;
default:
out.write((char) ch);
break;
}
}
}
/**
* Write to the stream escaping XML reserved characters.
*
* @param out the output stream.
* @param value the value to be converted.
*/
public static void toStreamEscaped(WriteStream out, Object value)
throws IOException
{
if (value == null)
return;
String string = value.toString();
int length = string.length();
for (int i = 0; i < length; i++) {
int ch = string.charAt(i);
switch (ch) {
case '<':
out.print("<");
break;
case '>':
out.print(">");
break;
case '&':
out.print("&");
break;
case '\'':
out.print("'");
break;
case '"':
out.print(""");
break;
default:
out.print((char) ch);
break;
}
}
}
/**
* Write to the stream escaping XML reserved characters.
*
* @param out the output stream.
* @param in the value to be converted.
*/
public static void toStreamEscaped(Writer out, Reader in)
throws IOException
{
if (in == null)
return;
int ch;
while ((ch = in.read()) >= 0) {
switch (ch) {
case '<':
out.write("<");
break;
case '>':
out.write(">");
break;
case '&':
out.write("&");
break;
case '\'':
out.write("'");
break;
case '"':
out.write(""");
break;
default:
out.write((char) ch);
break;
}
}
}
/**
* jsp/3019
*/
public static Class> toClass(Object value, ELContext env)
throws ELException
{
if (value == null)
return null;
else if (value instanceof Class)
return (Class>) value;
else if (value instanceof String) {
try {
Thread thread = Thread.currentThread();
ClassLoader loader = thread.getContextClassLoader();
return Class.forName((String) value, false, loader);
} catch (ClassNotFoundException e) {
error(e, env);
return null;
}
}
else {
ELException e = new ELException(L.l("can't convert {0} to Class.",
value.getClass().getName()));
error(e, env);
return null;
}
}
public static Object toEnum(Object obj, Class extends Enum> enumType)
{
if (obj == null)
return null;
Class objClass = obj.getClass();
if (objClass.equals(enumType))
return obj;
if (obj.getClass().equals(String.class) && "".equals(obj))
return null;
try {
return Enum.valueOf(enumType, obj.toString());
} catch (IllegalArgumentException e) {
throw new ELException(L.l("Unable convert '{0}' to '{1}'",
obj.toString(),
enumType.getName()));
}
}
/**
* Write to the *.java stream escaping Java reserved characters.
*
* @param os the output stream to the *.java code.
*
* @param is the value to be converted.
*/
public static void printEscaped(WriteStream os, ReadStream is)
throws IOException
{
int ch;
while ((ch = is.readChar()) >= 0) {
switch (ch) {
case '\\':
os.print("\\\\");
break;
case '\n':
os.print("\\n");
break;
case '\r':
os.print("\\r");
break;
case '\"':
os.print("\\\"");
break;
default:
os.print((char) ch);
break;
}
}
}
// XXX: does this belong in JSP?
public static void setProperty(Object target, String property, Object value)
throws ELException, JspException
{
if (target instanceof Map) {
Map map = (Map) target;
if (value != null)
map.put(property, value);
else
map.remove(property);
}
else if (target != null) {
Method method = null;
try {
method = BeanUtil.getSetMethod(target.getClass(), property);
} catch (Exception e) {
throw new JspException(e);
}
if (method == null)
throw new JspException(L.l("can't find property `{0}' in `{1}'",
property, target.getClass()));
Class> type = method.getParameterTypes()[0];
try {
int code = _typeMap.get(type);
switch (code) {
case BOOLEAN:
value = toBoolean(value, null) ? Boolean.TRUE : Boolean.FALSE;
break;
case BYTE:
value = new Byte((byte) toLong(value, null));
break;
case SHORT:
value = new Short((short) toLong(value, null));
break;
case INT:
value = new Integer((int) toLong(value, null));
break;
case LONG:
value = new Long((long) toLong(value, null));
break;
case FLOAT:
value = new Float((float) toDouble(value, null));
break;
case DOUBLE:
value = new Double((double) toDouble(value, null));
break;
case BOOLEAN_OBJ:
if (value != null)
value = toBoolean(value, null) ? Boolean.TRUE : Boolean.FALSE;
break;
case BYTE_OBJ:
if (value != null)
value = new Byte((byte) toLong(value, null));
break;
case SHORT_OBJ:
if (value != null)
value = new Short((short) toLong(value, null));
break;
case INT_OBJ:
if (value != null)
value = new Integer((int) toLong(value, null));
break;
case LONG_OBJ:
if (value != null)
value = new Long((long) toLong(value, null));
break;
case FLOAT_OBJ:
if (value != null)
value = new Float((float) toDouble(value, null));
break;
case DOUBLE_OBJ:
if (value != null)
value = new Double((double) toDouble(value, null));
break;
case STRING:
if (value != null)
value = String.valueOf(value);
break;
default:
break;
}
method.invoke(target, new Object[] { value });
} catch (Exception e) {
throw new JspException(e);
}
}
else {
// jsp/1c2l and JSTL TCK for exception type
throw new javax.servlet.jsp.JspException(L.l("null is an invalid c:set target value."));
}
}
protected static boolean isDoubleString(Object obj)
{
if (! (obj instanceof String))
return false;
String s = (String) obj;
int len = s.length();
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
if (ch == '.' || ch == 'e' || ch == 'E')
return true;
}
return false;
}
public static Object coerceToType(Object obj, Class> targetType)
throws ELException
{
if (targetType == null)
return obj;
CoerceType type = _coerceMap.get(targetType);
if (type != null) {
switch (type) {
case BOOLEAN:
return Expr.toBoolean(obj, null) ? Boolean.TRUE : Boolean.FALSE;
case CHARACTER:
return Expr.toCharacter(obj, null);
case BYTE:
return new Byte((byte) Expr.toLong(obj, null));
case SHORT:
return new Short((short) Expr.toLong(obj, null));
case INTEGER:
return new Integer((int) Expr.toLong(obj, null));
case LONG:
return new Long(Expr.toLong(obj, null));
case FLOAT:
return new Float((float) Expr.toDouble(obj, null));
case DOUBLE:
return new Double(Expr.toDouble(obj, null));
case STRING:
if (obj == null)
return "";
else
return obj.toString();
case BIG_DECIMAL:
return Expr.toBigDecimal(obj, null);
case BIG_INTEGER:
return Expr.toBigInteger(obj, null);
case CLASS:
return Expr.toClass(obj, null);
case OBJECT:
return obj;
case VOID:
return null;
}
} else if (targetType.isEnum()) {
return Expr.toEnum(obj, (Class extends Enum>) targetType);
} else if (obj == null) {
return null;
} else if (targetType.isAssignableFrom(obj.getClass())) {
return obj;
}
throw new ELException(L.l("unable to convert {0} to type {1}",
obj,
targetType));
}
/**
* Returns an error object
*/
public static Object error(Throwable e, ELContext env)
throws ELException
{
if (e instanceof ELException)
throw (ELException) e;
else if (env == null) {
// jsp/1b56
throw new ELException(e);
}
else if (env instanceof ExprEnv && ((ExprEnv) env).isIgnoreException()) {
log.log(Level.FINE, e.toString(), e);
return null;
}
else if (e instanceof RuntimeException)
throw (RuntimeException) e;
else
throw new ELException(e);
}
public int hashCode()
{
return toString().hashCode();
}
public boolean equals(Object o)
{
if (this == o)
return true;
else if (! (o instanceof Expr))
return false;
return toString().equals(o.toString());
}
abstract public String toString();
/**
* Returns an error object
*/
public static Object invocationError(Throwable e)
throws ELException
{
if (e instanceof InvocationTargetException && e.getCause() != null)
e = e.getCause();
if (e instanceof RuntimeException)
throw (RuntimeException) e;
else if (e instanceof Error)
throw (Error) e;
else
throw new ELException(e);
}
private enum CoerceType {
BOOLEAN,
CHARACTER,
STRING,
INTEGER,
DOUBLE,
LONG,
FLOAT,
SHORT,
BYTE,
BIG_INTEGER,
BIG_DECIMAL,
CLASS,
VOID,
OBJECT
};
static {
_coerceMap.put(boolean.class, CoerceType.BOOLEAN);
_coerceMap.put(Boolean.class, CoerceType.BOOLEAN);
_coerceMap.put(byte.class, CoerceType.BYTE);
_coerceMap.put(Byte.class, CoerceType.BYTE);
_coerceMap.put(short.class, CoerceType.SHORT);
_coerceMap.put(Short.class, CoerceType.SHORT);
_coerceMap.put(int.class, CoerceType.INTEGER);
_coerceMap.put(Integer.class, CoerceType.INTEGER);
_coerceMap.put(long.class, CoerceType.LONG);
_coerceMap.put(Long.class, CoerceType.LONG);
_coerceMap.put(float.class, CoerceType.FLOAT);
_coerceMap.put(Float.class, CoerceType.FLOAT);
_coerceMap.put(double.class, CoerceType.DOUBLE);
_coerceMap.put(Double.class, CoerceType.DOUBLE);
_coerceMap.put(char.class, CoerceType.CHARACTER);
_coerceMap.put(Character.class, CoerceType.CHARACTER);
_coerceMap.put(String.class, CoerceType.STRING);
_coerceMap.put(BigDecimal.class, CoerceType.BIG_DECIMAL);
_coerceMap.put(BigInteger.class, CoerceType.BIG_INTEGER);
_coerceMap.put(void.class, CoerceType.VOID);
_coerceMap.put(Object.class, CoerceType.OBJECT);
_coerceMap.put(Class.class, CoerceType.CLASS);
}
static {
_typeMap.put(boolean.class, BOOLEAN);
_typeMap.put(byte.class, BYTE);
_typeMap.put(short.class, SHORT);
_typeMap.put(int.class, INT);
_typeMap.put(long.class, LONG);
_typeMap.put(float.class, FLOAT);
_typeMap.put(double.class, DOUBLE);
_typeMap.put(Boolean.class, BOOLEAN_OBJ);
_typeMap.put(Byte.class, BYTE_OBJ);
_typeMap.put(Short.class, SHORT_OBJ);
_typeMap.put(Integer.class, INT_OBJ);
_typeMap.put(Long.class, LONG_OBJ);
_typeMap.put(Float.class, FLOAT_OBJ);
_typeMap.put(Double.class, DOUBLE_OBJ);
_typeMap.put(String.class, STRING);
}
}