use of org.akaza.openclinica.logic.score.function.Function in project OpenClinica by OpenClinica.
the class ScoreUtil method evalFunc.
/**
* Evaluate a function which might contain arithmetic expressions, and
* return result as a String.
* <p>
* If an item can not be found in the eventCRF, it will be treated as empty.
* If empty items exist in a function, the result will be empty.
*
* @param contents
* @param info
* @param function
* @return
*/
public static String evalFunc(ArrayList<ScoreToken> contents, Info info, Function function) throws ScoreException {
int originalLevel = info.level;
info.pos++;
info.level++;
ScoreToken token = new ScoreToken();
// currArg is in fact representing the current argument.
ArrayList<ScoreToken> currArg = new ArrayList<ScoreToken>();
boolean couldBeSign = true;
while (info.pos < contents.size()) {
ScoreToken scoretoken = contents.get(info.pos);
char c = scoretoken.getSymbol();
if (c == ')') {
couldBeSign = false;
info.level--;
// end of the function, marked by the equal level
if (info.level == originalLevel) {
if (token.getName().length() > 0) {
currArg.add(token);
}
String t = evalArgument(currArg);
if (t != null && t.length() > 0) {
function.addArgument(t);
} else {
// error message has been handled in evalArgument()
return "";
}
token = new ScoreToken();
break;
} else {
// argument
if (token.getName().length() > 0) {
currArg.add(token);
}
currArg.add(scoretoken);
}
token = new ScoreToken();
} else if (c == '(') {
couldBeSign = true;
String sign = "";
String tokenname = token.getName();
if (tokenname.length() > 0 && isSign(tokenname.charAt(0))) {
sign = tokenname.charAt(0) + "";
tokenname = tokenname.substring(1);
}
// it is either the start of a function or an expression
String funcname = getFunctionName(tokenname);
if (funcname != null) {
// store in the current argument
try {
token.setName(sign + evalFunc(contents, info, (Function) Class.forName(funcname).newInstance()));
token.setSymbol(ScoreSymbol.TERM_SYMBOL);
currArg.add(token);
couldBeSign = false;
} catch (InstantiationException e) {
e.printStackTrace();
return "";
} catch (ClassNotFoundException e) {
e.printStackTrace();
return "";
} catch (IllegalAccessException e) {
e.printStackTrace();
return "";
}
} else // if it is the start of an expression
{
info.level++;
if (token.getName().length() > 0) {
currArg.add(token);
}
currArg.add(scoretoken);
}
token = new ScoreToken();
} else // end of an argument
if (c == ',') {
couldBeSign = true;
if (token.getName().length() > 0) {
currArg.add(token);
}
// compute the argument
String t = evalArgument(currArg);
if (t != null && t.length() > 0) {
function.addArgument(t);
} else {
return "";
}
token = new ScoreToken();
// reset the argument for next one
currArg = new ArrayList<ScoreToken>();
} else // else if(isOperator(c)){
if (c == ScoreSymbol.ARITHMETIC_OPERATOR_SYMBOL) {
if (couldBeSign && isSign(scoretoken.getName())) {
if (token.getName().length() > 0) {
throw new ScoreException(scoretoken.getName() + " at position " + info.pos + " is invalid.", "1");
} else {
// token = scoretoken;
token.setName(scoretoken.getName());
token.setSymbol(scoretoken.getSymbol());
}
couldBeSign = false;
} else {
if (token.getName().length() > 0) {
currArg.add(token);
}
token = new ScoreToken();
currArg.add(scoretoken);
couldBeSign = true;
}
} else {
couldBeSign = false;
if (isSign(token.getName())) {
token.setName(token.getName() + scoretoken.getName());
token.setSymbol(ScoreSymbol.TERM_SYMBOL);
} else {
if (c != ' ') {
// token = scoretoken;
token.setName(scoretoken.getName());
token.setSymbol(scoretoken.getSymbol());
}
}
}
info.pos++;
}
function.execute();
if (function.getErrors().size() > 0) {
String errors = new String();
HashMap<Integer, String> es = function.getErrors();
for (int i = 0; i < es.size(); ++i) {
errors += es.get(Integer.valueOf(i));
}
throw new ScoreException(errors, "4");
}
return function.getValue();
}
Aggregations