org.jenkinsci.plugins.pipeline.maven.eventspy.handler.AbstractMavenEventHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.jenkinsci.plugins.pipeline.maven.eventspy.handler.AbstractMavenEventHandler.java

Source

/*
 * The MIT License
 *
 * Copyright (c) 2016, CloudBees, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.jenkinsci.plugins.pipeline.maven.eventspy.handler;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.model.Build;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.jenkinsci.plugins.pipeline.maven.eventspy.RuntimeIOException;
import org.jenkinsci.plugins.pipeline.maven.eventspy.reporter.MavenEventReporter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * @author <a href="mailto:cleclerc@cloudbees.com">Cyrille Le Clerc</a>
 */
public abstract class AbstractMavenEventHandler<E> implements MavenEventHandler<E> {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    protected final MavenEventReporter reporter;

    protected AbstractMavenEventHandler(MavenEventReporter reporter) {
        this.reporter = reporter;
    }

    @Override
    public boolean handle(Object event) {
        Type type = getSupportedType();
        Class<E> clazz = (Class<E>) type;
        if (clazz.isAssignableFrom(event.getClass())) {
            return _handle((E) event);
        } else {
            // print("event " + event + " not handled by " + toString());
            return false;
        }
    }

    private Type getSupportedType() {
        return ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    protected abstract boolean _handle(E e);

    @Override
    public String toString() {
        return getClass().getName() + "[type=" + getSupportedType() + "]";
    }

    public Xpp3Dom newElement(String name, String value) {
        Xpp3Dom element = new Xpp3Dom(name);
        element.setValue(value);
        return element;
    }

    public Xpp3Dom newElement(@Nonnull String name, @Nullable final MavenProject project) {
        Xpp3Dom projectElt = new Xpp3Dom(name);
        if (project == null) {
            return projectElt;
        }

        projectElt.setAttribute("name", project.getName());
        projectElt.setAttribute("groupId", project.getGroupId());
        projectElt.setAttribute("artifactId", project.getArtifactId());
        projectElt.setAttribute("version", project.getVersion());
        projectElt.setAttribute("packaging", project.getPackaging());

        if (project.getBasedir() != null) {
            try {
                projectElt.setAttribute("baseDir", project.getBasedir().getCanonicalPath());
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }
        }

        if (project.getFile() != null) {
            File projectFile = project.getFile();
            String absolutePath;
            try {
                absolutePath = projectFile.getCanonicalPath();
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }

            if (absolutePath.endsWith(File.separator + "pom.xml")
                    || absolutePath.endsWith(File.separator + ".flattened-pom.xml")) {
                // JENKINS-43616: flatten-maven-plugin replaces the original pom as artifact with a .flattened-pom.xml
                // no tweak
            } else if (absolutePath.endsWith(File.separator + "dependency-reduced-pom.xml")) {
                // JENKINS-42302: maven-shade-plugin creates a temporary project file dependency-reduced-pom.xml
                // TODO see if there is a better way to implement this "workaround"
                absolutePath = absolutePath.replace(File.separator + "dependency-reduced-pom.xml",
                        File.separator + "pom.xml");
            } else if (absolutePath.endsWith(File.separator + ".git-versioned-pom.xml")) {
                // JENKINS-56666 maven-git-versioning-extension causes warnings due to temporary pom.xml file name '.git-versioned-pom.xml'
                // https://github.com/qoomon/maven-git-versioning-extension/blob/v4.1.0/src/main/java/me/qoomon/maven/gitversioning/VersioningMojo.java#L39
                // TODO see if there is a better way to implement this "workaround"
                absolutePath = absolutePath.replace(File.separator + ".git-versioned-pom.xml",
                        File.separator + "pom.xml");
            } else {
                String flattenedPomFilename = getMavenFlattenPluginFlattenedPomFilename(project);
                if (flattenedPomFilename == null) {
                    logger.warn("[jenkins-event-spy] Unexpected Maven project file name '" + projectFile.getName()
                            + "', problems may occur");
                } else {
                    if (absolutePath.endsWith(File.separator + flattenedPomFilename)) {
                        absolutePath = absolutePath.replace(File.separator + flattenedPomFilename,
                                File.separator + "pom.xml");
                    } else {
                        logger.warn("[jenkins-event-spy] Unexpected Maven project file name '"
                                + projectFile.getName() + "', problems may occur");
                    }
                }
            }
            projectElt.setAttribute("file", absolutePath);
        }

        Build build = project.getBuild();

        if (build != null) {
            Xpp3Dom buildElt = new Xpp3Dom("build");
            projectElt.addChild(buildElt);
            if (build.getOutputDirectory() != null) {
                buildElt.setAttribute("directory", build.getDirectory());
            }
            if (build.getSourceDirectory() != null) {
                buildElt.setAttribute("sourceDirectory", build.getSourceDirectory());
            }
        }

        return projectElt;
    }

    /**
     * If the Maven project uses the "flatten-maven-plugin" and defines the config parameter "flattenedPomFilename", get its value.
     *
     * TODO optimize and keep in cache this result
     *
     * @param project
     * @return the "flattenedPomFilename" defined at the "flatten" execution level or at the plugin definition level. {@code null}
     */
    @Nullable
    protected String getMavenFlattenPluginFlattenedPomFilename(@Nonnull MavenProject project) {
        for (Plugin buildPlugin : project.getBuildPlugins()) {
            if ("org.codehaus.mojo:flatten-maven-plugin".equals(buildPlugin.getKey())) {
                String mavenConfigurationElement = "flattenedPomFilename";
                for (PluginExecution execution : buildPlugin.getExecutions()) {
                    if (execution.getGoals().contains("flatten")) {
                        if (execution.getConfiguration() instanceof Xpp3Dom) {
                            Xpp3Dom configuration = (Xpp3Dom) execution.getConfiguration();
                            Xpp3Dom flattenedPomFilename = configuration.getChild(mavenConfigurationElement);
                            if (flattenedPomFilename != null) {
                                return flattenedPomFilename.getValue();
                            }
                        } else {
                            // unexpected configuration type
                        }
                    }
                }
                if (buildPlugin.getConfiguration() instanceof Xpp3Dom) {
                    Xpp3Dom configuration = (Xpp3Dom) buildPlugin.getConfiguration();
                    Xpp3Dom flattenedPomFilename = configuration.getChild(mavenConfigurationElement);
                    if (flattenedPomFilename != null) {
                        return flattenedPomFilename.getValue();
                    }
                } else {
                    // unexpected configuration type
                }
            } else {

            }
        }
        return null;
    }

    public Xpp3Dom newElement(@Nonnull String name, @Nullable Throwable t) {
        Xpp3Dom rootElt = new Xpp3Dom(name);
        if (t == null) {
            return rootElt;
        }
        rootElt.setAttribute("class", t.getClass().getName());

        Xpp3Dom messageElt = new Xpp3Dom("message");
        rootElt.addChild(messageElt);
        messageElt.setValue(t.getMessage());

        Xpp3Dom stackTraceElt = new Xpp3Dom("stackTrace");
        rootElt.addChild(stackTraceElt);
        StringWriter stackTrace = new StringWriter();
        t.printStackTrace(new PrintWriter(stackTrace, true));
        stackTraceElt.setValue(stackTrace.toString());
        return rootElt;
    }

    public Xpp3Dom newElement(@Nonnull String name, @Nullable File file) {
        Xpp3Dom element = new Xpp3Dom(name);
        try {
            element.setValue(file == null ? null : file.getCanonicalPath());
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
        return element;
    }

    public Xpp3Dom newElement(@Nonnull String name, @Nullable Artifact artifact) {
        Xpp3Dom element = new Xpp3Dom(name);
        if (artifact == null) {
            return element;
        }

        element.setAttribute("groupId", artifact.getGroupId());
        element.setAttribute("artifactId", artifact.getArtifactId());
        element.setAttribute("baseVersion", artifact.getBaseVersion());
        element.setAttribute("version", artifact.getVersion());
        element.setAttribute("snapshot", String.valueOf(artifact.isSnapshot()));
        if (artifact.getClassifier() != null) {
            element.setAttribute("classifier", artifact.getClassifier());
        }
        element.setAttribute("type", artifact.getType());
        element.setAttribute("id", artifact.getId());

        ArtifactHandler artifactHandler = artifact.getArtifactHandler();
        String extension;
        if (artifactHandler == null) {
            extension = artifact.getType();
        } else {
            extension = artifactHandler.getExtension();
        }
        element.setAttribute("extension", extension);

        return element;
    }
}