View Javadoc

1   package org.apache.maven.lifecycle.internal;
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 org.apache.maven.execution.MavenSession;
23  import org.apache.maven.model.Dependency;
24  import org.apache.maven.model.Plugin;
25  import org.apache.maven.plugin.BuildPluginManager;
26  import org.apache.maven.plugin.InvalidPluginDescriptorException;
27  import org.apache.maven.plugin.MojoNotFoundException;
28  import org.apache.maven.plugin.PluginDescriptorParsingException;
29  import org.apache.maven.plugin.PluginNotFoundException;
30  import org.apache.maven.plugin.PluginResolutionException;
31  import org.apache.maven.plugin.descriptor.MojoDescriptor;
32  import org.apache.maven.plugin.prefix.DefaultPluginPrefixRequest;
33  import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
34  import org.apache.maven.plugin.prefix.PluginPrefixRequest;
35  import org.apache.maven.plugin.prefix.PluginPrefixResolver;
36  import org.apache.maven.plugin.prefix.PluginPrefixResult;
37  import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
38  import org.apache.maven.plugin.version.PluginVersionRequest;
39  import org.apache.maven.plugin.version.PluginVersionResolutionException;
40  import org.apache.maven.plugin.version.PluginVersionResolver;
41  import org.apache.maven.project.MavenProject;
42  import org.codehaus.plexus.component.annotations.Component;
43  import org.codehaus.plexus.component.annotations.Requirement;
44  import org.codehaus.plexus.configuration.PlexusConfiguration;
45  import org.codehaus.plexus.logging.Logger;
46  import org.codehaus.plexus.util.xml.Xpp3Dom;
47  
48  import java.util.ArrayList;
49  import java.util.Collection;
50  import java.util.StringTokenizer;
51  
52  /**
53   * Resolves dependencies for the artifacts in context of the lifecycle build
54   * 
55   * @since 3.0
56   * @author Benjamin Bentmann
57   * @author Jason van Zyl
58   * @author jdcasey
59   * @author Kristian Rosenvold (extracted class only)
60   *         <p/>
61   *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
62   */
63  
64  @Component( role = MojoDescriptorCreator.class )
65  public class MojoDescriptorCreator
66  {
67  
68      @Requirement
69      private Logger logger;
70  
71      @Requirement
72      private PluginVersionResolver pluginVersionResolver;
73  
74      @Requirement
75      private BuildPluginManager pluginManager;
76  
77      @Requirement
78      private PluginPrefixResolver pluginPrefixResolver;
79  
80      @Requirement
81      private LifecyclePluginResolver lifecyclePluginResolver;
82  
83      @SuppressWarnings( { "UnusedDeclaration" } )
84      public MojoDescriptorCreator()
85      {
86      }
87  
88      public MojoDescriptorCreator( PluginVersionResolver pluginVersionResolver, BuildPluginManager pluginManager,
89                                    PluginPrefixResolver pluginPrefixResolver,
90                                    LifecyclePluginResolver lifecyclePluginResolver )
91      {
92          this.pluginVersionResolver = pluginVersionResolver;
93          this.pluginManager = pluginManager;
94          this.pluginPrefixResolver = pluginPrefixResolver;
95          this.lifecyclePluginResolver = lifecyclePluginResolver;
96      }
97  
98      private Plugin findPlugin( String groupId, String artifactId, Collection<Plugin> plugins )
99      {
100         for ( Plugin plugin : plugins )
101         {
102             if ( artifactId.equals( plugin.getArtifactId() ) && groupId.equals( plugin.getGroupId() ) )
103             {
104                 return plugin;
105             }
106         }
107 
108         return null;
109     }
110 
111     public static Xpp3Dom convert( MojoDescriptor mojoDescriptor )
112     {
113         Xpp3Dom dom = new Xpp3Dom( "configuration" );
114 
115         PlexusConfiguration c = mojoDescriptor.getMojoConfiguration();
116 
117         PlexusConfiguration[] ces = c.getChildren();
118 
119         if ( ces != null )
120         {
121             for ( PlexusConfiguration ce : ces )
122             {
123                 String value = ce.getValue( null );
124                 String defaultValue = ce.getAttribute( "default-value", null );
125                 if ( value != null || defaultValue != null )
126                 {
127                     Xpp3Dom e = new Xpp3Dom( ce.getName() );
128                     e.setValue( value );
129                     if ( defaultValue != null )
130                     {
131                         e.setAttribute( "default-value", defaultValue );
132                     }
133                     dom.addChild( e );
134                 }
135             }
136         }
137 
138         return dom;
139     }
140 
141     // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process
142 
143     public MojoDescriptor getMojoDescriptor( String task, MavenSession session, MavenProject project )
144         throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
145         MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
146         PluginVersionResolutionException
147     {
148         String goal = null;
149 
150         Plugin plugin = null;
151 
152         StringTokenizer tok = new StringTokenizer( task, ":" );
153 
154         int numTokens = tok.countTokens();
155 
156         if ( numTokens >= 4 )
157         {
158             // We have everything that we need
159             //
160             // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process
161             //
162             // groupId
163             // artifactId
164             // version
165             // goal
166             //
167             plugin = new Plugin();
168             plugin.setGroupId( tok.nextToken() );
169             plugin.setArtifactId( tok.nextToken() );
170             plugin.setVersion( tok.nextToken() );
171             goal = tok.nextToken();
172 
173             // This won't be valid, but it constructs something easy to read in the error message
174             while ( tok.hasMoreTokens() )
175             {
176                 goal += ":" + tok.nextToken();
177             }
178         }
179         else if ( numTokens == 3 )
180         {
181             // We have everything that we need except the version
182             //
183             // org.apache.maven.plugins:maven-remote-resources-plugin:???:process
184             //
185             // groupId
186             // artifactId
187             // ???
188             // goal
189             //
190             plugin = new Plugin();
191             plugin.setGroupId( tok.nextToken() );
192             plugin.setArtifactId( tok.nextToken() );
193             goal = tok.nextToken();
194         }
195         else if ( numTokens <= 2 )
196         {
197             // We have a prefix and goal
198             //
199             // idea:idea
200             //
201             String prefix = tok.nextToken();
202 
203             if ( numTokens == 2 )
204             {
205                 goal = tok.nextToken();
206             }
207             else
208             {
209                 // goal was missing - pass through to MojoNotFoundException
210                 goal = "";
211             }
212 
213             // This is the case where someone has executed a single goal from the command line
214             // of the form:
215             //
216             // mvn remote-resources:process
217             //
218             // From the metadata stored on the server which has been created as part of a standard
219             // Maven plugin deployment we will find the right PluginDescriptor from the remote
220             // repository.
221 
222             plugin = findPluginForPrefix( prefix, session );
223         }
224 
225         injectPluginDeclarationFromProject( plugin, project );
226 
227         // If there is no version to be found then we need to look in the repository metadata for
228         // this plugin and see what's specified as the latest release.
229         //
230         if ( plugin.getVersion() == null )
231         {
232             resolvePluginVersion( plugin, session, project );
233         }
234 
235         return pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(),
236                                                 session.getRepositorySession() );
237     }
238 
239     // TODO: take repo mans into account as one may be aggregating prefixes of many
240     // TODO: collect at the root of the repository, read the one at the root, and fetch remote if something is missing
241     // or the user forces the issue
242 
243     public Plugin findPluginForPrefix( String prefix, MavenSession session )
244         throws NoPluginFoundForPrefixException
245     {
246         // [prefix]:[goal]
247 
248         if ( session.getCurrentProject() != null )
249         {
250             try
251             {
252                 lifecyclePluginResolver.resolveMissingPluginVersions( session.getCurrentProject(), session );
253             }
254             catch ( PluginVersionResolutionException e )
255             {
256                 // not critical here
257                 logger.debug( e.getMessage(), e );
258             }
259         }
260 
261         PluginPrefixRequest prefixRequest = new DefaultPluginPrefixRequest( prefix, session );
262         PluginPrefixResult prefixResult = pluginPrefixResolver.resolve( prefixRequest );
263 
264         Plugin plugin = new Plugin();
265         plugin.setGroupId( prefixResult.getGroupId() );
266         plugin.setArtifactId( prefixResult.getArtifactId() );
267 
268         return plugin;
269     }
270 
271     private void resolvePluginVersion( Plugin plugin, MavenSession session, MavenProject project )
272         throws PluginVersionResolutionException
273     {
274         PluginVersionRequest versionRequest =
275             new DefaultPluginVersionRequest( plugin, session.getRepositorySession(),
276                                              project.getRemotePluginRepositories() );
277         plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
278     }
279 
280     private void injectPluginDeclarationFromProject( Plugin plugin, MavenProject project )
281     {
282         Plugin pluginInPom = findPlugin( plugin, project.getBuildPlugins() );
283 
284         if ( pluginInPom == null && project.getPluginManagement() != null )
285         {
286             pluginInPom = findPlugin( plugin, project.getPluginManagement().getPlugins() );
287         }
288 
289         if ( pluginInPom != null )
290         {
291             if ( plugin.getVersion() == null )
292             {
293                 plugin.setVersion( pluginInPom.getVersion() );
294             }
295 
296             plugin.setDependencies( new ArrayList<Dependency>( pluginInPom.getDependencies() ) );
297         }
298     }
299 
300     private Plugin findPlugin( Plugin plugin, Collection<Plugin> plugins )
301     {
302         return findPlugin( plugin.getGroupId(), plugin.getArtifactId(), plugins );
303     }
304 
305 }