001 package org.apache.maven.lifecycle.internal;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.maven.execution.MavenSession;
023 import org.apache.maven.model.Dependency;
024 import org.apache.maven.model.Plugin;
025 import org.apache.maven.plugin.BuildPluginManager;
026 import org.apache.maven.plugin.InvalidPluginDescriptorException;
027 import org.apache.maven.plugin.MojoNotFoundException;
028 import org.apache.maven.plugin.PluginDescriptorParsingException;
029 import org.apache.maven.plugin.PluginNotFoundException;
030 import org.apache.maven.plugin.PluginResolutionException;
031 import org.apache.maven.plugin.descriptor.MojoDescriptor;
032 import org.apache.maven.plugin.prefix.DefaultPluginPrefixRequest;
033 import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
034 import org.apache.maven.plugin.prefix.PluginPrefixRequest;
035 import org.apache.maven.plugin.prefix.PluginPrefixResolver;
036 import org.apache.maven.plugin.prefix.PluginPrefixResult;
037 import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
038 import org.apache.maven.plugin.version.PluginVersionRequest;
039 import org.apache.maven.plugin.version.PluginVersionResolutionException;
040 import org.apache.maven.plugin.version.PluginVersionResolver;
041 import org.apache.maven.project.MavenProject;
042 import org.codehaus.plexus.component.annotations.Component;
043 import org.codehaus.plexus.component.annotations.Requirement;
044 import org.codehaus.plexus.configuration.PlexusConfiguration;
045 import org.codehaus.plexus.logging.Logger;
046 import org.codehaus.plexus.util.xml.Xpp3Dom;
047
048 import java.util.ArrayList;
049 import java.util.Collection;
050 import java.util.StringTokenizer;
051
052 /**
053 * Resolves dependencies for the artifacts in context of the lifecycle build
054 *
055 * @since 3.0
056 * @author Benjamin Bentmann
057 * @author Jason van Zyl
058 * @author jdcasey
059 * @author Kristian Rosenvold (extracted class only)
060 * <p/>
061 * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
062 */
063 @Component( role = MojoDescriptorCreator.class )
064 public class MojoDescriptorCreator
065 {
066
067 @Requirement
068 private Logger logger;
069
070 @Requirement
071 private PluginVersionResolver pluginVersionResolver;
072
073 @Requirement
074 private BuildPluginManager pluginManager;
075
076 @Requirement
077 private PluginPrefixResolver pluginPrefixResolver;
078
079 @Requirement
080 private LifecyclePluginResolver lifecyclePluginResolver;
081
082 public MojoDescriptorCreator()
083 {
084 }
085
086 public MojoDescriptorCreator( PluginVersionResolver pluginVersionResolver, BuildPluginManager pluginManager,
087 PluginPrefixResolver pluginPrefixResolver,
088 LifecyclePluginResolver lifecyclePluginResolver )
089 {
090 this.pluginVersionResolver = pluginVersionResolver;
091 this.pluginManager = pluginManager;
092 this.pluginPrefixResolver = pluginPrefixResolver;
093 this.lifecyclePluginResolver = lifecyclePluginResolver;
094 }
095
096 private Plugin findPlugin( String groupId, String artifactId, Collection<Plugin> plugins )
097 {
098 for ( Plugin plugin : plugins )
099 {
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 }