/*****************************************************************************
SQLJEP - Java SQL Expression Parser 0.2
November 1 2006
(c) Copyright 2006, Alexey Gaidukov
SQLJEP Author: Alexey Gaidukov
SQLJEP is based on JEP 2.24 (http://www.singularsys.com/jep/)
(c) Copyright 2002, Nathan Funk
See LICENSE.txt for license information.
*****************************************************************************/
package com.meidusa.amoeba.sqljep.function;
import java.math.BigDecimal;
import java.util.Stack;
import com.meidusa.amoeba.sqljep.ASTFunNode;
import com.meidusa.amoeba.sqljep.JepRuntime;
import com.meidusa.amoeba.sqljep.ParseException;
/**
* <pre>
* Function classes extend this class. It is an implementation of the
* PostfixMathCommandI interface.
*
* It includes a numberOfParameters member, that is checked when parsing the
* expression. This member should be initialized to an appropriate value for
* all classes extending this class. If an arbitrary number of parameters
* should be allowed, initialize this member to -1.
* </pre>
*/
public abstract class PostfixCommand implements PostfixCommandI {
protected static final Integer ZERO = new Integer(0);
public static final String PARAMS_NUMBER = "Wrong number of parameters";
public static final String WRONG_TYPE = "Wrong type";
public static final String INTERNAL_ERROR = "Internal error";
public static final String NOT_IMPLIMENTED_EXCEPTION = "Not implimented";
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* Return the required number of parameters.
* Number of parameters a the function requires. Initialize this value to
* -1 if any number of parameters should be allowed.
*/
abstract public int getNumberOfParameters();
/**
* Throws an exception because this method should never be called under
* normal circumstances. Each function should use it's own run() method
* for evaluating the function. This includes popping off the parameters
* from the stack, and pushing the result back on the stack.
*/
abstract public Comparable<?>[] evaluate(ASTFunNode node, JepRuntime runtime) throws ParseException;
public boolean isAutoBox(){
return true;
}
@SuppressWarnings("unchecked")
protected final void removeParams(Stack<Comparable> s, int num) {
int i = 1;
s.pop();
while (i < num) {
s.pop();
i++;
}
s.push(null);
}
public static Comparable<?> parse(String param) throws ParseException {
try {
return Long.valueOf((String)param);
} catch (NumberFormatException e) {
try {
BigDecimal d = new BigDecimal((String)param);
if (d.scale() < 0) {
d = d.setScale(0);
}
return d;
} catch (NumberFormatException ex) {
throw new ParseException(param+" Not a number");
}
}
}
public static BigDecimal getBigDecimal(Number param) {
// BigInteger is not supported
if (param instanceof BigDecimal) {
return (BigDecimal)param;
}
if (param instanceof Double || param instanceof Float) {
return new BigDecimal(param.doubleValue());
}
return new BigDecimal(param.longValue());
}
public static int getInteger(Comparable<?> param) throws ParseException {
if (param instanceof Number) {
return ((Number)param).intValue();
}
else if (param instanceof String) {
try {
BigDecimal d = new BigDecimal((String)param);
return d.intValueExact();
} catch (Exception e) {
throw new ParseException("Cant parse integer: '"+(String)param+"'");
}
}
throw new ParseException("Not Integer: "+(param != null ? param.getClass() : "null"));
}
public static double getDouble(Comparable<?> param) throws ParseException {
if (param instanceof Number) {
Number n = (Number)param;
return n.doubleValue();
}
else if (param instanceof String) {
try {
return Double.valueOf((String)param);
} catch (NumberFormatException e) {
throw new ParseException("Cant parse double: '"+(String)param+"'");
}
}
throw new ParseException("Not Double: "+(param != null ? param.getClass() : "null"));
}
public boolean isDeclare(){
return false;
}
}