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

com.paypal.butterfly.utilities.conditions.java.JavaMatch Maven / Gradle / Ivy

There is a newer version: 3.2.7
Show newest version
package com.paypal.butterfly.utilities.conditions.java;

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.paypal.butterfly.extensions.api.SingleCondition;
import com.paypal.butterfly.extensions.api.TUExecutionResult;
import com.paypal.butterfly.extensions.api.TransformationContext;
import com.paypal.butterfly.extensions.api.exception.TransformationUtilityException;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * Parses and evaluates the specified Java class file
 * based on a set of {@link JavaCondition}. It returns true only
 * if they all are true. If the specified Java class file contains
 * more than one type, only the outer one will be considered
 * during evaluation. If it has none, the evaluation will result
 * in false and a warning be returned.
 * If the Java class file is named package-info.java, the file content
 * will not be evaluated and false and a warning will be returned.
 * The boolean result for package-info.java file is configurable though.
 *
 * @author facarvalho
 */
public class JavaMatch extends SingleCondition {

    private static final String DESCRIPTION = "Check if Java class in '%s' matches all specified criteria";

    private Set conditions = new HashSet<>();

    private boolean packageInfo;

    /**
     * This utility parses and evaluates the specified Java class file
     * based on a set of {@link JavaCondition}. It returns true only
     * if they all are true. If the specified Java class file contains
     * more than one type, only the outer one will be considered
     * during evaluation. If it has none, the evaluation will result
     * in false and a warning be returned.
     */
    public JavaMatch() {}

    /**
     * This utility parses and evaluates the specified Java class file
     * based on a set of {@link JavaCondition}. It returns true only
     * if they all are true. If the specified Java class file contains
     * more than one type, only the outer one will be considered
     * during evaluation. If it has none, the evaluation will result
     * in false and a warning be returned.
     *
     * @param condition one condition to be evaluated. More can be added with
     *                  {@link #addCondition(JavaCondition)}
     */
    public JavaMatch(JavaCondition condition) {
        addCondition(condition);
    }

    /**
     * Returns the set of Java conditions to be used to
     * evaluate the specified class. The returned object
     * is not a copy and it is modifiable.
     *
     * @return the set of Java conditions to be used to evaluate the specified class
     */
    public Set getConditions() {
        return conditions;
    }

    /**
     * Sets the set of Java conditions to be used to
     * evaluate the specified class. Any conditions
     * added previously will be discarded.
     *
     * @param conditions the set of Java conditions to be used to evaluate the specified class
     * @return this transformation utility condition instance
     */
    public JavaMatch setConditions(Set conditions) {
        checkForNull("conditions", conditions);
        this.conditions = conditions;
        return this;
    }

    /**
     * Returns the current boolean status of packageInfo.
     *
     * @return this packageInfo boolean status
     */
    public boolean getPackageInfo() {
        return this.packageInfo;
    }

    /**
     * Sets the result value for package info warning.
     * By default the result for package-info.java
     * file will be false.
     *
     * @param packageInfo boolean status of value for packageInfo warning
     * @return this transformation utility condition instance
     */
    public JavaMatch setPackageInfo(boolean packageInfo) {
        this.packageInfo = packageInfo;
        return this;
    }

    /**
     * Add a new Java condition to be evaluated against the Java class.
     *
     * @param condition a Java condition to be used to evaluate the specified class
     * @return this transformation utility condition instance
     */
    public JavaMatch addCondition(JavaCondition condition) {
        checkForNull("condition", condition);
        conditions.add(condition);
        return this;
    }

    @Override
    public String getDescription() {
        return String.format(DESCRIPTION, getRelativePath());
    }

    @Override
    protected TUExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
        File javaClassFile = getAbsoluteFile(transformedAppFolder, transformationContext);
        FileInputStream fileInputStream = null;
        TUExecutionResult result = null;

        try {
            fileInputStream = new FileInputStream(javaClassFile);
            CompilationUnit compilationUnit = StaticJavaParser.parse(fileInputStream);

            if (javaClassFile.getName().equals("package-info.java")) {
                return TUExecutionResult.warning(this, new TransformationUtilityException("Skipping execution for " + javaClassFile.getAbsolutePath() + ". This is a package-info.java file."), this.packageInfo);
            }

            // TODO
            // This should be done as part of validation, as soon as
            // TU validation is implemented
            if(compilationUnit.getTypes().size() == 0) {
                return TUExecutionResult.warning(this, new TransformationUtilityException("This Java class file has no declared types: " + javaClassFile.getAbsolutePath()), false);
            }

            boolean match = evaluate(compilationUnit);
            result = TUExecutionResult.value(this, match);
        } catch (Exception e) {
            result = TUExecutionResult.error(this, e);
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException e) {
                if (result == null) {
                    result = TUExecutionResult.error(this, e);
                } else {
                    result.addWarning(e);
                }
            }
        }

        return result;
    }

    /*
     * Evaluates all conditions against the specified Java class
     * and returns true only if all of them are true
     */
    private boolean evaluate(CompilationUnit compilationUnit) {
        for (JavaCondition condition : conditions) {
            if (!condition.evaluate(compilationUnit)) return false;
        }
        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy