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    }