All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drools.mvel.parser.printer.ConstraintPrintVisitor Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2019 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *
 */

package org.drools.mvel.parser.printer;

import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.printer.PrettyPrintVisitor;
import com.github.javaparser.printer.PrettyPrinterConfiguration;
import org.drools.mvel.parser.ast.expr.BigDecimalLiteralExpr;
import org.drools.mvel.parser.ast.expr.BigIntegerLiteralExpr;
import org.drools.mvel.parser.ast.expr.DrlNameExpr;
import org.drools.mvel.parser.ast.expr.DrlxExpression;
import org.drools.mvel.parser.ast.expr.HalfBinaryExpr;
import org.drools.mvel.parser.ast.expr.HalfPointFreeExpr;
import org.drools.mvel.parser.ast.expr.InlineCastExpr;
import org.drools.mvel.parser.ast.expr.MapCreationLiteralExpression;
import org.drools.mvel.parser.ast.expr.MapCreationLiteralExpressionKeyValuePair;
import org.drools.mvel.parser.ast.expr.ModifyStatement;
import org.drools.mvel.parser.ast.expr.NullSafeFieldAccessExpr;
import org.drools.mvel.parser.ast.expr.NullSafeMethodCallExpr;
import org.drools.mvel.parser.ast.expr.OOPathChunk;
import org.drools.mvel.parser.ast.expr.OOPathExpr;
import org.drools.mvel.parser.ast.expr.PointFreeExpr;
import org.drools.mvel.parser.ast.expr.RuleBody;
import org.drools.mvel.parser.ast.expr.RuleDeclaration;
import org.drools.mvel.parser.ast.expr.TemporalChunkExpr;
import org.drools.mvel.parser.ast.expr.TemporalLiteralChunkExpr;
import org.drools.mvel.parser.ast.expr.TemporalLiteralExpr;
import org.drools.mvel.parser.ast.expr.TemporalLiteralInfiniteChunkExpr;
import org.drools.mvel.parser.ast.expr.WithStatement;
import org.drools.mvel.parser.ast.visitor.DrlVoidVisitor;

import static com.github.javaparser.utils.Utils.isNullOrEmpty;
import static org.drools.mvel.parser.printer.PrintUtil.printConstraint;

public class ConstraintPrintVisitor extends PrettyPrintVisitor implements DrlVoidVisitor {

    public ConstraintPrintVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) {
        super(prettyPrinterConfiguration);
    }

    @Override
    public void visit( RuleDeclaration n, Void arg ) {
        printComment(n.getComment(), arg);

        for (AnnotationExpr ae : n.getAnnotations()) {
            ae.accept(this, arg);
            printer.print(" ");
        }

        printer.print("rule ");
        n.getName().accept(this, arg);
        printer.println(" {");
        n.getRuleBody().accept(this, arg);
        printer.println("}");
    }

    @Override
    public void visit( RuleBody ruleBody, Void arg ) {
    }

    @Override
    public void visit( InlineCastExpr inlineCastExpr, Void arg ) {
        printComment(inlineCastExpr.getComment(), arg);
        inlineCastExpr.getExpression().accept( this, arg );
        printer.print( "#" );
        inlineCastExpr.getType().accept( this, arg );
    }

    @Override
    public void visit( NullSafeFieldAccessExpr nullSafeFieldAccessExpr, Void arg ) {
        printComment(nullSafeFieldAccessExpr.getComment(), arg);
        nullSafeFieldAccessExpr.getScope().accept( this, arg );
        printer.print( "!." );
        nullSafeFieldAccessExpr.getName().accept( this, arg );
    }

    @Override
    public void visit( NullSafeMethodCallExpr nullSafeMethodCallExpr, Void arg ) {
        printComment(nullSafeMethodCallExpr.getComment(), arg);
        Optional scopeExpression = nullSafeMethodCallExpr.getScope();
        if (scopeExpression.isPresent()) {
            scopeExpression.get().accept( this, arg );
            printer.print("!.");
        }
        printTypeArgs(nullSafeMethodCallExpr, arg);
        nullSafeMethodCallExpr.getName().accept( this, arg );
        printArguments(nullSafeMethodCallExpr.getArguments(), arg);
    }

    @Override
    public void visit( PointFreeExpr pointFreeExpr, Void arg ) {
        printComment(pointFreeExpr.getComment(), arg);
        pointFreeExpr.getLeft().accept( this, arg );
        if(pointFreeExpr.isNegated()) {
            printer.print(" not");
        }
        printer.print(" ");
        pointFreeExpr.getOperator().accept( this, arg );
        if (pointFreeExpr.getArg1() != null) {
            printer.print("[");
            pointFreeExpr.getArg1().accept( this, arg );
            if (pointFreeExpr.getArg2() != null) {
                printer.print(",");
                pointFreeExpr.getArg2().accept( this, arg );
            }
            if (pointFreeExpr.getArg3() != null) {
                printer.print(",");
                pointFreeExpr.getArg3().accept( this, arg );
            }
            if (pointFreeExpr.getArg4() != null) {
                printer.print(",");
                pointFreeExpr.getArg4().accept( this, arg );
            }
            printer.print("]");
        }
        printer.print(" ");
        NodeList rightExprs = pointFreeExpr.getRight();
        if (rightExprs.size() == 1) {
            rightExprs.get(0).accept( this, arg );
        } else {
            printer.print("(");
            if(rightExprs.isNonEmpty()) {
                rightExprs.get(0).accept(this, arg);
            }
            for (int i = 1; i < rightExprs.size(); i++) {
                printer.print(", ");
                rightExprs.get(i).accept( this, arg );
            }
            printer.print(")");
        }
    }

    @Override
    public void visit(TemporalLiteralExpr temporalLiteralExpr, Void arg) {
        printComment(temporalLiteralExpr.getComment(), arg);
        NodeList chunks = temporalLiteralExpr.getChunks();
        for (TemporalChunkExpr c : chunks) {
            c.accept(this, arg);
        }
    }

    @Override
    public void visit(TemporalLiteralChunkExpr temporalLiteralExpr, Void arg) {
        printComment(temporalLiteralExpr.getComment(), arg);
        printer.print("" + temporalLiteralExpr.getValue());
        switch (temporalLiteralExpr.getTimeUnit()) {
            case MILLISECONDS:
                printer.print("ms");
                break;
            case SECONDS:
                printer.print("s");
                break;
            case MINUTES:
                printer.print("m");
                break;
            case HOURS:
                printer.print("h");
                break;
            case DAYS:
                printer.print("d");
                break;
        }
    }

    @Override
    public void visit(TemporalLiteralInfiniteChunkExpr temporalLiteralInfiniteChunkExpr, Void arg) {
        printer.print("*");
    }

    @Override
    public void visit( DrlxExpression expr, Void arg ) {
        if (expr.getBind() != null) {
            expr.getBind().accept( this, arg );
            printer.print( " : " );
        }
        expr.getExpr().accept(this, arg);
    }

    @Override
    public void visit(OOPathExpr oopathExpr, Void arg ) {
        printComment(oopathExpr.getComment(), arg);
        printer.print("/");
        NodeList chunks = oopathExpr.getChunks();
        for (int i = 0; i <  chunks.size(); i++) {
            final OOPathChunk chunk = chunks.get(i);
            chunk.accept(this, arg);
            printer.print(chunk.getField().toString());

            List condition = chunk.getConditions();
            final Iterator iterator = condition.iterator();
            if (!condition.isEmpty()) {
                printer.print("[");
                Expression first = iterator.next();
                first.accept(this, arg);
                while(iterator.hasNext()) {
                    printer.print(",");
                    iterator.next().accept(this, arg);
                }
                printer.print("]");
            }

            if(i != chunks.size() - 1) { // Avoid printing last /
                printer.print("/");
            }
        }
    }

    @Override
    public void visit(HalfBinaryExpr n, Void arg) {
        printComment(n.getComment(), arg);
        printer.print(n.getOperator().asString());
        printer.print(" ");
        n.getRight().accept(this, arg);
    }

    @Override
    public void visit(HalfPointFreeExpr pointFreeExpr, Void arg ) {
        printComment(pointFreeExpr.getComment(), arg);
        if(pointFreeExpr.isNegated()) {
            printer.print("not ");
        }
        pointFreeExpr.getOperator().accept( this, arg );
        if (pointFreeExpr.getArg1() != null) {
            printer.print("[");
            pointFreeExpr.getArg1().accept( this, arg );
            if (pointFreeExpr.getArg2() != null) {
                printer.print(",");
                pointFreeExpr.getArg2().accept( this, arg );
            }
            if (pointFreeExpr.getArg3() != null) {
                printer.print(",");
                pointFreeExpr.getArg3().accept( this, arg );
            }
            if (pointFreeExpr.getArg4() != null) {
                printer.print(",");
                pointFreeExpr.getArg4().accept( this, arg );
            }
            printer.print("]");
        }
        printer.print(" ");
        NodeList rightExprs = pointFreeExpr.getRight();
        if (rightExprs.size() == 1) {
            rightExprs.get(0).accept( this, arg );
        } else {
            printer.print("(");
            rightExprs.get(0).accept( this, arg );
            for (int i = 1; i < rightExprs.size(); i++) {
                printer.print(", ");
                rightExprs.get(i).accept( this, arg );
            }
            printer.print(")");
        }
    }

    @Override
    public void visit(BigDecimalLiteralExpr bigDecimalLiteralExpr, Void arg) {
        printer.print(bigDecimalLiteralExpr.asBigDecimal().toString());
        printer.print("B");
    }

    @Override
    public void visit(BigIntegerLiteralExpr bigIntegerLiteralExpr, Void arg) {
        printer.print(bigIntegerLiteralExpr.asBigInteger().toString());
        printer.print("I");
    }

    @Override
    public void visit(ModifyStatement modifyExpression, Void arg) {
        printer.print("modify (");
        modifyExpression.getModifyObject().accept(this, arg);
        printer.print(") { ");

        String expressionWithComma = modifyExpression.getExpressions()
                .stream()
                .filter(Objects::nonNull)
                .filter(Statement::isExpressionStmt)
                .map(n -> printConstraint(n.asExpressionStmt().getExpression()))
                .collect(Collectors.joining(", "));

        printer.print(expressionWithComma);
        printer.print(" }");

        printer.print(";");
    }

    @Override
    public void visit(WithStatement withExpression, Void arg) {
        printer.print("with (");
        withExpression.getWithObject().accept(this, arg);
        printer.print(") { ");

        String expressionWithComma = withExpression.getExpressions()
                .stream()
                .filter(Objects::nonNull)
                .filter(Statement::isExpressionStmt)
                .map(n -> printConstraint(n.asExpressionStmt().getExpression()))
                .collect(Collectors.joining(", "));

        printer.print(expressionWithComma);
        printer.print(" }");

        printer.print(";");
    }

    public void printComment(final Optional comment, final Void arg) {
        comment.ifPresent(c -> c.accept(this, arg));
    }


    public void printTypeArgs(final NodeWithTypeArguments nodeWithTypeArguments, final Void arg) {
        NodeList typeArguments = nodeWithTypeArguments.getTypeArguments().orElse(null);
        if (!isNullOrEmpty(typeArguments)) {
            printer.print("<");
            for (final Iterator i = typeArguments.iterator(); i.hasNext(); ) {
                final Type t = i.next();
                t.accept(this, arg);
                if (i.hasNext()) {
                    printer.print(", ");
                }
            }
            printer.print(">");
        }
    }


    public void printArguments(final NodeList args, final Void arg) {
        printer.print("(");
        if (!isNullOrEmpty(args)) {
            boolean columnAlignParameters = (args.size() > 1) && configuration.isColumnAlignParameters();
            if (columnAlignParameters) {
                printer.indentWithAlignTo(printer.getCursor().column);
            }
            for (final Iterator i = args.iterator(); i.hasNext(); ) {
                final Expression e = i.next();
                e.accept(this, arg);
                if (i.hasNext()) {
                    printer.print(",");
                    if (columnAlignParameters) {
                        printer.println();
                    } else {
                        printer.print(" ");
                    }
                }
            }
            if (columnAlignParameters) {
                printer.unindent();
            }
        }
        printer.print(")");
    }

    @Override
    public void visit(DrlNameExpr n, Void arg) {
        printComment(n.getComment(), arg);
        java.util.stream.IntStream.range(0, n.getBackReferencesCount()).forEach(s -> printer.print("../"));
        n.getName().accept(this, arg);
    }

    @Override
    public void visit(MapCreationLiteralExpression n, Void arg) {
        printer.print("[");

        Iterator expressions = n.getExpressions().iterator();
        while(expressions.hasNext()) {
            expressions.next().accept(this, arg);
            if(expressions.hasNext()) {
                printer.print(", ");
            }
        }
        printer.print("]");
    }

    @Override
    public void visit(MapCreationLiteralExpressionKeyValuePair n, Void arg) {
        n.getKey().accept(this, arg);
        printer.print(" : ");
        n.getValue().accept(this, arg);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy