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