Search in sources :

Example 26 with And

use of org.mvel2.ast.And in project jbpm by kiegroup.

the class RuleFlowProcessValidator method validateNodes.

private void validateNodes(Node[] nodes, List<ProcessValidationError> errors, RuleFlowProcess process) {
    String isForCompensation = "isForCompensation";
    for (int i = 0; i < nodes.length; i++) {
        final Node node = nodes[i];
        if (node instanceof StartNode) {
            final StartNode startNode = (StartNode) node;
            if (startNode.getTo() == null) {
                addErrorMessage(process, node, errors, "Start has no outgoing connection.");
            }
            if (startNode.getTimer() != null) {
                validateTimer(startNode.getTimer(), node, process, errors);
            }
        } else if (node instanceof EndNode) {
            final EndNode endNode = (EndNode) node;
            if (endNode.getFrom() == null) {
                addErrorMessage(process, node, errors, "End has no incoming connection.");
            }
            validateCompensationIntermediateOrEndEvent(endNode, process, errors);
        } else if (node instanceof RuleSetNode) {
            final RuleSetNode ruleSetNode = (RuleSetNode) node;
            if (ruleSetNode.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "RuleSet has no incoming connection.");
            }
            if (ruleSetNode.getTo() == null && !acceptsNoOutgoingConnections(node)) {
                addErrorMessage(process, node, errors, "RuleSet has no outgoing connection.");
            }
            final String language = ruleSetNode.getLanguage();
            if (RuleSetNode.DRL_LANG.equals(language)) {
                final String ruleFlowGroup = ruleSetNode.getRuleFlowGroup();
                if (ruleFlowGroup == null || "".equals(ruleFlowGroup)) {
                    addErrorMessage(process, node, errors, "RuleSet (DRL) has no ruleflow-group.");
                }
            } else if (RuleSetNode.DMN_LANG.equals(language)) {
                final String namespace = ruleSetNode.getNamespace();
                if (namespace == null || "".equals(namespace)) {
                    addErrorMessage(process, node, errors, "RuleSet (DMN) has no namespace.");
                }
                final String model = ruleSetNode.getModel();
                if (model == null || "".equals(model)) {
                    addErrorMessage(process, node, errors, "RuleSet (DMN) has no model.");
                }
            } else {
                addErrorMessage(process, node, errors, "Unsupported rule language '" + language + "'");
            }
            if (ruleSetNode.getTimers() != null) {
                for (Timer timer : ruleSetNode.getTimers().keySet()) {
                    validateTimer(timer, node, process, errors);
                }
            }
        } else if (node instanceof Split) {
            final Split split = (Split) node;
            if (split.getType() == Split.TYPE_UNDEFINED) {
                addErrorMessage(process, node, errors, "Split has no type.");
            }
            if (split.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "Split has no incoming connection.");
            }
            if (split.getDefaultOutgoingConnections().size() < 2) {
                addErrorMessage(process, node, errors, "Split does not have more than one outgoing connection: " + split.getOutgoingConnections().size() + ".");
            }
            if (split.getType() == Split.TYPE_XOR || split.getType() == Split.TYPE_OR) {
                for (final Iterator<Connection> it = split.getDefaultOutgoingConnections().iterator(); it.hasNext(); ) {
                    final Connection connection = it.next();
                    if (split.getConstraint(connection) == null && !split.isDefault(connection) || (!split.isDefault(connection) && (split.getConstraint(connection).getConstraint() == null || split.getConstraint(connection).getConstraint().trim().length() == 0))) {
                        addErrorMessage(process, node, errors, "Split does not have a constraint for " + connection.toString() + ".");
                    }
                }
            }
        } else if (node instanceof Join) {
            final Join join = (Join) node;
            if (join.getType() == Join.TYPE_UNDEFINED) {
                addErrorMessage(process, node, errors, "Join has no type.");
            }
            if (join.getDefaultIncomingConnections().size() < 2) {
                addErrorMessage(process, node, errors, "Join does not have more than one incoming connection: " + join.getIncomingConnections().size() + ".");
            }
            if (join.getTo() == null && !acceptsNoOutgoingConnections(node)) {
                addErrorMessage(process, node, errors, "Join has no outgoing connection.");
            }
            if (join.getType() == Join.TYPE_N_OF_M) {
                String n = join.getN();
                if (!n.startsWith("#{") || !n.endsWith("}")) {
                    try {
                        new Integer(n);
                    } catch (NumberFormatException e) {
                        addErrorMessage(process, node, errors, "Join has illegal n value: " + n);
                    }
                }
            }
        } else if (node instanceof MilestoneNode) {
            final MilestoneNode milestone = (MilestoneNode) node;
            if (milestone.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "Milestone has no incoming connection.");
            }
            if (milestone.getTo() == null && !acceptsNoOutgoingConnections(node)) {
                addErrorMessage(process, node, errors, "Milestone has no outgoing connection.");
            }
            if (milestone.getConstraint() == null) {
                addErrorMessage(process, node, errors, "Milestone has no constraint.");
            }
            if (milestone.getTimers() != null) {
                for (Timer timer : milestone.getTimers().keySet()) {
                    validateTimer(timer, node, process, errors);
                }
            }
        } else if (node instanceof StateNode) {
            final StateNode stateNode = (StateNode) node;
            if (stateNode.getDefaultIncomingConnections().size() == 0 && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "State has no incoming connection");
            }
        } else if (node instanceof SubProcessNode) {
            final SubProcessNode subProcess = (SubProcessNode) node;
            if (subProcess.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "SubProcess has no incoming connection.");
            }
            if (subProcess.getTo() == null && !acceptsNoOutgoingConnections(node)) {
                Object compensationObj = subProcess.getMetaData(isForCompensation);
                if (compensationObj == null || !((Boolean) compensationObj)) {
                    addErrorMessage(process, node, errors, "SubProcess has no outgoing connection.");
                }
            }
            if (subProcess.getProcessId() == null && subProcess.getProcessName() == null) {
                addErrorMessage(process, node, errors, "SubProcess has no process id.");
            }
            if (subProcess.getTimers() != null) {
                for (Timer timer : subProcess.getTimers().keySet()) {
                    validateTimer(timer, node, process, errors);
                }
            }
            if (!subProcess.isIndependent() && !subProcess.isWaitForCompletion()) {
                addErrorMessage(process, node, errors, "SubProcess you can only set " + "independent to 'false' only when 'Wait for completion' is set to true.");
            }
        } else if (node instanceof ActionNode) {
            final ActionNode actionNode = (ActionNode) node;
            if (actionNode.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "Action has no incoming connection.");
            }
            if (actionNode.getTo() == null && !acceptsNoOutgoingConnections(node)) {
                Object compensationObj = actionNode.getMetaData(isForCompensation);
                if (compensationObj == null || !((Boolean) compensationObj)) {
                    addErrorMessage(process, node, errors, "Action has no outgoing connection.");
                }
            }
            if (actionNode.getAction() == null) {
                addErrorMessage(process, node, errors, "Action has no action.");
            } else if (actionNode.getAction() instanceof DroolsConsequenceAction) {
                DroolsConsequenceAction droolsAction = (DroolsConsequenceAction) actionNode.getAction();
                String actionString = droolsAction.getConsequence();
                if (actionString == null) {
                    addErrorMessage(process, node, errors, "Action has empty action.");
                } else if ("mvel".equals(droolsAction.getDialect())) {
                    try {
                        ParserContext parserContext = new ParserContext();
                        // parserContext.setStrictTypeEnforcement(true);
                        ExpressionCompiler compiler = new ExpressionCompiler(actionString, parserContext);
                        compiler.setVerifying(true);
                        compiler.compile();
                        List<ErrorDetail> mvelErrors = parserContext.getErrorList();
                        if (mvelErrors != null) {
                            for (Iterator<ErrorDetail> iterator = mvelErrors.iterator(); iterator.hasNext(); ) {
                                ErrorDetail error = iterator.next();
                                addErrorMessage(process, node, errors, "Action has invalid action: " + error.getMessage() + ".");
                            }
                        }
                    } catch (Throwable t) {
                        addErrorMessage(process, node, errors, "Action has invalid action: " + t.getMessage() + ".");
                    }
                }
                // TODO: validation for "java" and "drools" scripts!
                validateCompensationIntermediateOrEndEvent(actionNode, process, errors);
            }
        } else if (node instanceof WorkItemNode) {
            final WorkItemNode workItemNode = (WorkItemNode) node;
            if (workItemNode.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "Task has no incoming connection.");
            }
            if (workItemNode.getTo() == null && !acceptsNoOutgoingConnections(node)) {
                Object compensationObj = workItemNode.getMetaData(isForCompensation);
                if (compensationObj == null || !((Boolean) compensationObj)) {
                    addErrorMessage(process, node, errors, "Task has no outgoing connection.");
                }
            }
            if (workItemNode.getWork() == null) {
                addErrorMessage(process, node, errors, "Task has no work specified.");
            } else {
                Work work = workItemNode.getWork();
                if (work.getName() == null || work.getName().trim().length() == 0) {
                    addErrorMessage(process, node, errors, "Task has no task type.");
                }
            }
            if (workItemNode.getTimers() != null) {
                for (Timer timer : workItemNode.getTimers().keySet()) {
                    validateTimer(timer, node, process, errors);
                }
            }
        } else if (node instanceof ForEachNode) {
            final ForEachNode forEachNode = (ForEachNode) node;
            String variableName = forEachNode.getVariableName();
            if (variableName == null || "".equals(variableName)) {
                addErrorMessage(process, node, errors, "ForEach has no variable name");
            }
            String collectionExpression = forEachNode.getCollectionExpression();
            if (collectionExpression == null || "".equals(collectionExpression)) {
                addErrorMessage(process, node, errors, "ForEach has no collection expression");
            }
            if (forEachNode.getDefaultIncomingConnections().size() == 0 && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "ForEach has no incoming connection");
            }
            if (forEachNode.getDefaultOutgoingConnections().size() == 0 && !acceptsNoOutgoingConnections(node)) {
                addErrorMessage(process, node, errors, "ForEach has no outgoing connection");
            }
            // TODO: check, if no linked connections, for start and end node(s)
            // if (forEachNode.getLinkedIncomingNode(org.drools.workflow.core.Node.CONNECTION_DEFAULT_TYPE) == null) {
            // errors.add(new ProcessValidationErrorImpl(process,
            // "ForEach node '%s' [%d] has no linked start node"));
            // }
            // if (forEachNode.getLinkedOutgoingNode(org.drools.workflow.core.Node.CONNECTION_DEFAULT_TYPE) == null) {
            // errors.add(new ProcessValidationErrorImpl(process,
            // "ForEach node '%s' [%d] has no linked end node"));
            // }
            validateNodes(forEachNode.getNodes(), errors, process);
        } else if (node instanceof DynamicNode) {
            final DynamicNode dynamicNode = (DynamicNode) node;
            if (dynamicNode.getDefaultIncomingConnections().size() == 0 && !acceptsNoIncomingConnections(dynamicNode)) {
                addErrorMessage(process, node, errors, "Dynamic has no incoming connection");
            }
            if (dynamicNode.getDefaultOutgoingConnections().size() == 0 && !acceptsNoOutgoingConnections(dynamicNode)) {
                addErrorMessage(process, node, errors, "Dynamic has no outgoing connection");
            }
            if ("".equals(dynamicNode.getCompletionExpression()) && !dynamicNode.isAutoComplete()) {
                addErrorMessage(process, node, errors, "Dynamic has no completion condition set");
            }
            validateNodes(dynamicNode.getNodes(), errors, process);
        } else if (node instanceof CompositeNode) {
            final CompositeNode compositeNode = (CompositeNode) node;
            for (Map.Entry<String, NodeAndType> inType : compositeNode.getLinkedIncomingNodes().entrySet()) {
                if (compositeNode.getIncomingConnections(inType.getKey()).size() == 0 && !acceptsNoIncomingConnections(node)) {
                    addErrorMessage(process, node, errors, "Composite has no incoming connection for type " + inType.getKey());
                }
                if (inType.getValue().getNode() == null && !acceptsNoOutgoingConnections(node)) {
                    addErrorMessage(process, node, errors, "Composite has invalid linked incoming node for type " + inType.getKey());
                }
            }
            for (Map.Entry<String, NodeAndType> outType : compositeNode.getLinkedOutgoingNodes().entrySet()) {
                if (compositeNode.getOutgoingConnections(outType.getKey()).size() == 0) {
                    addErrorMessage(process, node, errors, "Composite has no outgoing connection for type " + outType.getKey());
                }
                if (outType.getValue().getNode() == null) {
                    addErrorMessage(process, node, errors, "Composite has invalid linked outgoing node for type " + outType.getKey());
                }
            }
            if (compositeNode instanceof EventSubProcessNode) {
                if (compositeNode.getIncomingConnections().size() > 0) {
                    addErrorMessage(process, node, errors, "Event subprocess is not allowed to have any incoming connections.");
                }
                if (compositeNode.getOutgoingConnections().size() > 0) {
                    addErrorMessage(process, node, errors, "Event subprocess is not allowed to have any outgoing connections.");
                }
                Node[] eventSubProcessNodes = compositeNode.getNodes();
                int startEventCount = 0;
                for (int j = 0; j < eventSubProcessNodes.length; ++j) {
                    if (eventSubProcessNodes[j] instanceof StartNode) {
                        StartNode startNode = (StartNode) eventSubProcessNodes[j];
                        if (++startEventCount == 2) {
                            addErrorMessage(process, compositeNode, errors, "Event subprocess is not allowed to have more than one start node.");
                        }
                        if (startNode.getTriggers() == null || startNode.getTriggers().isEmpty()) {
                            addErrorMessage(process, startNode, errors, "Start in Event SubProcess '" + compositeNode.getName() + "' [" + compositeNode.getId() + "] must contain a trigger (event definition).");
                        }
                    }
                }
            } else {
                Boolean isForCompensationObject = (Boolean) compositeNode.getMetaData("isForCompensation");
                if (compositeNode.getIncomingConnections().size() == 0 && !Boolean.TRUE.equals(isForCompensationObject)) {
                    addErrorMessage(process, node, errors, "Embedded subprocess does not have incoming connection.");
                }
                if (compositeNode.getOutgoingConnections().size() == 0 && !Boolean.TRUE.equals(isForCompensationObject)) {
                    addErrorMessage(process, node, errors, "Embedded subprocess does not have outgoing connection.");
                }
            }
            if (compositeNode.getTimers() != null) {
                for (Timer timer : compositeNode.getTimers().keySet()) {
                    validateTimer(timer, node, process, errors);
                }
            }
            validateNodes(compositeNode.getNodes(), errors, process);
        } else if (node instanceof EventNode) {
            final EventNode eventNode = (EventNode) node;
            if (eventNode.getEventFilters().size() == 0) {
                addErrorMessage(process, node, errors, "Event should specify an event type");
            }
            if (eventNode.getDefaultOutgoingConnections().size() == 0) {
                addErrorMessage(process, node, errors, "Event has no outgoing connection");
            } else {
                List<EventFilter> eventFilters = eventNode.getEventFilters();
                boolean compensationHandler = false;
                for (EventFilter eventFilter : eventFilters) {
                    if (((EventTypeFilter) eventFilter).getType().startsWith("Compensation")) {
                        compensationHandler = true;
                        break;
                    }
                }
                if (compensationHandler && eventNode instanceof BoundaryEventNode) {
                    Connection connection = eventNode.getDefaultOutgoingConnections().get(0);
                    Boolean isAssociation = (Boolean) connection.getMetaData().get("association");
                    if (isAssociation == null) {
                        isAssociation = false;
                    }
                    if (!(eventNode.getDefaultOutgoingConnections().size() == 1 && connection != null && isAssociation)) {
                        addErrorMessage(process, node, errors, "Compensation Boundary Event is only allowed to have 1 association to 1 compensation activity.");
                    }
                }
            }
        } else if (node instanceof FaultNode) {
            final FaultNode faultNode = (FaultNode) node;
            if (faultNode.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "Fault has no incoming connection.");
            }
            if (faultNode.getFaultName() == null) {
                addErrorMessage(process, node, errors, "Fault has no fault name.");
            }
        } else if (node instanceof TimerNode) {
            TimerNode timerNode = (TimerNode) node;
            if (timerNode.getFrom() == null && !acceptsNoIncomingConnections(node)) {
                addErrorMessage(process, node, errors, "Timer has no incoming connection.");
            }
            if (timerNode.getTo() == null && !acceptsNoOutgoingConnections(node)) {
                addErrorMessage(process, node, errors, "Timer has no outgoing connection.");
            }
            if (timerNode.getTimer() == null) {
                addErrorMessage(process, node, errors, "Timer has no timer specified.");
            } else {
                validateTimer(timerNode.getTimer(), node, process, errors);
            }
        } else if (node instanceof CatchLinkNode) {
        // catchlink validation here, there also are validations in
        // ProcessHandler regarding connection issues
        } else if (node instanceof ThrowLinkNode) {
        // throw validation here, there also are validations in
        // ProcessHandler regarding connection issues
        } else {
            errors.add(new ProcessValidationErrorImpl(process, "Unknown node type '" + node.getClass().getName() + "'"));
        }
    }
}
Also used : DroolsConsequenceAction(org.jbpm.workflow.core.impl.DroolsConsequenceAction) NodeAndType(org.jbpm.workflow.core.node.CompositeNode.NodeAndType) RuleSetNode(org.jbpm.workflow.core.node.RuleSetNode) EventSubProcessNode(org.jbpm.workflow.core.node.EventSubProcessNode) ForEachNode(org.jbpm.workflow.core.node.ForEachNode) BoundaryEventNode(org.jbpm.workflow.core.node.BoundaryEventNode) DynamicNode(org.jbpm.workflow.core.node.DynamicNode) StartNode(org.jbpm.workflow.core.node.StartNode) CompositeNode(org.jbpm.workflow.core.node.CompositeNode) StateNode(org.jbpm.workflow.core.node.StateNode) RuleSetNode(org.jbpm.workflow.core.node.RuleSetNode) SubProcessNode(org.jbpm.workflow.core.node.SubProcessNode) CatchLinkNode(org.jbpm.workflow.core.node.CatchLinkNode) ForEachJoinNode(org.jbpm.workflow.core.node.ForEachNode.ForEachJoinNode) MilestoneNode(org.jbpm.workflow.core.node.MilestoneNode) ThrowLinkNode(org.jbpm.workflow.core.node.ThrowLinkNode) EventSubProcessNode(org.jbpm.workflow.core.node.EventSubProcessNode) TimerNode(org.jbpm.workflow.core.node.TimerNode) FaultNode(org.jbpm.workflow.core.node.FaultNode) WorkItemNode(org.jbpm.workflow.core.node.WorkItemNode) ActionNode(org.jbpm.workflow.core.node.ActionNode) EndNode(org.jbpm.workflow.core.node.EndNode) EventNode(org.jbpm.workflow.core.node.EventNode) Node(org.kie.api.definition.process.Node) ForEachSplitNode(org.jbpm.workflow.core.node.ForEachNode.ForEachSplitNode) StateNode(org.jbpm.workflow.core.node.StateNode) ActionNode(org.jbpm.workflow.core.node.ActionNode) MilestoneNode(org.jbpm.workflow.core.node.MilestoneNode) ErrorDetail(org.mvel2.ErrorDetail) BoundaryEventNode(org.jbpm.workflow.core.node.BoundaryEventNode) EventNode(org.jbpm.workflow.core.node.EventNode) EventTypeFilter(org.jbpm.process.core.event.EventTypeFilter) SubProcessNode(org.jbpm.workflow.core.node.SubProcessNode) EventSubProcessNode(org.jbpm.workflow.core.node.EventSubProcessNode) Iterator(java.util.Iterator) WorkItemNode(org.jbpm.workflow.core.node.WorkItemNode) Work(org.jbpm.process.core.Work) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) TimerNode(org.jbpm.workflow.core.node.TimerNode) StartNode(org.jbpm.workflow.core.node.StartNode) CatchLinkNode(org.jbpm.workflow.core.node.CatchLinkNode) Connection(org.kie.api.definition.process.Connection) Join(org.jbpm.workflow.core.node.Join) BoundaryEventNode(org.jbpm.workflow.core.node.BoundaryEventNode) ThrowLinkNode(org.jbpm.workflow.core.node.ThrowLinkNode) EventFilter(org.jbpm.process.core.event.EventFilter) FaultNode(org.jbpm.workflow.core.node.FaultNode) CompositeNode(org.jbpm.workflow.core.node.CompositeNode) EndNode(org.jbpm.workflow.core.node.EndNode) Timer(org.jbpm.process.core.timer.Timer) ProcessValidationErrorImpl(org.jbpm.process.core.validation.impl.ProcessValidationErrorImpl) ExpressionCompiler(org.mvel2.compiler.ExpressionCompiler) ForEachNode(org.jbpm.workflow.core.node.ForEachNode) DynamicNode(org.jbpm.workflow.core.node.DynamicNode) Split(org.jbpm.workflow.core.node.Split) ParserContext(org.mvel2.ParserContext) Map(java.util.Map) HashMap(java.util.HashMap)

Example 27 with And

use of org.mvel2.ast.And in project mvel by mikebrock.

the class AbstractParser method procTypedNode.

/**
 * Process the current typed node
 *
 * @param decl node is a declaration or not
 * @return and ast node
 */
private ASTNode procTypedNode(boolean decl) {
    while (true) {
        if (lastNode.getLiteralValue() instanceof String) {
            char[] tmp = ((String) lastNode.getLiteralValue()).toCharArray();
            TypeDescriptor tDescr = new TypeDescriptor(tmp, 0, tmp.length, 0);
            try {
                lastNode.setLiteralValue(getClassReference(pCtx, tDescr));
                lastNode.discard();
            } catch (Exception e) {
            // fall through;
            }
        }
        if (lastNode.isLiteral() && lastNode.getLiteralValue() instanceof Class) {
            lastNode.discard();
            captureToEOS();
            if (decl) {
                splitAccumulator.add(new DeclTypedVarNode(new String(expr, st, cursor - st), expr, st, cursor - st, (Class) lastNode.getLiteralValue(), fields | ASTNode.ASSIGN, pCtx));
            } else {
                captureToEOS();
                splitAccumulator.add(new TypedVarNode(expr, st, cursor - st - 1, fields | ASTNode.ASSIGN, (Class) lastNode.getLiteralValue(), pCtx));
            }
        } else if (lastNode instanceof Proto) {
            captureToEOS();
            if (decl) {
                splitAccumulator.add(new DeclProtoVarNode(new String(expr, st, cursor - st), (Proto) lastNode, fields | ASTNode.ASSIGN, pCtx));
            } else {
                splitAccumulator.add(new ProtoVarNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, (Proto) lastNode, pCtx));
            }
        } else // this redundant looking code is needed to work with the interpreter and MVELSH properly.
        if ((fields & ASTNode.COMPILE_IMMEDIATE) == 0) {
            if (stk.peek() instanceof Class) {
                captureToEOS();
                if (decl) {
                    splitAccumulator.add(new DeclTypedVarNode(new String(expr, st, cursor - st), expr, st, cursor - st, (Class) stk.pop(), fields | ASTNode.ASSIGN, pCtx));
                } else {
                    splitAccumulator.add(new TypedVarNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, (Class) stk.pop(), pCtx));
                }
            } else if (stk.peek() instanceof Proto) {
                captureToEOS();
                if (decl) {
                    splitAccumulator.add(new DeclProtoVarNode(new String(expr, st, cursor - st), (Proto) stk.pop(), fields | ASTNode.ASSIGN, pCtx));
                } else {
                    splitAccumulator.add(new ProtoVarNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, (Proto) stk.pop(), pCtx));
                }
            } else {
                throw new CompileException("unknown class or illegal statement: " + lastNode.getLiteralValue(), expr, cursor);
            }
        } else {
            throw new CompileException("unknown class or illegal statement: " + lastNode.getLiteralValue(), expr, cursor);
        }
        skipWhitespace();
        if (cursor < end && expr[cursor] == ',') {
            st = ++cursor;
            splitAccumulator.add(new EndOfStatement());
        } else {
            return (ASTNode) splitAccumulator.pop();
        }
    }
}
Also used : CompileException(org.mvel2.CompileException) CompileException(org.mvel2.CompileException)

Example 28 with And

use of org.mvel2.ast.And in project mvel by mikebrock.

the class AbstractParser method arithmeticFunctionReduction.

/**
 * Reduce the current operations on the stack.
 *
 * @param operator the operator
 * @return a stack control code
 */
protected int arithmeticFunctionReduction(int operator) {
    ASTNode tk;
    int operator2;
    /**
     * If the next token is an operator, we check to see if it has a higher
     * precdence.
     */
    if ((tk = nextToken()) != null) {
        if (isArithmeticOperator(operator2 = tk.getOperator()) && PTABLE[operator2] > PTABLE[operator]) {
            stk.xswap();
            /**
             * The current arith. operator is of higher precedence the last.
             */
            tk = nextToken();
            /**
             * Check to see if we're compiling or executing interpretively.  If we're compiling, we really
             * need to stop if this is not a literal.
             */
            if (compileMode && !tk.isLiteral()) {
                splitAccumulator.push(tk, new OperatorNode(operator2, expr, st));
                return OP_OVERFLOW;
            }
            dStack.push(operator = operator2, tk.getReducedValue(ctx, ctx, variableFactory));
            while (true) {
                // look ahead again
                if ((tk = nextToken()) != null && (operator2 = tk.getOperator()) != -1 && operator2 != 37 && PTABLE[operator2] > PTABLE[operator]) {
                    if (dStack.isReduceable()) {
                        stk.copyx2(dStack);
                    }
                    /**
                     * This operator is of higher precedence, or the same level precedence.  push to the RHS.
                     */
                    dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));
                    continue;
                } else if (tk != null && operator2 != -1 && operator2 != 37) {
                    if (PTABLE[operator2] == PTABLE[operator]) {
                        if (!dStack.isEmpty())
                            dreduce();
                        else {
                            while (stk.isReduceable()) {
                                stk.xswap_op();
                            }
                        }
                        /**
                         * This operator is of the same level precedence.  push to the RHS.
                         */
                        dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));
                        continue;
                    } else {
                        /**
                         * The operator doesn't have higher precedence. Therfore reduce the LHS.
                         */
                        while (dStack.size() > 1) {
                            dreduce();
                        }
                        operator = tk.getOperator();
                        // Reduce the lesser or equal precedence operations.
                        while (stk.size() != 1 && stk.peek2() instanceof Integer && ((operator2 = (Integer) stk.peek2()) < PTABLE.length) && PTABLE[operator2] >= PTABLE[operator]) {
                            stk.xswap_op();
                        }
                    }
                } else {
                    if (dStack.size() > 1) {
                        dreduce();
                    }
                    if (stk.isReduceable())
                        stk.xswap();
                    break;
                }
                if ((tk = nextToken()) != null) {
                    switch(operator) {
                        case AND:
                            {
                                if (!(stk.peekBoolean()))
                                    return OP_TERMINATE;
                                else {
                                    splitAccumulator.add(tk);
                                    return AND;
                                }
                            }
                        case OR:
                            {
                                if ((stk.peekBoolean()))
                                    return OP_TERMINATE;
                                else {
                                    splitAccumulator.add(tk);
                                    return OR;
                                }
                            }
                        default:
                            stk.push(operator, tk.getReducedValue(ctx, ctx, variableFactory));
                    }
                }
            }
        } else if (!tk.isOperator()) {
            throw new CompileException("unexpected token: " + tk.getName(), expr, st);
        } else {
            reduce();
            splitAccumulator.push(tk);
        }
    }
    // keep XSWAPing and reducing, until there is nothing left.
    if (stk.isReduceable()) {
        while (true) {
            reduce();
            if (stk.isReduceable()) {
                stk.xswap();
            } else {
                break;
            }
        }
    }
    return OP_RESET_FRAME;
}
Also used : CompileException(org.mvel2.CompileException)

Example 29 with And

use of org.mvel2.ast.And in project mvel by mikebrock.

the class AbstractParser method reduce.

/**
 * This method is called when we reach the point where we must subEval a trinary operation in the expression.
 * (ie. val1 op val2).  This is not the same as a binary operation, although binary operations would appear
 * to have 3 structures as well.  A binary structure (or also a junction in the expression) compares the
 * current state against 2 downrange structures (usually an op and a val).
 */
protected void reduce() {
    Object v1, v2;
    int operator;
    try {
        switch(operator = (Integer) stk.pop()) {
            case ADD:
            case SUB:
            case DIV:
            case MULT:
            case MOD:
            case EQUAL:
            case NEQUAL:
            case GTHAN:
            case LTHAN:
            case GETHAN:
            case LETHAN:
            case POWER:
                stk.op(operator);
                break;
            case AND:
                v1 = stk.pop();
                stk.push(((Boolean) stk.pop()) && ((Boolean) v1));
                break;
            case OR:
                v1 = stk.pop();
                stk.push(((Boolean) stk.pop()) || ((Boolean) v1));
                break;
            case CHOR:
                v1 = stk.pop();
                if (!isEmpty(v2 = stk.pop()) || !isEmpty(v1)) {
                    stk.clear();
                    stk.push(!isEmpty(v2) ? v2 : v1);
                    return;
                } else
                    stk.push(null);
                break;
            case REGEX:
                stk.push(java.util.regex.Pattern.compile(java.lang.String.valueOf(stk.pop())).matcher(java.lang.String.valueOf(stk.pop())).matches());
                break;
            case INSTANCEOF:
                stk.push(((Class) stk.pop()).isInstance(stk.pop()));
                break;
            case CONVERTABLE_TO:
                stk.push(org.mvel2.DataConversion.canConvert(stk.peek2().getClass(), (Class) stk.pop2()));
                break;
            case CONTAINS:
                stk.push(containsCheck(stk.peek2(), stk.pop2()));
                break;
            case BW_AND:
                stk.push(asInt(stk.peek2()) & asInt(stk.pop2()));
                break;
            case BW_OR:
                stk.push(asInt(stk.peek2()) | asInt(stk.pop2()));
                break;
            case BW_XOR:
                stk.push(asInt(stk.peek2()) ^ asInt(stk.pop2()));
                break;
            case BW_SHIFT_LEFT:
                stk.push(asInt(stk.peek2()) << asInt(stk.pop2()));
                break;
            case BW_USHIFT_LEFT:
                int iv2 = asInt(stk.peek2());
                if (iv2 < 0)
                    iv2 *= -1;
                stk.push(iv2 << asInt(stk.pop2()));
                break;
            case BW_SHIFT_RIGHT:
                stk.push(asInt(stk.peek2()) >> asInt(stk.pop2()));
                break;
            case BW_USHIFT_RIGHT:
                stk.push(asInt(stk.peek2()) >>> asInt(stk.pop2()));
                break;
            case SOUNDEX:
                stk.push(soundex(java.lang.String.valueOf(stk.pop())).equals(soundex(java.lang.String.valueOf(stk.pop()))));
                break;
            case SIMILARITY:
                stk.push(similarity(java.lang.String.valueOf(stk.pop()), java.lang.String.valueOf(stk.pop())));
                break;
        }
    } catch (ClassCastException e) {
        throw new CompileException("syntax error or incompatable types", expr, st, e);
    } catch (ArithmeticException e) {
        throw new CompileException("arithmetic error: " + e.getMessage(), expr, st, e);
    } catch (Exception e) {
        throw new CompileException("failed to subEval expression", expr, st, e);
    }
}
Also used : CompileException(org.mvel2.CompileException) CompileException(org.mvel2.CompileException)

Example 30 with And

use of org.mvel2.ast.And in project mvel by mikebrock.

the class MVELInterpretedRuntime method procBooleanOperator.

private int procBooleanOperator(int operator) {
    switch(operator) {
        case RETURN:
            return RETURN;
        case NOOP:
            return -2;
        case AND:
            reduceRight();
            if (!stk.peekBoolean()) {
                if (unwindStatement(operator)) {
                    return -1;
                } else {
                    stk.clear();
                    return OP_RESET_FRAME;
                }
            } else {
                stk.discard();
                return OP_RESET_FRAME;
            }
        case OR:
            reduceRight();
            if (stk.peekBoolean()) {
                if (unwindStatement(operator)) {
                    return OP_TERMINATE;
                } else {
                    stk.clear();
                    return OP_RESET_FRAME;
                }
            } else {
                stk.discard();
                return OP_RESET_FRAME;
            }
        case CHOR:
            if (!BlankLiteral.INSTANCE.equals(stk.peek())) {
                return OP_TERMINATE;
            }
            break;
        case TERNARY:
            if (!stk.popBoolean()) {
                stk.clear();
                ASTNode tk;
                for (; ; ) {
                    if ((tk = nextToken()) == null || tk.isOperator(Operator.TERNARY_ELSE))
                        break;
                }
            }
            return OP_RESET_FRAME;
        case TERNARY_ELSE:
            captureToEOS();
            return OP_RESET_FRAME;
        case END_OF_STMT:
            if (hasMore()) {
                holdOverRegister = stk.pop();
                stk.clear();
            }
            return OP_RESET_FRAME;
    }
    return OP_CONTINUE;
}
Also used : ASTNode(org.mvel2.ast.ASTNode)

Aggregations

CompileException (org.mvel2.CompileException)22 HashMap (java.util.HashMap)13 Map (java.util.Map)12 ParserContext (org.mvel2.ParserContext)12 ASTNode (org.mvel2.ast.ASTNode)9 Type (org.mvel2.asm.Type)8 Serializable (java.io.Serializable)7 Method (java.lang.reflect.Method)7 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)7 ExpressionCompiler (org.mvel2.compiler.ExpressionCompiler)7 StringAppender (org.mvel2.util.StringAppender)6 EndOfStatement (org.mvel2.ast.EndOfStatement)5 IOException (java.io.IOException)4 BitSet (java.util.BitSet)4 List (java.util.List)4 LabelNode (org.mvel2.asm.tree.LabelNode)4 LiteralNode (org.mvel2.ast.LiteralNode)4 Proto (org.mvel2.ast.Proto)4 ArrayList (java.util.ArrayList)3 Money (org.broadleafcommerce.common.money.Money)3