001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright (c) 2013-2014 Edugility LLC.
004 *
005 * Permission is hereby granted, free of charge, to any person
006 * obtaining a copy of this software and associated documentation
007 * files (the "Software"), to deal in the Software without
008 * restriction, including without limitation the rights to use, copy,
009 * modify, merge, publish, distribute, sublicense and/or sell copies
010 * of the Software, and to permit persons to whom the Software is
011 * furnished to do so, subject to the following conditions:
012 *
013 * The above copyright notice and this permission notice shall be
014 * included in all copies or substantial portions of the Software.
015 *
016 * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
019 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
020 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
021 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
022 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
023 * DEALINGS IN THE SOFTWARE.
024 *
025 * The original copy of this license is available at
026 * http://www.opensource.org/license/mit-license.html.
027 */
028package com.edugility.maven;
029
030import java.io.File;
031
032import java.util.Collection;
033
034import com.edugility.maven.Artifacts;
035
036import org.apache.maven.artifact.Artifact;
037
038import org.apache.maven.artifact.resolver.ArtifactResolver;
039import org.apache.maven.artifact.resolver.ArtifactResolutionException;
040
041import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
042
043import org.apache.maven.artifact.repository.ArtifactRepository;
044
045import org.apache.maven.plugin.AbstractMojo;
046import org.apache.maven.plugin.MojoExecutionException;
047import org.apache.maven.plugin.MojoFailureException;
048
049import org.apache.maven.plugin.logging.Log;
050
051import org.apache.maven.plugins.annotations.Mojo;
052import org.apache.maven.plugins.annotations.ResolutionScope;
053import org.apache.maven.plugins.annotations.Component;
054import org.apache.maven.plugins.annotations.Parameter;
055
056import org.apache.maven.project.MavenProject;
057
058import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
059import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
060
061/**
062 * A mojo that sorts Maven artifacts topologically and then arranges
063 * the processing of them with a user-supplied {@linkplain
064 * ArtifactsProcessor processor}.
065 *
066 * @author <a href="http://about.me/lairdnelson"
067 * target="_parent">Laird Nelson</a>
068 *
069 * @see ArtifactsProcessor
070 */
071@Mojo(name = "process")
072public class ArtifactMojo extends AbstractMojo {
073
074  /**
075   * The {@link MavenProject} in effect.
076   */
077  @Parameter(defaultValue = "${project}", readonly = true, required = true)
078  private MavenProject project;
079
080  /**
081   * The {@link DependencyGraphBuilder} used to collect all
082   * dependencies of a project.
083   */
084  @Component
085  private DependencyGraphBuilder dependencyGraphBuilder;
086
087  /**
088   * The {@link ArtifactResolver} to use when a given artifact has not
089   * yet been resolved.
090   */
091  @Component
092  private ArtifactResolver resolver;
093
094  /**
095   * An {@link ArtifactsProcessor} implementation that will receive a
096   * topologically sorted collection of resolved Maven artifacts.
097   */
098  @Parameter(required = true)
099  private ArtifactsProcessor artifactsProcessor;
100
101  /**
102   * The local {@link ArtifactRepository} in effect.
103   */
104  @Parameter(defaultValue = "${localRepository}", readonly = true, required = true)
105  private ArtifactRepository localRepository;
106
107  /**
108   * An {@link ArtifactFilter} for choosing what {@link Artifact}s are
109   * to be processed.
110   */
111  @Parameter
112  private ArtifactFilter artifactFilter;
113
114  /**
115   * Creates a new {@link ArtifactMojo}.
116   */
117  public ArtifactMojo() {
118    super();
119  }
120
121  /**
122   * Collects all {@link Artifact}s that should be
123   * processed&mdash;according to the {@linkplain #artifactFilter
124   * associated <code>ArtifactFilter</code>}&mdash;and hands them off
125   * to the associated {@link #artifactsProcessor ArtifactsProcessor}.
126   *
127   * @exception MojoExecutionException if processing failed
128   *
129   * @exception MojoFailureException if setup failed
130   *
131   * @see ArtifactsProcessor
132   */
133  @Override
134  public void execute() throws MojoExecutionException, MojoFailureException {
135    if (this.project == null) {
136      throw new MojoFailureException("this.project == null", new IllegalStateException("this.project == null", new NullPointerException("this.project")));
137    }
138    if (this.dependencyGraphBuilder == null) {
139      throw new MojoFailureException("this.dependencyGraphBuilder == null", new IllegalStateException("this.dependencyGraphBuilder == null", new NullPointerException("this.dependencyGraphBuilder")));
140    }
141
142    final ArtifactsProcessor processor = this.getArtifactsProcessor();
143    if (processor == null) {
144      throw new MojoFailureException("this.getArtifactsProcessor() == null", new IllegalStateException("this.getArtifactsProcessor() == null", new NullPointerException("this.getArtifactsProcessor()")));
145    }
146
147    Collection<? extends Artifact> artifacts = null;
148
149    try {
150      artifacts = new Artifacts().getArtifactsInTopologicalOrder(this.project, 
151                                                                 this.dependencyGraphBuilder,
152                                                                 this.artifactFilter,
153                                                                 resolver,
154                                                                 localRepository);
155    } catch (final DependencyGraphBuilderException wrapMe) {
156      throw new MojoExecutionException("Failed to get dependency artifacts", wrapMe);
157    } catch (final ArtifactResolutionException wrapMe) {
158      throw new MojoExecutionException("Failed to get dependency artifacts", wrapMe);
159    }
160
161    if (artifacts != null && !artifacts.isEmpty()) {
162      try {
163        processor.process(this.project, artifacts, this.getLog());
164      } catch (final ArtifactsProcessingException wrapMe) {
165        throw new MojoExecutionException("Failed to process artifacts", wrapMe);
166      }
167    }
168  }
169
170  /**
171   * Returns an {@link ArtifactsProcessor} for use by the {@link
172   * #execute()} method.
173   *
174   * <p>This method may return {@code null}.</p>
175   *
176   * @return an {@link ArtifactsProcessor}
177   *
178   * @see ArtifactsProcessor
179   */
180  public ArtifactsProcessor getArtifactsProcessor() {
181    return this.artifactsProcessor;
182  }
183
184}