Package com.lewisd.maven.lint.rules

Source Code of com.lewisd.maven.lint.rules.AbstractReduntantVersionRule

package com.lewisd.maven.lint.rules;

import com.lewisd.maven.lint.ResultCollector;
import com.lewisd.maven.lint.model.Coordinates;
import com.lewisd.maven.lint.model.ObjectWithPath;
import com.lewisd.maven.lint.util.ExpressionEvaluator;
import com.lewisd.maven.lint.util.ModelUtil;
import org.apache.log4j.Logger;
import org.apache.maven.model.InputLocation;
import org.apache.maven.model.Model;
import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public abstract class AbstractReduntantVersionRule extends AbstractRule {

    private final Logger log = Logger.getLogger(this.getClass());

    private final Set<Coordinates> excludedCoordinates = new HashSet<Coordinates>();
    private final PluginParameterExpressionEvaluator pluginParameterExpressionEvaluator;

    public AbstractReduntantVersionRule(ExpressionEvaluator expressionEvaluator,
                                        ModelUtil modelUtil,
                                        PluginParameterExpressionEvaluator pluginParameterExpressionEvaluator) {
        super(expressionEvaluator, modelUtil);
        this.pluginParameterExpressionEvaluator = pluginParameterExpressionEvaluator;
    }

    protected void checkForRedundantVersions(final MavenProject mavenProject,
                                             final ResultCollector resultCollector,
                                             final ObjectWithPath<? extends Object> object,
                                             final ObjectWithPath<? extends Object> inheritedObject,
                                             final String dependencyDescription,
                                             final String inheritedDescription) {

        Object modelObject = object.getObject();
        Object resolvedModelObject = tryResolveObject(object);

        if (isExcluded(resolvedModelObject)) {
            return;
        }

        String version = resolveVersion(modelObject, resolvedModelObject);
        String inheritedVersion = modelUtil.getVersion(tryResolveObject(inheritedObject));
        // both have a version, but if they're different, that might be ok.
        // But if they're the same, then one is redundant.
        if (version != null && inheritedVersion != null && inheritedVersion.equals(version)) {
            InputLocation location = modelUtil.getLocation(modelObject, "version");
            String message = dependencyDescription + " '" + modelUtil.getKey(modelObject) + "' has same version (" + version + ") as " + inheritedDescription;
            resultCollector.addViolation(mavenProject, this, message, location);
        }
    }

    private String resolveVersion(final Object modelObject, final Object resolvedModelObject) {
        final String version = modelUtil.getVersion(modelObject);
        if (version != null && version.contains("${")) {
            return modelUtil.getVersion(resolvedModelObject);
        }
        return version;
    }

    public void setExcludedCoordinates(final Set<String> coordinates) {
        excludedCoordinates.clear();
        for (final String coordinate : coordinates) {
            excludedCoordinates.add(Coordinates.parse(coordinate));
        }
    }

    private boolean isExcluded(final Object modelObject) {
        final Coordinates coords = modelUtil.getCoordinates(modelObject);
        for (final Coordinates excludedCoordinate : excludedCoordinates) {
            if (excludedCoordinate.matches(coords)) {
                return true;
            }
        }
        return false;
    }

    private Object tryResolveObject(final ObjectWithPath<? extends Object> objectWithPath) {
        try {
            return resolveObject(objectWithPath);
        } catch (final IllegalStateException e) {
            log.warn(e);
            return objectWithPath.getObject();
        }
    }

    /**
     * This uses the path of an object that was found in the "original model", and tries to find
     * the same object in the "model".  The "model" has had properties replaced with values, so
     * this is how we find the resolved version of the object.
     */
    private Object resolveObject(final ObjectWithPath<? extends Object> objectWithPath) {
        Object object = objectWithPath.getObject();
        StringBuilder path = new StringBuilder();
        path.append(objectWithPath.getPath());
        path.append("[");
        path.append("groupId='").append(modelUtil.getGroupId(object)).append("'");
        path.append(" and artifactId='").append(modelUtil.getArtifactId(object)).append("'");

        String type = modelUtil.tryGetType(object);
        if (type != null) {
            path.append(" and type='").append(type).append("'");
        }

        String classifier = modelUtil.tryGetClassifier(object);
        if (classifier != null) {
            path.append(" and classifier='").append(classifier).append("'");
        }
        path.append("]");

        // evaluate embedded properties
        if (path.toString().contains("${")) {
            try {
                Object evaluate = pluginParameterExpressionEvaluator.evaluate(path.toString());
                path = new StringBuilder(evaluate.toString());
            } catch (ExpressionEvaluationException e) {
                throw new IllegalStateException(e);
            }
        }

        Model model = objectWithPath.getProject().getModel();
        Collection<Object> objects = expressionEvaluator.getPath(model, path.toString());
        if (objects.isEmpty()) {
            throw new IllegalStateException("Could not resolve " + object + " using path " + path);
        } else if (objects.size() > 1) {
            throw new IllegalStateException("Found " + objects.size() + " objects using path " + path);
        } else {
            return objects.iterator().next();
        }

    }

}
TOP

Related Classes of com.lewisd.maven.lint.rules.AbstractReduntantVersionRule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.