Search in sources :

Example 1 with Function

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();
}
Also used : ArrayList(java.util.ArrayList) ScoreException(org.akaza.openclinica.exception.ScoreException) Function(org.akaza.openclinica.logic.score.function.Function)

Aggregations

ArrayList (java.util.ArrayList)1 ScoreException (org.akaza.openclinica.exception.ScoreException)1 Function (org.akaza.openclinica.logic.score.function.Function)1