Search in sources :

Example 46 with Operand

use of com.dexels.navajo.document.Operand in project navajo by Dexels.

the class TslCompiler method optimizeExpresssion.

/**
 * VERY NASTY METHOD. IT TRIES ALL KINDS OF TRICKS TO TRY TO AVOID CALLING
 * THE EXPRESSION.EVALUATE() METHOD IN THE GENERATED JAVA.
 *
 * @param ident
 * @param clause
 * @param className
 * @return
 */
public String optimizeExpresssion(int ident, String clause, String className, String objectName) throws UserException {
    boolean exact = false;
    StringBuilder result = new StringBuilder();
    char firstChar = ' ';
    boolean functionCall = false;
    StringBuilder functionNameBuffer = new StringBuilder();
    String functionName = "";
    String call = "";
    // attribute call.
    for (int i = 0; i < clause.length(); i++) {
        char c = clause.charAt(i);
        if (c != ' ' && firstChar == ' ') {
            firstChar = c;
        }
        if (((firstChar > 'a' && firstChar < 'z')) || ((firstChar > 'A') && (firstChar < 'Z'))) {
            functionCall = true;
        }
        if ((functionCall) && (c != '(')) {
            functionNameBuffer.append(c);
        } else if (functionCall && c == '(') {
            functionName = functionNameBuffer.toString();
            functionNameBuffer = new StringBuilder();
        }
        if (c == '$') {
            // New attribute found
            StringBuilder name = new StringBuilder();
            i++;
            c = clause.charAt(i);
            while (c != '(' && i < clause.length() && c != ')') {
                name.append(c);
                i++;
                if (i < clause.length()) {
                    c = clause.charAt(i);
                }
            }
            if (name.toString().contains("..")) {
                // We cannot optimize these yet
                continue;
            }
            i++;
            StringBuilder params = new StringBuilder();
            if (clause.indexOf("(") != -1) {
                // Determine parameters.
                int endOfParams = 1;
                while (endOfParams > 0 && i < clause.length()) {
                    c = clause.charAt(i);
                    if (c == '(') {
                        endOfParams++;
                    } else if (c == ')') {
                        endOfParams--;
                    } else {
                        params.append(c);
                    }
                    i++;
                }
            }
            String expr = "";
            if (functionName.equals("")) {
                expr = (params.toString().length() > 0 ? "$" + name + "(" + params + ")" : "$" + name);
            } else {
                expr = functionName + "(" + (params.toString().length() > 0 ? "$" + name + "(" + params + ")" : "$" + name) + ")";
            }
            if (removeWhiteSpaces(expr).equals(removeWhiteSpaces(clause))) {
                // Let's evaluate this directly.
                exact = true;
                Class expressionContextClass = null;
                try {
                    StringBuilder objectizedParams = new StringBuilder();
                    StringTokenizer allParams = new StringTokenizer(params.toString(), ",");
                    while (allParams.hasMoreElements()) {
                        String param = allParams.nextToken();
                        // Try to evaluate expression (NOTE THAT IF
                        // REFERENCES ARE MADE TO EITHER NAVAJO OR MAPPABLE
                        // OBJECTS THIS WILL FAIL
                        // SINCE THESE OBJECTS ARE NOT KNOWN AT COMPILE
                        // TIME!!!!!!!!!!!!!!1
                        Operand op = Expression.evaluate(param, null);
                        Object v = op.value;
                        if (v instanceof String) {
                            objectizedParams.append("\"" + v + "\"");
                        } else if (v instanceof Integer) {
                            objectizedParams.append("new Integer(" + v + ")");
                        } else if (v instanceof Long) {
                            objectizedParams.append("Long.valueOf(" + v + ")");
                        } else if (v instanceof Float) {
                            objectizedParams.append("new Float(" + v + ")");
                        } else if (v instanceof Boolean) {
                            objectizedParams.append("new Boolean(" + v + ")");
                        } else if (v instanceof Double) {
                            objectizedParams.append("Double.valueOf(" + v + ")");
                        } else if (v == null) {
                            // Null support
                            objectizedParams.append(v);
                        } else {
                            throw new UserException(-1, "Unknown type encountered during compile time: " + v.getClass().getName() + " @clause: " + clause);
                        }
                        if (allParams.hasMoreElements()) {
                            objectizedParams.append(',');
                        }
                    }
                    try {
                        expressionContextClass = Class.forName(className, false, loader);
                    } catch (Exception e) {
                        throw new Exception("Could not find adapter: " + className);
                    }
                    String attrType = MappingUtils.getFieldType(expressionContextClass, name.toString());
                    // Try to locate class:
                    if (!functionName.equals("")) {
                        try {
                            Class.forName("com.dexels.navajo.functions." + functionName, false, loader);
                        } catch (Exception e) {
                            throw new Exception("Could not find Navajo function: " + functionName);
                        }
                    }
                    call = objectName + ".get" + (name.charAt(0) + "").toUpperCase() + name.substring(1) + "(" + objectizedParams.toString() + ")";
                    if (attrType.equals("int")) {
                        call = "new Integer(" + call + ")";
                    } else if (attrType.equals("float") || attrType.equals("double")) {
                        call = "Double.valueOf(" + call + ")";
                    } else if (attrType.equals("boolean")) {
                        call = "new Boolean(" + call + ")";
                    } else if (attrType.equals("long")) {
                        call = "Long.valueOf(" + call + ")";
                    }
                } catch (ClassNotFoundException cnfe) {
                    if (expressionContextClass == null) {
                        throw new UserException(-1, "Error in script: Could not find adapter: " + className + " @clause: " + clause);
                    } else {
                        throw new UserException(-1, "Error in script: Could not locate function: " + functionName + " @ clause: " + clause);
                    }
                } catch (Throwable e) {
                    exact = false;
                }
            }
        }
    }
    // Try to evaluate clause directly (compile time).
    if ((!exact) && !clause.equals("TODAY") && !clause.equals("null") && (clause.indexOf("[") == -1) && (clause.indexOf("$") == -1) && (clause.indexOf("(") == -1) && (clause.indexOf("+") == -1)) {
        try {
            Operand op = Expression.evaluate(clause, null);
            Object v = op.value;
            exact = true;
            if (v instanceof String) {
                call = replaceQuotesValue((String) v);
            } else if (v instanceof Integer) {
                call = "new Integer(" + v + ")";
            } else if (v instanceof Long) {
                call = "Long.valueOf(" + v + ")";
            } else if (v instanceof Float) {
                call = "new Float(" + v + ")";
            } else if (v instanceof Boolean) {
                call = "new Boolean(" + v + ")";
            } else if (v instanceof Double) {
                call = "Double.valueOf(" + v + ")";
            } else
                throw new UserException(-1, "Unknown type encountered during compile time: " + v.getClass().getName() + " @clause: " + clause);
        } catch (NullPointerException | TMLExpressionException ne) {
            exact = false;
        } catch (SystemException se) {
            exact = false;
            if (clause.length() == 0 || clause.charAt(0) != '#') {
                throw new UserException(-1, "Could not compile script, Invalid expression: " + clause);
            }
        } catch (Throwable e) {
            exact = false;
        }
    }
    if (!exact && clause.equals("null")) {
        call = "null";
        exact = true;
    }
    // Use Expression.evaluate() if expression could not be executed in an
    // optimized way.
    result.append(printIdent(ident) + "op = Expression.evaluate(" + replaceQuotes(clause) + ", access.getInDoc(), currentMap, currentInMsg, currentParamMsg, currentSelection, null, getEvaluationParams());\n");
    result.append(printIdent(ident) + "sValue = op.value;\n");
    return result.toString();
}
Also used : Operand(com.dexels.navajo.document.Operand) TMLExpressionException(com.dexels.navajo.expression.api.TMLExpressionException) UserException(com.dexels.navajo.script.api.UserException) TransformerException(javax.xml.transform.TransformerException) MappingException(com.dexels.navajo.script.api.MappingException) TMLExpressionException(com.dexels.navajo.expression.api.TMLExpressionException) ParseException(com.dexels.navajo.parser.compiled.ParseException) KeywordException(com.dexels.navajo.mapping.compiler.meta.KeywordException) MetaCompileException(com.dexels.navajo.mapping.compiler.meta.MetaCompileException) IOException(java.io.IOException) SystemException(com.dexels.navajo.script.api.SystemException) CompilationException(com.dexels.navajo.script.api.CompilationException) StringTokenizer(java.util.StringTokenizer) SystemException(com.dexels.navajo.script.api.SystemException) UserException(com.dexels.navajo.script.api.UserException)

Example 47 with Operand

use of com.dexels.navajo.document.Operand in project navajo by Dexels.

the class CompiledScript method checkValidationRules.

/**
 * Deprecated method to check validation errors. Use <validations> block
 * inside webservice script instead.
 *
 * @param conditions
 * @param inMessage
 * @param outMessage
 * @return
 * @throws NavajoException
 * @throws SystemException
 * @throws UserException
 */
private final Message[] checkValidationRules(ConditionData[] conditions, Navajo inMessage, Navajo outMessage, Access a) throws SystemException, UserException {
    if (conditions == null) {
        return null;
    }
    List<Message> messages = new ArrayList<>();
    int index = 0;
    for (int i = 0; i < conditions.length; i++) {
        ConditionData condition = conditions[i];
        boolean valid = false;
        try {
            valid = com.dexels.navajo.parser.Condition.evaluate(condition.condition, inMessage, a);
        } catch (com.dexels.navajo.expression.api.TMLExpressionException ee) {
            throw new UserException(-1, "Invalid condition: " + ee.getMessage(), ee);
        }
        if (!valid) {
            String eval = com.dexels.navajo.parser.Expression.replacePropertyValues(condition.condition, inMessage);
            Message msg = NavajoFactory.getInstance().createMessage(outMessage, "failed" + (index++));
            Property prop0 = NavajoFactory.getInstance().createProperty(outMessage, "Id", Property.STRING_PROPERTY, condition.id + "", 0, "", Property.DIR_OUT);
            // Evaluate comment as expression.
            String description = "";
            try {
                Operand o = Expression.evaluate(condition.comment, inMessage);
                description = o.value + "";
            } catch (Exception e) {
                description = condition.comment;
            }
            Property prop1 = NavajoFactory.getInstance().createProperty(outMessage, "Description", Property.STRING_PROPERTY, description, 0, "", Property.DIR_OUT);
            msg.addProperty(prop0);
            msg.addProperty(prop1);
            if (System.getenv("DEBUG_SCRIPTS") != null && System.getenv("DEBUG_SCRIPTS").equals("true")) {
                Property prop2 = NavajoFactory.getInstance().createProperty(outMessage, "FailedExpression", Property.STRING_PROPERTY, condition.condition, 0, "", Property.DIR_OUT);
                Property prop3 = NavajoFactory.getInstance().createProperty(outMessage, "EvaluatedExpression", Property.STRING_PROPERTY, eval, 0, "", Property.DIR_OUT);
                msg.addProperty(prop2);
                msg.addProperty(prop3);
            }
            messages.add(msg);
        }
    }
    if (!messages.isEmpty()) {
        Message[] msgArray = new Message[messages.size()];
        messages.toArray(msgArray);
        return msgArray;
    } else {
        return null;
    }
}
Also used : ConditionData(com.dexels.navajo.server.ConditionData) Message(com.dexels.navajo.document.Message) Operand(com.dexels.navajo.document.Operand) ArrayList(java.util.ArrayList) NavajoException(com.dexels.navajo.document.NavajoException) UserException(com.dexels.navajo.script.api.UserException) MappableException(com.dexels.navajo.script.api.MappableException) SystemException(com.dexels.navajo.script.api.SystemException) ConditionErrorException(com.dexels.navajo.server.ConditionErrorException) CompilationException(com.dexels.navajo.script.api.CompilationException) UserException(com.dexels.navajo.script.api.UserException) Property(com.dexels.navajo.document.Property)

Example 48 with Operand

use of com.dexels.navajo.document.Operand in project navajo by Dexels.

the class SumExpressions method evaluate.

/* (non-Javadoc)
	 * @see com.dexels.navajo.parser.FunctionInterface#evaluate()
	 */
@Override
public Object evaluate() throws TMLExpressionException {
    if (getOperands().size() < 2) {
        for (int i = 0; i < getOperands().size(); i++) {
            Object o = getOperands().get(i);
            System.err.println("Operand # " + i + " is: " + o.toString() + " - " + o.getClass());
        }
        throw new TMLExpressionException(this, "Wrong number of arguments: " + getOperands().size());
    }
    if (!(getOperand(0) instanceof String && getOperand(1) instanceof String)) {
        throw new TMLExpressionException(this, "Wrong argument types: " + getOperand(0).getClass() + " and " + getOperand(1).getClass());
    }
    String messageName = (String) getOperand(0);
    String expression = (String) getOperand(1);
    String filter = null;
    if (getOperands().size() > 2) {
        filter = (String) getOperand(2);
    }
    Message parent = getCurrentMessage();
    Navajo doc = getNavajo();
    try {
        List<Message> arrayMsg = (parent != null ? parent.getMessages(messageName) : doc.getMessages(messageName));
        if (arrayMsg == null) {
            throw new TMLExpressionException(this, "Empty or non existing array message: " + messageName);
        }
        String sumType = "int";
        double sum = 0;
        for (int i = 0; i < arrayMsg.size(); i++) {
            Message m = arrayMsg.get(i);
            boolean evaluate = (filter != null ? Condition.evaluate(filter, doc, null, m, getAccess()) : true);
            if (evaluate) {
                Operand o = Expression.evaluate(expression, m.getRootDoc(), null, m);
                if (o.value == null) {
                    throw new TMLExpressionException(this, "Null value encountered");
                }
                if (o.value instanceof Integer) {
                    sum += ((Integer) o.value).doubleValue();
                } else if (o.value instanceof Double) {
                    sum += ((Double) o.value).doubleValue();
                } else {
                    throw new TMLExpressionException(this, "Incompatible type while summing: " + o.value.getClass().getName());
                }
            }
        }
        if (sumType.equals("int")) {
            return Integer.valueOf((int) sum);
        } else if (sumType.equals("money")) {
            return new Money(sum);
        } else if (sumType.equals("percentage")) {
            return new Percentage(sum);
        } else {
            return Double.valueOf(sum);
        }
    } catch (NavajoException ne) {
        throw new TMLExpressionException(this, ne.getMessage());
    } catch (SystemException se) {
        throw new TMLExpressionException(this, se.getMessage());
    }
}
Also used : Message(com.dexels.navajo.document.Message) Percentage(com.dexels.navajo.document.types.Percentage) Operand(com.dexels.navajo.document.Operand) NavajoException(com.dexels.navajo.document.NavajoException) Navajo(com.dexels.navajo.document.Navajo) TMLExpressionException(com.dexels.navajo.expression.api.TMLExpressionException) Money(com.dexels.navajo.document.types.Money) SystemException(com.dexels.navajo.script.api.SystemException)

Example 49 with Operand

use of com.dexels.navajo.document.Operand in project navajo by Dexels.

the class SumProperties method main.

public static void main(String[] args) throws Exception {
    System.setProperty("com.dexels.navajo.DocumentImplementation", "com.dexels.navajo.document.nanoimpl.NavajoFactoryImpl");
    Navajo doc = NavajoFactory.getInstance().createNavajo();
    Message top = NavajoFactory.getInstance().createMessage(doc, "Top");
    doc.addMessage(top);
    Message array = NavajoFactory.getInstance().createMessage(doc, "MyArray", Message.MSG_TYPE_ARRAY);
    top.addMessage(array);
    for (int i = 0; i < 9; i++) {
        Message elt = NavajoFactory.getInstance().createMessage(doc, "MyArray", Message.MSG_TYPE_ARRAY_ELEMENT);
        array.addMessage(elt);
        Message array2 = NavajoFactory.getInstance().createMessage(doc, "NogEenArraytje" + i, Message.MSG_TYPE_ARRAY);
        elt.addMessage(array2);
        for (int j = 0; j < 2; j++) {
            Message elt2 = NavajoFactory.getInstance().createMessage(doc, "NogEenArraytje" + i, Message.MSG_TYPE_ARRAY_ELEMENT);
            array2.addMessage(elt2);
            Property p = NavajoFactory.getInstance().createProperty(doc, "MyBoolean", Property.BOOLEAN_PROPERTY, Property.TRUE, 0, "", Property.DIR_OUT);
            elt2.addProperty(p);
        }
    }
    // doc.write(System.err);
    Operand result = Expression.evaluate("SumProperties('/Top/MyArray.*/NogEenArraytje.*', 'MyBoolean')", doc);
    System.err.println("result = " + result.value);
}
Also used : Message(com.dexels.navajo.document.Message) Operand(com.dexels.navajo.document.Operand) Navajo(com.dexels.navajo.document.Navajo) Property(com.dexels.navajo.document.Property)

Example 50 with Operand

use of com.dexels.navajo.document.Operand in project navajo by Dexels.

the class ToPercentage method main.

public static void main(String[] args) throws Exception {
    java.util.Locale.setDefault(new java.util.Locale("nl", "NL"));
    // Tests.
    ToPercentage tm = new ToPercentage();
    tm.reset();
    tm.insertFloatOperand(Double.valueOf(1.5));
    System.out.println("result = " + ((Percentage) tm.evaluate()).formattedString());
    // Using expressions.
    String expression = "ToPercentage(1024.50) + 500 - 5.7 + ToPercentage(1)/2";
    Operand o = Expression.evaluate(expression, null);
    System.out.println("o = " + o.value);
    System.out.println("type = " + o.type);
}
Also used : Percentage(com.dexels.navajo.document.types.Percentage) Operand(com.dexels.navajo.document.Operand)

Aggregations

Operand (com.dexels.navajo.document.Operand)95 Test (org.junit.Test)57 Message (com.dexels.navajo.document.Message)22 ImmutableMessage (com.dexels.immutable.api.ImmutableMessage)20 Navajo (com.dexels.navajo.document.Navajo)20 TMLExpressionException (com.dexels.navajo.expression.api.TMLExpressionException)15 ContextExpression (com.dexels.navajo.expression.api.ContextExpression)14 ArrayList (java.util.ArrayList)12 Selection (com.dexels.navajo.document.Selection)11 Property (com.dexels.navajo.document.Property)10 FunctionInterface (com.dexels.navajo.expression.api.FunctionInterface)10 Access (com.dexels.navajo.script.api.Access)10 MappableTreeNode (com.dexels.navajo.script.api.MappableTreeNode)10 NavajoException (com.dexels.navajo.document.NavajoException)9 TipiLink (com.dexels.navajo.expression.api.TipiLink)9 Optional (java.util.Optional)9 FunctionDefinition (com.dexels.navajo.expression.api.FunctionDefinition)8 GiveLongTestFunction (com.dexels.navajo.expression.compiled.GiveLongTestFunction)6 SystemException (com.dexels.navajo.script.api.SystemException)6 List (java.util.List)6