com.caucho.xpath.expr.StaticJavaExpr Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resin-kernel Show documentation
Show all versions of resin-kernel Show documentation
Kernel for Resin Java Application Server
The newest version!
/*
* Copyright (c) 1998-2012 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 SoftwareFoundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.xpath.expr;
import com.caucho.util.CharBuffer;
import com.caucho.xpath.Expr;
import com.caucho.xpath.ExprEnvironment;
import com.caucho.xpath.XPathException;
import org.w3c.dom.Node;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
* Implements the static java extension functions.
*/
public class StaticJavaExpr extends Expr {
private static final int J_BOOLEAN = 1;
private static final int J_BYTE = J_BOOLEAN + 1;
private static final int J_SHORT = J_BYTE + 1;
private static final int J_INT = J_SHORT + 1;
private static final int J_LONG = J_INT + 1;
private static final int J_FLOAT = J_LONG + 1;
private static final int J_DOUBLE = J_FLOAT + 1;
private static final int J_STRING = J_DOUBLE + 1;
private static final int J_OBJECT = J_STRING + 1;
// Code of the expression defined in Expr
private Method _method;
// Arguments for more than 3.
private ArrayList args;
private int []argTypes;
private int retType;
/**
* Create a StringExpression with three arguments.
*
* @param method Java method
* @param args the arguments
*/
public StaticJavaExpr(Method method, ArrayList args)
{
_method = method;
this.args = args;
argTypes = new int[args.size()];
Class []paramClasses = _method.getParameterTypes();
for (int i = 0; i < paramClasses.length; i++)
argTypes[i] = classToType(paramClasses[i]);
retType = classToType(_method.getReturnType());
}
private int classToType(Class cl)
{
if (boolean.class.equals(cl) || Boolean.class.equals(cl))
return J_BOOLEAN;
else if (byte.class.equals(cl) || Byte.class.equals(cl))
return J_BYTE;
else if (short.class.equals(cl) || Short.class.equals(cl))
return J_SHORT;
else if (int.class.equals(cl) || Integer.class.equals(cl))
return J_INT;
else if (long.class.equals(cl) || Long.class.equals(cl))
return J_LONG;
else if (float.class.equals(cl) || Float.class.equals(cl))
return J_FLOAT;
else if (double.class.equals(cl) || Double.class.equals(cl))
return J_DOUBLE;
else if (String.class.equals(cl))
return J_STRING;
else
return J_OBJECT;
}
/**
* True if it returns a string.
*/
public boolean isString()
{
return retType == J_STRING;
}
/**
* True if this returns a boolean.
*/
public boolean isBoolean()
{
return retType == J_BOOLEAN;
}
/**
* True if this returns a boolean.
*/
public boolean isNumber()
{
return retType >= J_BYTE && retType <= J_DOUBLE;
}
/**
* Evaluates the expression as an string.
*
* @param node the current node
* @param env the variable environment.
*
* @return the string representation of the expression.
*/
public String evalString(Node node, ExprEnvironment env)
throws XPathException
{
Object value = evalObject(node, env);
return String.valueOf(value);
}
/**
* Evaluate the expression as a boolean, i.e. evaluate it as a string
* and then convert it to a boolean.
*
* @param node the current node
* @param env the variable environment.
*
* @return the boolean representation of the expression.
*/
public boolean evalBoolean(Node node, ExprEnvironment env)
throws XPathException
{
return toBoolean(evalObject(node, env));
}
/**
* Evaluate the expression as a double, i.e. evaluate it as a string
* and then convert it to a double.
*
* @param node the current node
* @param env the variable environment.
*
* @return the numeric representation of the expression.
*/
public double evalNumber(Node node, ExprEnvironment env)
throws XPathException
{
return toDouble(evalObject(node, env));
}
/**
* Evaluate the expression as an object, i.e. return the string value.
*
* @param node the current node
* @param env the variable environment.
*
* @return the boolean representation of the expression.
*/
public Object evalObject(Node node, ExprEnvironment env)
throws XPathException
{
Object []argArray = new Object[args.size()];
for (int i = 0; i < argArray.length; i++) {
Expr expr = (Expr) args.get(i);
switch (argTypes[i]) {
case J_BOOLEAN:
argArray[i] = new Boolean(expr.evalBoolean(node, env));
break;
case J_BYTE:
argArray[i] = new Byte((byte) expr.evalNumber(node, env));
break;
case J_SHORT:
argArray[i] = new Short((short) expr.evalNumber(node, env));
break;
case J_INT:
argArray[i] = new Integer((int) expr.evalNumber(node, env));
break;
case J_LONG:
argArray[i] = new Long((long) expr.evalNumber(node, env));
break;
case J_FLOAT:
argArray[i] = new Float((float) expr.evalNumber(node, env));
break;
case J_DOUBLE:
argArray[i] = new Double(expr.evalNumber(node, env));
break;
case J_STRING:
argArray[i] = expr.evalString(node, env);
break;
default:
argArray[i] = expr.evalObject(node, env);
break;
}
}
try {
return _method.invoke(null, argArray);
} catch (Exception e) {
throw new XPathException(e);
}
}
/**
* Return the expression as a string. toString() returns a valid
* XPath expression. This lets applications like XSLT use toString()
* to print the string in the generated Java.
*/
public String toString()
{
CharBuffer cb = CharBuffer.allocate();
cb.append("java:");
cb.append(_method.getDeclaringClass().getName());
cb.append(".");
cb.append(_method.getName());
cb.append("(");
for (int i = 0; i < args.size(); i++) {
if (i != 0)
cb.append(",");
cb.append(args.get(i));
}
cb.append(")");
return cb.close();
}
}