1 16 package hudson.maven; 17 18 import org.apache.maven.BuildFailureException; 19 import org.apache.maven.artifact.Artifact; 20 import org.apache.maven.artifact.factory.ArtifactFactory; 21 import org.apache.maven.artifact.manager.WagonManager; 22 import org.apache.maven.artifact.repository.ArtifactRepository; 23 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; 24 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; 25 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; 26 import org.apache.maven.artifact.resolver.ArtifactNotFoundException; 27 import org.apache.maven.artifact.resolver.ArtifactResolutionException; 28 import org.apache.maven.artifact.resolver.ArtifactResolver; 29 import org.apache.maven.embedder.MavenEmbedderException; 30 import org.apache.maven.embedder.MavenEmbedderLogger; 31 import org.apache.maven.embedder.MavenEmbedderLoggerManager; 32 import org.apache.maven.embedder.PlexusLoggerAdapter; 33 import org.apache.maven.embedder.SummaryPluginDescriptor; 34 import org.apache.maven.execution.MavenSession; 35 import org.apache.maven.execution.ReactorManager; 36 import org.apache.maven.lifecycle.LifecycleExecutionException; 37 import org.apache.maven.lifecycle.LifecycleExecutor; 38 import org.apache.maven.model.Model; 39 import org.apache.maven.model.io.xpp3.MavenXpp3Reader; 40 import org.apache.maven.model.io.xpp3.MavenXpp3Writer; 41 import org.apache.maven.monitor.event.DefaultEventDispatcher; 42 import org.apache.maven.monitor.event.EventDispatcher; 43 import org.apache.maven.monitor.event.EventMonitor; 44 import org.apache.maven.plugin.MojoExecutionException; 45 import org.apache.maven.plugin.descriptor.PluginDescriptor; 46 import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder; 47 import org.apache.maven.profiles.DefaultProfileManager; 48 import org.apache.maven.profiles.ProfileManager; 49 import org.apache.maven.project.DuplicateProjectException; 50 import org.apache.maven.project.MavenProject; 51 import org.apache.maven.project.MavenProjectBuilder; 52 import org.apache.maven.project.ProjectBuildingException; 53 import org.apache.maven.settings.MavenSettingsBuilder; 54 import org.apache.maven.settings.RuntimeInfo; 55 import org.apache.maven.settings.Settings; 56 import org.apache.maven.wagon.events.TransferListener; 57 import org.codehaus.classworlds.ClassWorld; 58 import org.codehaus.classworlds.DuplicateRealmException; 59 import org.codehaus.plexus.PlexusContainer; 60 import org.codehaus.plexus.PlexusContainerException; 61 import org.codehaus.plexus.component.repository.ComponentDescriptor; 62 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException; 63 import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 64 import org.codehaus.plexus.configuration.PlexusConfiguration; 65 import org.codehaus.plexus.configuration.PlexusConfigurationException; 66 import org.codehaus.plexus.embed.Embedder; 67 import org.codehaus.plexus.util.DirectoryScanner; 68 import org.codehaus.plexus.util.dag.CycleDetectedException; 69 import org.codehaus.plexus.util.xml.pull.XmlPullParserException; 70 71 import java.io.File ; 72 import java.io.FileNotFoundException ; 73 import java.io.FileReader ; 74 import java.io.IOException ; 75 import java.io.InputStream ; 76 import java.io.InputStreamReader ; 77 import java.io.Writer ; 78 import java.net.URL ; 79 import java.util.ArrayList ; 80 import java.util.Collections ; 81 import java.util.Date ; 82 import java.util.Iterator ; 83 import java.util.List ; 84 import java.util.Properties ; 85 86 91 class MavenEmbedder 92 { 93 public static final String userHome = System.getProperty( "user.home" ); 94 95 99 private Embedder embedder; 100 101 105 private MavenProjectBuilder mavenProjectBuilder; 106 107 private ArtifactRepositoryFactory artifactRepositoryFactory; 108 109 private MavenSettingsBuilder settingsBuilder; 110 111 private LifecycleExecutor lifecycleExecutor; 112 113 private WagonManager wagonManager; 114 115 private MavenXpp3Reader modelReader; 116 117 private MavenXpp3Writer modelWriter; 118 119 private ProfileManager profileManager; 120 121 private PluginDescriptorBuilder pluginDescriptorBuilder; 122 123 private ArtifactFactory artifactFactory; 124 125 private ArtifactResolver artifactResolver; 126 127 private ArtifactRepositoryLayout defaultArtifactRepositoryLayout; 128 129 133 private Settings settings; 134 135 private ArtifactRepository localRepository; 136 137 private File localRepositoryDirectory; 138 139 private ClassLoader classLoader; 140 141 private MavenEmbedderLogger logger; 142 143 147 private boolean interactiveMode; 149 150 private boolean offline; 151 152 private String globalChecksumPolicy; 153 154 158 private boolean alignWithUserInstallation; 159 160 164 public void setInteractiveMode( boolean interactiveMode ) 165 { 166 this.interactiveMode = interactiveMode; 167 } 168 169 public boolean isInteractiveMode() 170 { 171 return interactiveMode; 172 } 173 174 public void setOffline( boolean offline ) 175 { 176 this.offline = offline; 177 } 178 179 public boolean isOffline() 180 { 181 return offline; 182 } 183 184 public void setGlobalChecksumPolicy( String globalChecksumPolicy ) 185 { 186 this.globalChecksumPolicy = globalChecksumPolicy; 187 } 188 189 public String getGlobalChecksumPolicy() 190 { 191 return globalChecksumPolicy; 192 } 193 194 public boolean isAlignWithUserInstallation() 195 { 196 return alignWithUserInstallation; 197 } 198 199 public void setAlignWithUserInstallation( boolean alignWithUserInstallation ) 200 { 201 this.alignWithUserInstallation = alignWithUserInstallation; 202 } 203 204 209 public void setClassLoader( ClassLoader classLoader ) 210 { 211 this.classLoader = classLoader; 212 } 213 214 public ClassLoader getClassLoader() 215 { 216 return classLoader; 217 } 218 219 public void setLocalRepositoryDirectory( File localRepositoryDirectory ) 220 { 221 this.localRepositoryDirectory = localRepositoryDirectory; 222 } 223 224 public File getLocalRepositoryDirectory() 225 { 226 return localRepositoryDirectory; 227 } 228 229 public ArtifactRepository getLocalRepository() 230 { 231 return localRepository; 232 } 233 234 public MavenEmbedderLogger getLogger() 235 { 236 return logger; 237 } 238 239 public void setLogger( MavenEmbedderLogger logger ) 240 { 241 this.logger = logger; 242 } 243 244 248 252 public Model readModel( File model ) 253 throws XmlPullParserException, FileNotFoundException , IOException { 254 return modelReader.read( new FileReader ( model ) ); 255 } 256 257 public void writeModel( Writer writer, Model model ) 258 throws IOException 259 { 260 modelWriter.write( writer, model ); 261 } 262 263 267 public MavenProject readProject( File mavenProject ) 268 throws ProjectBuildingException { 269 return mavenProjectBuilder.build( mavenProject, localRepository, profileManager ); 270 } 271 272 public MavenProject readProjectWithDependencies( File mavenProject, TransferListener transferListener ) 273 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException { 274 return mavenProjectBuilder.buildWithDependencies( mavenProject, localRepository, profileManager, transferListener ); 275 } 276 277 public MavenProject readProjectWithDependencies( File mavenProject ) 278 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException 279 { 280 return mavenProjectBuilder.buildWithDependencies( mavenProject, localRepository, profileManager ); 281 } 282 283 public List collectProjects( File basedir, String [] includes, String [] excludes ) 284 throws MojoExecutionException { 285 List projects = new ArrayList (); 286 287 List poms = getPomFiles( basedir, includes, excludes ); 288 289 for ( Iterator i = poms.iterator(); i.hasNext(); ) 290 { 291 File pom = (File ) i.next(); 292 293 try 294 { 295 MavenProject p = readProject( pom ); 296 297 projects.add( p ); 298 299 } 300 catch ( ProjectBuildingException e ) 301 { 302 throw new MojoExecutionException( "Error loading " + pom, e ); 303 } 304 } 305 306 return projects; 307 } 308 309 313 public Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type ) 314 { 315 return artifactFactory.createArtifact( groupId, artifactId, version, scope, type ); 316 } 317 318 public Artifact createArtifactWithClassifier( String groupId, String artifactId, String version, String type, String classifier ) 319 { 320 return artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, classifier ); 321 } 322 323 public void resolve( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository ) 324 throws ArtifactResolutionException, ArtifactNotFoundException 325 { 326 artifactResolver.resolve( artifact, remoteRepositories, localRepository ); 327 } 328 329 333 public List getAvailablePlugins() 334 { 335 List plugins = new ArrayList (); 336 337 plugins.add( makeMockPlugin( "org.apache.maven.plugins", "maven-jar-plugin", "Maven Jar Plug-in" ) ); 338 339 plugins.add( makeMockPlugin( "org.apache.maven.plugins", "maven-compiler-plugin", "Maven Compiler Plug-in" ) ); 340 341 return plugins; 342 } 343 344 public PluginDescriptor getPluginDescriptor( SummaryPluginDescriptor summaryPluginDescriptor ) 345 throws MavenEmbedderException { 346 PluginDescriptor pluginDescriptor; 347 348 try 349 { 350 InputStream is = classLoader.getResourceAsStream( "/plugins/" + summaryPluginDescriptor.getArtifactId() + ".xml" ); 351 352 pluginDescriptor = pluginDescriptorBuilder.build( new InputStreamReader ( is ) ); 353 } 354 catch ( PlexusConfigurationException e ) 355 { 356 throw new MavenEmbedderException( "Error retrieving plugin descriptor.", e ); 357 } 358 359 return pluginDescriptor; 360 } 361 362 private SummaryPluginDescriptor makeMockPlugin( String groupId, String artifactId, String name ) 363 { 364 return new SummaryPluginDescriptor( groupId, artifactId, name ); 365 } 366 367 371 375 public void execute( MavenProject project, 376 List goals, 377 EventMonitor eventMonitor, 378 TransferListener transferListener, 379 Properties properties, 380 File executionRootDirectory ) 381 throws CycleDetectedException, LifecycleExecutionException, BuildFailureException, DuplicateProjectException { 382 execute( Collections.singletonList( project ), goals, eventMonitor, transferListener, properties, executionRootDirectory ); 383 } 384 385 public void execute( List projects, 386 List goals, 387 EventMonitor eventMonitor, 388 TransferListener transferListener, 389 Properties properties, 390 File executionRootDirectory ) 391 throws CycleDetectedException, LifecycleExecutionException, BuildFailureException, DuplicateProjectException 392 { 393 ReactorManager rm = new ReactorManager( projects ); 394 395 EventDispatcher eventDispatcher = new DefaultEventDispatcher(); 396 397 eventDispatcher.addEventMonitor( eventMonitor ); 398 399 401 403 rm.setFailureBehavior( ReactorManager.FAIL_FAST ); 404 405 MavenSession session = new MavenSession( embedder.getContainer(), 406 settings, 407 localRepository, 408 eventDispatcher, 409 rm, 410 goals, 411 executionRootDirectory.getAbsolutePath(), 412 properties, 413 new Date () ); 414 415 session.setUsingPOMsFromFilesystem( true ); 416 417 if ( transferListener != null ) 418 { 419 wagonManager.setDownloadMonitor( transferListener ); 420 } 421 422 429 if ( properties != null ) 430 { 431 for ( Iterator i = properties.keySet().iterator(); i.hasNext(); ) 432 { 433 String key = (String ) i.next(); 434 435 String value = properties.getProperty( key ); 436 437 System.setProperty( key, value ); 438 } 439 } 440 441 lifecycleExecutor.execute( session, rm, session.getEventDispatcher() ); 442 } 443 444 448 public List getLifecyclePhases() 449 throws MavenEmbedderException 450 { 451 List phases = new ArrayList (); 452 453 ComponentDescriptor descriptor = embedder.getContainer().getComponentDescriptor( LifecycleExecutor.ROLE ); 454 455 PlexusConfiguration configuration = descriptor.getConfiguration(); 456 457 PlexusConfiguration[] phasesConfigurations = configuration.getChild( "lifecycles" ).getChild( 0 ).getChild( "phases" ).getChildren( "phase" ); 458 459 try 460 { 461 for ( int i = 0; i < phasesConfigurations.length; i++ ) 462 { 463 phases.add( phasesConfigurations[i].getValue() ); 464 } 465 } 466 catch ( PlexusConfigurationException e ) 467 { 468 throw new MavenEmbedderException( "Cannot retrieve default lifecycle phasesConfigurations.", e ); 469 } 470 471 return phases; 472 } 473 474 478 482 public static final String DEFAULT_LOCAL_REPO_ID = "local"; 483 484 public static final String DEFAULT_LAYOUT_ID = "default"; 485 486 public ArtifactRepository createLocalRepository( File localRepository ) 487 throws ComponentLookupException { 488 return createLocalRepository( localRepository.getAbsolutePath(), DEFAULT_LOCAL_REPO_ID ); 489 } 490 491 public ArtifactRepository createLocalRepository( Settings settings ) 492 throws ComponentLookupException 493 { 494 return createLocalRepository( settings.getLocalRepository(), DEFAULT_LOCAL_REPO_ID ); 495 } 496 497 public ArtifactRepository createLocalRepository( String url, String repositoryId ) 498 throws ComponentLookupException 499 { 500 if ( !url.startsWith( "file:" ) ) 501 { 502 url = "file://" + url; 503 } 504 505 return createRepository( url, repositoryId ); 506 } 507 508 public ArtifactRepository createRepository( String url, String repositoryId ) 509 throws ComponentLookupException 510 { 511 514 516 String updatePolicyFlag = ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS; 517 518 String checksumPolicyFlag = ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN; 519 520 ArtifactRepositoryPolicy snapshotsPolicy = new ArtifactRepositoryPolicy( true, updatePolicyFlag, checksumPolicyFlag ); 521 522 ArtifactRepositoryPolicy releasesPolicy = new ArtifactRepositoryPolicy( true, updatePolicyFlag, checksumPolicyFlag ); 523 524 return artifactRepositoryFactory.createArtifactRepository( repositoryId, url, defaultArtifactRepositoryLayout, snapshotsPolicy, releasesPolicy ); 525 } 526 527 531 private RuntimeInfo createRuntimeInfo( Settings settings ) 532 { 533 RuntimeInfo runtimeInfo = new RuntimeInfo( settings ); 534 535 runtimeInfo.setPluginUpdateOverride( Boolean.FALSE ); 536 537 return runtimeInfo; 538 } 539 540 private List getPomFiles( File basedir, String [] includes, String [] excludes ) 541 { 542 DirectoryScanner scanner = new DirectoryScanner(); 543 544 scanner.setBasedir( basedir ); 545 546 scanner.setIncludes( includes ); 547 548 scanner.setExcludes( excludes ); 549 550 scanner.scan(); 551 552 List poms = new ArrayList (); 553 554 for ( int i = 0; i < scanner.getIncludedFiles().length; i++ ) 555 { 556 poms.add( new File ( basedir, scanner.getIncludedFiles()[i] ) ); 557 } 558 559 return poms; 560 } 561 562 566 public void start() 567 throws MavenEmbedderException 568 { 569 detectUserInstallation(); 570 571 576 if ( classLoader == null ) 577 { 578 throw new IllegalStateException ( "A classloader must be specified using setClassLoader(ClassLoader)." ); 579 } 580 581 embedder = new Embedder(); 582 583 if ( logger != null ) 584 { 585 embedder.setLoggerManager( new MavenEmbedderLoggerManager( new PlexusLoggerAdapter( logger ) ) ); 586 } 587 588 if(overridingComponentsXml!=null) { 590 try { 591 embedder.setConfiguration(overridingComponentsXml); 592 } catch (IOException e) { 593 throw new MavenEmbedderException(e); 594 } 595 } 596 598 try 599 { 600 ClassWorld classWorld = new ClassWorld(); 601 602 classWorld.newRealm( "plexus.core", classLoader ); 603 604 embedder.start( classWorld ); 605 606 611 modelReader = new MavenXpp3Reader(); 612 613 modelWriter = new MavenXpp3Writer(); 614 615 pluginDescriptorBuilder = new PluginDescriptorBuilder(); 616 617 profileManager = new DefaultProfileManager( embedder.getContainer() ); 618 619 mavenProjectBuilder = (MavenProjectBuilder) embedder.lookup( MavenProjectBuilder.ROLE ); 620 621 625 artifactRepositoryFactory = (ArtifactRepositoryFactory) embedder.lookup( ArtifactRepositoryFactory.ROLE ); 626 627 artifactFactory = (ArtifactFactory) embedder.lookup( ArtifactFactory.ROLE ); 628 629 artifactResolver = (ArtifactResolver) embedder.lookup( ArtifactResolver.ROLE ); 630 631 defaultArtifactRepositoryLayout = (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE, DEFAULT_LAYOUT_ID ); 632 633 lifecycleExecutor = (LifecycleExecutor) embedder.lookup( LifecycleExecutor.ROLE ); 634 635 wagonManager = (WagonManager) embedder.lookup( WagonManager.ROLE ); 636 637 createMavenSettings(); 638 639 profileManager.loadSettingsProfiles( settings ); 640 641 localRepository = createLocalRepository( settings ); 642 } 643 catch ( PlexusContainerException e ) 644 { 645 throw new MavenEmbedderException( "Cannot start Plexus embedder.", e ); 646 } 647 catch ( DuplicateRealmException e ) 648 { 649 throw new MavenEmbedderException( "Cannot create Classworld realm for the embedder.", e ); 650 } 651 catch ( ComponentLookupException e ) 652 { 653 throw new MavenEmbedderException( "Cannot lookup required component.", e ); 654 } 655 } 656 657 661 private void detectUserInstallation() 662 { 663 if ( new File ( userHome, ".m2" ).exists() ) 664 { 665 alignWithUserInstallation = true; 666 } 667 } 668 669 678 private void createMavenSettings() 679 throws MavenEmbedderException, ComponentLookupException 680 { 681 if ( alignWithUserInstallation ) 682 { 683 689 settingsBuilder = (MavenSettingsBuilder) embedder.lookup( MavenSettingsBuilder.ROLE ); 690 691 try 692 { 693 settings = settingsBuilder.buildSettings(); 694 } 695 catch ( IOException e ) 696 { 697 throw new MavenEmbedderException( "Error creating settings.", e ); 698 } 699 catch ( XmlPullParserException e ) 700 { 701 throw new MavenEmbedderException( "Error creating settings.", e ); 702 } 703 } 704 else 705 { 706 if ( localRepository == null ) 707 { 708 throw new IllegalArgumentException ( "When not aligning with a user install you must specify a local repository location using the setLocalRepositoryDirectory( File ) method." ); 709 } 710 711 settings = new Settings(); 712 713 settings.setLocalRepository( localRepositoryDirectory.getAbsolutePath() ); 714 715 settings.setRuntimeInfo( createRuntimeInfo( settings ) ); 716 717 settings.setOffline( offline ); 718 719 settings.setInteractiveMode( interactiveMode ); 720 } 721 } 722 723 727 public void stop() 728 throws MavenEmbedderException 729 { 730 try 731 { 732 embedder.release( mavenProjectBuilder ); 733 734 embedder.release( artifactRepositoryFactory ); 735 736 embedder.release( settingsBuilder ); 737 738 embedder.release( lifecycleExecutor ); 739 } 740 catch ( ComponentLifecycleException e ) 741 { 742 throw new MavenEmbedderException( "Cannot stop the embedder.", e ); 743 } 744 } 745 746 747 private URL overridingComponentsXml; 751 752 759 public void setOverridingComponentsXml(URL overridingComponentsXml) { 760 this.overridingComponentsXml = overridingComponentsXml; 761 } 762 763 768 public PlexusContainer getContainer() { 769 return embedder.getContainer(); 770 } 771 } 772 | Popular Tags |