001package 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 022import org.apache.maven.execution.MavenSession; 023import org.apache.maven.model.Plugin; 024import org.apache.maven.plugin.BuildPluginManager; 025import org.apache.maven.plugin.InvalidPluginDescriptorException; 026import org.apache.maven.plugin.MojoNotFoundException; 027import org.apache.maven.plugin.PluginDescriptorParsingException; 028import org.apache.maven.plugin.PluginNotFoundException; 029import org.apache.maven.plugin.PluginResolutionException; 030import org.apache.maven.plugin.descriptor.MojoDescriptor; 031import org.apache.maven.plugin.prefix.DefaultPluginPrefixRequest; 032import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; 033import org.apache.maven.plugin.prefix.PluginPrefixRequest; 034import org.apache.maven.plugin.prefix.PluginPrefixResolver; 035import org.apache.maven.plugin.prefix.PluginPrefixResult; 036import org.apache.maven.plugin.version.DefaultPluginVersionRequest; 037import org.apache.maven.plugin.version.PluginVersionRequest; 038import org.apache.maven.plugin.version.PluginVersionResolutionException; 039import org.apache.maven.plugin.version.PluginVersionResolver; 040import org.apache.maven.project.MavenProject; 041import org.codehaus.plexus.component.annotations.Component; 042import org.codehaus.plexus.component.annotations.Requirement; 043import org.codehaus.plexus.configuration.PlexusConfiguration; 044import org.codehaus.plexus.logging.Logger; 045import org.codehaus.plexus.util.xml.Xpp3Dom; 046 047import java.util.ArrayList; 048import java.util.Collection; 049import java.util.StringTokenizer; 050 051/** 052 * Resolves dependencies for the artifacts in context of the lifecycle build 053 * 054 * @since 3.0 055 * @author Benjamin Bentmann 056 * @author Jason van Zyl 057 * @author jdcasey 058 * @author Kristian Rosenvold (extracted class only) 059 * <p/> 060 * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. 061 */ 062@Component( role = MojoDescriptorCreator.class ) 063public class MojoDescriptorCreator 064{ 065 066 @Requirement 067 private Logger logger; 068 069 @Requirement 070 private PluginVersionResolver pluginVersionResolver; 071 072 @Requirement 073 private BuildPluginManager pluginManager; 074 075 @Requirement 076 private PluginPrefixResolver pluginPrefixResolver; 077 078 @Requirement 079 private LifecyclePluginResolver lifecyclePluginResolver; 080 081 public MojoDescriptorCreator() 082 { 083 } 084 085 public MojoDescriptorCreator( PluginVersionResolver pluginVersionResolver, BuildPluginManager pluginManager, 086 PluginPrefixResolver pluginPrefixResolver, 087 LifecyclePluginResolver lifecyclePluginResolver ) 088 { 089 this.pluginVersionResolver = pluginVersionResolver; 090 this.pluginManager = pluginManager; 091 this.pluginPrefixResolver = pluginPrefixResolver; 092 this.lifecyclePluginResolver = lifecyclePluginResolver; 093 } 094 095 private Plugin findPlugin( String groupId, String artifactId, Collection<Plugin> plugins ) 096 { 097 for ( Plugin plugin : plugins ) 098 { 099 if ( artifactId.equals( plugin.getArtifactId() ) && groupId.equals( plugin.getGroupId() ) ) 100 { 101 return plugin; 102 } 103 } 104 105 return null; 106 } 107 108 public static Xpp3Dom convert( MojoDescriptor mojoDescriptor ) 109 { 110 Xpp3Dom dom = new Xpp3Dom( "configuration" ); 111 112 PlexusConfiguration c = mojoDescriptor.getMojoConfiguration(); 113 114 PlexusConfiguration[] ces = c.getChildren(); 115 116 if ( ces != null ) 117 { 118 for ( PlexusConfiguration ce : ces ) 119 { 120 String value = ce.getValue( null ); 121 String defaultValue = ce.getAttribute( "default-value", null ); 122 if ( value != null || defaultValue != null ) 123 { 124 Xpp3Dom e = new Xpp3Dom( ce.getName() ); 125 e.setValue( value ); 126 if ( defaultValue != null ) 127 { 128 e.setAttribute( "default-value", defaultValue ); 129 } 130 dom.addChild( e ); 131 } 132 } 133 } 134 135 return dom; 136 } 137 138 // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process@executionId 139 140 public MojoDescriptor getMojoDescriptor( String task, MavenSession session, MavenProject project ) 141 throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, 142 MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, 143 PluginVersionResolutionException 144 { 145 String goal = null; 146 147 Plugin plugin = null; 148 149 StringTokenizer tok = new StringTokenizer( task, ":" ); 150 151 int numTokens = tok.countTokens(); 152 153 if ( numTokens >= 4 ) 154 { 155 // We have everything that we need 156 // 157 // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process 158 // 159 // groupId 160 // artifactId 161 // version 162 // goal 163 // 164 plugin = new Plugin(); 165 plugin.setGroupId( tok.nextToken() ); 166 plugin.setArtifactId( tok.nextToken() ); 167 plugin.setVersion( tok.nextToken() ); 168 goal = tok.nextToken(); 169 170 // This won't be valid, but it constructs something easy to read in the error message 171 while ( tok.hasMoreTokens() ) 172 { 173 goal += ":" + tok.nextToken(); 174 } 175 } 176 else if ( numTokens == 3 ) 177 { 178 // We have everything that we need except the version 179 // 180 // org.apache.maven.plugins:maven-remote-resources-plugin:???:process 181 // 182 // groupId 183 // artifactId 184 // ??? 185 // goal 186 // 187 plugin = new Plugin(); 188 plugin.setGroupId( tok.nextToken() ); 189 plugin.setArtifactId( tok.nextToken() ); 190 goal = tok.nextToken(); 191 } 192 else if ( numTokens <= 2 ) 193 { 194 // We have a prefix and goal 195 // 196 // idea:idea 197 // 198 String prefix = tok.nextToken(); 199 200 if ( numTokens == 2 ) 201 { 202 goal = tok.nextToken(); 203 } 204 else 205 { 206 // goal was missing - pass through to MojoNotFoundException 207 goal = ""; 208 } 209 210 // This is the case where someone has executed a single goal from the command line 211 // of the form: 212 // 213 // mvn remote-resources:process 214 // 215 // From the metadata stored on the server which has been created as part of a standard 216 // Maven plugin deployment we will find the right PluginDescriptor from the remote 217 // repository. 218 219 plugin = findPluginForPrefix( prefix, session ); 220 } 221 222 int executionIdx = goal.indexOf( '@' ); 223 if ( executionIdx > 0 ) 224 { 225 goal = goal.substring( 0, executionIdx ); 226 } 227 228 injectPluginDeclarationFromProject( plugin, project ); 229 230 // If there is no version to be found then we need to look in the repository metadata for 231 // this plugin and see what's specified as the latest release. 232 // 233 if ( plugin.getVersion() == null ) 234 { 235 resolvePluginVersion( plugin, session, project ); 236 } 237 238 return pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(), 239 session.getRepositorySession() ); 240 } 241 242 // TODO: take repo mans into account as one may be aggregating prefixes of many 243 // TODO: collect at the root of the repository, read the one at the root, and fetch remote if something is missing 244 // or the user forces the issue 245 246 public Plugin findPluginForPrefix( String prefix, MavenSession session ) 247 throws NoPluginFoundForPrefixException 248 { 249 // [prefix]:[goal] 250 251 if ( session.getCurrentProject() != null ) 252 { 253 try 254 { 255 lifecyclePluginResolver.resolveMissingPluginVersions( session.getCurrentProject(), session ); 256 } 257 catch ( PluginVersionResolutionException e ) 258 { 259 // not critical here 260 logger.debug( e.getMessage(), e ); 261 } 262 } 263 264 PluginPrefixRequest prefixRequest = new DefaultPluginPrefixRequest( prefix, session ); 265 PluginPrefixResult prefixResult = pluginPrefixResolver.resolve( prefixRequest ); 266 267 Plugin plugin = new Plugin(); 268 plugin.setGroupId( prefixResult.getGroupId() ); 269 plugin.setArtifactId( prefixResult.getArtifactId() ); 270 271 return plugin; 272 } 273 274 private void resolvePluginVersion( Plugin plugin, MavenSession session, MavenProject project ) 275 throws PluginVersionResolutionException 276 { 277 PluginVersionRequest versionRequest = 278 new DefaultPluginVersionRequest( plugin, session.getRepositorySession(), 279 project.getRemotePluginRepositories() ); 280 plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() ); 281 } 282 283 private void injectPluginDeclarationFromProject( Plugin plugin, MavenProject project ) 284 { 285 Plugin pluginInPom = findPlugin( plugin, project.getBuildPlugins() ); 286 287 if ( pluginInPom == null && project.getPluginManagement() != null ) 288 { 289 pluginInPom = findPlugin( plugin, project.getPluginManagement().getPlugins() ); 290 } 291 292 if ( pluginInPom != null ) 293 { 294 if ( plugin.getVersion() == null ) 295 { 296 plugin.setVersion( pluginInPom.getVersion() ); 297 } 298 299 plugin.setDependencies( new ArrayList<>( pluginInPom.getDependencies() ) ); 300 } 301 } 302 303 private Plugin findPlugin( Plugin plugin, Collection<Plugin> plugins ) 304 { 305 return findPlugin( plugin.getGroupId(), plugin.getArtifactId(), plugins ); 306 } 307 308}