View Javadoc
1   package org.apache.maven.plugins.help;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.Writer;
25  import java.util.List;
26  
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.repository.ArtifactRepository;
29  import org.apache.maven.execution.MavenSession;
30  import org.apache.maven.model.building.ModelBuildingRequest;
31  import org.apache.maven.plugin.AbstractMojo;
32  import org.apache.maven.plugin.MojoExecutionException;
33  import org.apache.maven.plugins.annotations.Component;
34  import org.apache.maven.plugins.annotations.Parameter;
35  import org.apache.maven.project.DefaultProjectBuildingRequest;
36  import org.apache.maven.project.MavenProject;
37  import org.apache.maven.project.ProjectBuilder;
38  import org.apache.maven.project.ProjectBuildingRequest;
39  import org.apache.maven.shared.artifact.ArtifactCoordinate;
40  import org.apache.maven.shared.artifact.DefaultArtifactCoordinate;
41  import org.apache.maven.shared.artifact.resolve.ArtifactResolver;
42  import org.codehaus.plexus.util.IOUtil;
43  import org.codehaus.plexus.util.StringUtils;
44  import org.codehaus.plexus.util.WriterFactory;
45  
46  /**
47   * Base class with some Help Mojo functionalities.
48   *
49   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
50   * @version $Id$
51   * @since 2.1
52   */
53  public abstract class AbstractHelpMojo
54      extends AbstractMojo
55  {
56      /** The maximum length of a display line. */
57      protected static final int LINE_LENGTH = 79;
58      
59      /** The line separator for the current OS. */
60      protected static final String LS = System.getProperty( "line.separator" );
61      
62      /**
63       * Maven Project Builder component.
64       */
65      @Component
66      protected ProjectBuilder projectBuilder;
67      
68      /**
69       * Component used to resolve artifacts and download their files from remote repositories.
70       */
71      @Component
72      protected ArtifactResolver artifactResolver;
73      
74      /**
75       * Remote repositories used for the project.
76       */
77      @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
78      protected List<ArtifactRepository> remoteRepositories;
79      
80      /**
81       * Local Repository.
82       */
83      @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
84      protected ArtifactRepository localRepository;
85      
86      /**
87       * The current build session instance. This is used for
88       * plugin manager API calls.
89       */
90      @Parameter( defaultValue = "${session}", readonly = true, required = true )
91      protected MavenSession session;
92  
93      /**
94       * Optional parameter to write the output of this help in a given file, instead of writing to the console.
95       * <br>
96       * <b>Note</b>: Could be a relative path.
97       */
98      @Parameter( property = "output" )
99      protected File output;
100 
101     /**
102      * Utility method to write a content in a given file.
103      *
104      * @param output is the wanted output file.
105      * @param content contains the content to be written to the file.
106      * @throws IOException if any
107      * @see #writeFile(File, String)
108      */
109     protected static void writeFile( File output, StringBuilder content )
110         throws IOException
111     {
112         writeFile( output, content.toString() );
113     }
114 
115     /**
116      * Utility method to write a content in a given file.
117      *
118      * @param output is the wanted output file.
119      * @param content contains the content to be written to the file.
120      * @throws IOException if any
121      */
122     protected static void writeFile( File output, String content )
123         throws IOException
124     {
125         if ( output == null )
126         {
127             return;
128         }
129 
130         Writer out = null;
131         try
132         {
133             output.getParentFile().mkdirs();
134 
135             out = WriterFactory.newPlatformWriter( output );
136 
137             out.write( content );
138 
139             out.close();
140             out = null;
141         }
142         finally
143         {
144             IOUtil.close( out );
145         }
146     }
147     
148     /**
149      * Parses the given String into GAV artifact coordinate information, adding the given type.
150      * 
151      * @param artifactString should respect the format <code>groupId:artifactId[:version]</code>
152      * @param type The extension for the artifact, must not be <code>null</code>.
153      * @return the <code>Artifact</code> object for the <code>artifactString</code> parameter.
154      * @throws MojoExecutionException if the <code>artifactString</code> doesn't respect the format.
155      */
156     protected ArtifactCoordinate getArtifactCoordinate( String artifactString, String type )
157         throws MojoExecutionException
158     {
159         if ( StringUtils.isEmpty( artifactString ) )
160         {
161             throw new IllegalArgumentException( "artifact parameter could not be empty" );
162         }
163 
164         String groupId; // required
165         String artifactId; // required
166         String version; // optional
167 
168         String[] artifactParts = artifactString.split( ":" );
169         switch ( artifactParts.length )
170         {
171             case 2:
172                 groupId = artifactParts[0];
173                 artifactId = artifactParts[1];
174                 version = Artifact.LATEST_VERSION;
175                 break;
176             case 3:
177                 groupId = artifactParts[0];
178                 artifactId = artifactParts[1];
179                 version = artifactParts[2];
180                 break;
181             default:
182                 throw new MojoExecutionException( "The artifact parameter '" + artifactString
183                     + "' should be conform to: " + "'groupId:artifactId[:version]'." );
184         }
185         return getArtifactCoordinate( groupId, artifactId, version, type );
186     }
187 
188     protected ArtifactCoordinate getArtifactCoordinate( String groupId, String artifactId, String version, String type )
189     {
190         DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
191         coordinate.setGroupId( groupId );
192         coordinate.setArtifactId( artifactId );
193         coordinate.setVersion( version );
194         coordinate.setExtension( type );
195         return coordinate;
196     }
197 
198     /**
199      * Retrieves the Maven Project associated with the given artifact String, in the form of
200      * <code>groupId:artifactId[:version]</code>. This resolves the POM artifact at those coordinates and then builds
201      * the Maven project from it.
202      * 
203      * @param artifactString Coordinates of the Maven project to get.
204      * @return New Maven project.
205      * @throws MojoExecutionException If there was an error while getting the Maven project.
206      */
207     protected MavenProject getMavenProject( String artifactString )
208         throws MojoExecutionException
209     {
210         ArtifactCoordinate coordinate = getArtifactCoordinate( artifactString, "pom" );
211         try
212         {
213             ProjectBuildingRequest pbr = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
214             pbr.setRemoteRepositories( remoteRepositories );
215             pbr.setProject( null );
216             pbr.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
217             pbr.setResolveDependencies( true );
218             Artifact artifact = artifactResolver.resolveArtifact( pbr, coordinate ).getArtifact();
219             return projectBuilder.build( artifact.getFile(), pbr ).getProject();
220         }
221         catch ( Exception e )
222         {
223             throw new MojoExecutionException( "Unable to get the POM for the artifact '" + artifactString
224                 + "'. Verify the artifact parameter.", e );
225         }
226     }
227 
228 }