1 package org.apache.maven.project; 2 3 18 19 import org.apache.maven.artifact.Artifact; 20 import org.apache.maven.artifact.ArtifactStatus; 21 import org.apache.maven.artifact.ArtifactUtils; 22 import org.apache.maven.artifact.InvalidRepositoryException; 23 import org.apache.maven.artifact.factory.ArtifactFactory; 24 import org.apache.maven.artifact.manager.WagonManager; 25 import org.apache.maven.artifact.metadata.ArtifactMetadataSource; 26 import org.apache.maven.artifact.repository.ArtifactRepository; 27 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; 28 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; 29 import org.apache.maven.artifact.resolver.ArtifactNotFoundException; 30 import org.apache.maven.artifact.resolver.ArtifactResolutionException; 31 import org.apache.maven.artifact.resolver.ArtifactResolutionResult; 32 import org.apache.maven.artifact.resolver.ArtifactResolver; 33 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; 34 import org.apache.maven.artifact.versioning.VersionRange; 35 import org.apache.maven.model.Build; 36 import org.apache.maven.model.Dependency; 37 import org.apache.maven.model.DependencyManagement; 38 import org.apache.maven.model.DistributionManagement; 39 import org.apache.maven.model.Extension; 40 import org.apache.maven.model.Model; 41 import org.apache.maven.model.Parent; 42 import org.apache.maven.model.Plugin; 43 import org.apache.maven.model.Profile; 44 import org.apache.maven.model.ReportPlugin; 45 import org.apache.maven.model.Repository; 46 import org.apache.maven.model.io.xpp3.MavenXpp3Reader; 47 import org.apache.maven.profiles.DefaultProfileManager; 48 import org.apache.maven.profiles.MavenProfilesBuilder; 49 import org.apache.maven.profiles.ProfileManager; 50 import org.apache.maven.profiles.ProfilesConversionUtils; 51 import org.apache.maven.profiles.ProfilesRoot; 52 import org.apache.maven.profiles.activation.ProfileActivationException; 53 import org.apache.maven.project.artifact.InvalidDependencyVersionException; 54 import org.apache.maven.project.inheritance.ModelInheritanceAssembler; 55 import org.apache.maven.project.injection.ModelDefaultsInjector; 56 import org.apache.maven.project.injection.ProfileInjector; 57 import org.apache.maven.project.interpolation.ModelInterpolationException; 58 import org.apache.maven.project.interpolation.ModelInterpolator; 59 import org.apache.maven.project.path.PathTranslator; 60 import org.apache.maven.project.validation.ModelValidationResult; 61 import org.apache.maven.project.validation.ModelValidator; 62 import org.apache.maven.wagon.events.TransferListener; 63 import org.codehaus.plexus.PlexusConstants; 64 import org.codehaus.plexus.PlexusContainer; 65 import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 66 import org.codehaus.plexus.context.Context; 67 import org.codehaus.plexus.context.ContextException; 68 import org.codehaus.plexus.logging.AbstractLogEnabled; 69 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; 70 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; 71 import org.codehaus.plexus.util.IOUtil; 72 import org.codehaus.plexus.util.StringUtils; 73 import org.codehaus.plexus.util.xml.pull.XmlPullParserException; 74 75 import java.io.File ; 76 import java.io.FileNotFoundException ; 77 import java.io.FileReader ; 78 import java.io.IOException ; 79 import java.io.InputStreamReader ; 80 import java.io.Reader ; 81 import java.io.StringReader ; 82 import java.io.StringWriter ; 83 import java.net.URL ; 84 import java.util.ArrayList ; 85 import java.util.Collections ; 86 import java.util.Date ; 87 import java.util.HashMap ; 88 import java.util.HashSet ; 89 import java.util.Iterator ; 90 import java.util.LinkedHashSet ; 91 import java.util.LinkedList ; 92 import java.util.List ; 93 import java.util.Map ; 94 import java.util.Set ; 95 96 129 130 134 public class DefaultMavenProjectBuilder 135 extends AbstractLogEnabled 136 implements MavenProjectBuilder, Initializable, Contextualizable 137 { 138 private PlexusContainer container; 140 141 protected MavenProfilesBuilder profilesBuilder; 142 143 protected ArtifactResolver artifactResolver; 144 145 protected ArtifactMetadataSource artifactMetadataSource; 146 147 private ArtifactFactory artifactFactory; 148 149 private ModelInheritanceAssembler modelInheritanceAssembler; 150 151 private ProfileInjector profileInjector; 152 153 private ModelValidator validator; 154 155 private Map rawProjectCache = new HashMap (); 156 157 private Map processedProjectCache = new HashMap (); 158 159 private MavenXpp3Reader modelReader; 161 162 private PathTranslator pathTranslator; 163 164 private ModelDefaultsInjector modelDefaultsInjector; 165 166 private ModelInterpolator modelInterpolator; 167 168 private ArtifactRepositoryFactory artifactRepositoryFactory; 169 170 176 private WagonManager wagonManager; 177 178 public static final String MAVEN_MODEL_VERSION = "4.0.0"; 179 180 public void initialize() 181 { 182 modelReader = new MavenXpp3Reader(); 183 } 184 185 189 public MavenProject build( File projectDescriptor, ArtifactRepository localRepository, ProfileManager profileManager ) 190 throws ProjectBuildingException 191 { 192 return buildFromSourceFileInternal( projectDescriptor, localRepository, profileManager, true ); 193 } 194 195 public MavenProject build( File projectDescriptor, 196 ArtifactRepository localRepository, 197 ProfileManager profileManager, 198 boolean checkDistributionManagementStatus ) 199 throws ProjectBuildingException 200 { 201 return buildFromSourceFileInternal( projectDescriptor, localRepository, profileManager, checkDistributionManagementStatus ); 202 } 203 204 public MavenProject buildFromRepository( Artifact artifact, 211 List remoteArtifactRepositories, 212 ArtifactRepository localRepository, 213 boolean allowStubModel ) 214 throws ProjectBuildingException 215 { 216 String cacheKey = createCacheKey( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() ); 217 218 MavenProject project = (MavenProject) processedProjectCache.get( cacheKey ); 219 220 if ( project != null ) 221 { 222 return project; 223 } 224 225 Model model = findModelFromRepository( artifact, remoteArtifactRepositories, localRepository, allowStubModel ); 226 227 return buildInternal( "Artifact [" + artifact + "]", model, localRepository, remoteArtifactRepositories, null, null, false ); 228 } 229 230 public MavenProject buildFromRepository( Artifact artifact, 231 List remoteArtifactRepositories, 232 ArtifactRepository localRepository ) 233 throws ProjectBuildingException 234 { 235 return buildFromRepository( artifact, remoteArtifactRepositories, localRepository, true ); 236 } 237 238 public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository ) 240 throws ProjectBuildingException 241 { 242 Model superModel = getSuperModel(); 243 244 superModel.setGroupId( STANDALONE_SUPERPOM_GROUPID ); 245 246 superModel.setArtifactId( STANDALONE_SUPERPOM_ARTIFACTID ); 247 248 superModel.setVersion( STANDALONE_SUPERPOM_VERSION ); 249 250 ProfileManager profileManager = new DefaultProfileManager( container ); 251 252 List activeProfiles; 253 254 profileManager.addProfiles( superModel.getProfiles() ); 255 256 String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID ); 257 258 activeProfiles = injectActiveProfiles( profileManager, superModel ); 259 260 MavenProject project = new MavenProject( superModel ); 261 262 project.setActiveProfiles( activeProfiles ); 263 264 project.setOriginalModel( superModel ); 265 266 try 267 { 268 project = processProjectLogic( "<Super-POM>", project, null, null, true ); 269 270 project.setExecutionRoot( true ); 271 272 return project; 273 } 274 catch ( ModelInterpolationException e ) 275 { 276 throw new ProjectBuildingException( projectId, e.getMessage(), e ); 277 } 278 catch ( InvalidRepositoryException e ) 279 { 280 throw new ProjectBuildingException( projectId, e.getMessage(), e ); 281 } 282 } 283 284 public MavenProject buildWithDependencies( File projectDescriptor, 285 ArtifactRepository localRepository, 286 ProfileManager profileManager ) 287 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException 288 { 289 return buildWithDependencies( projectDescriptor, localRepository, profileManager, null ); 290 } 291 292 294 297 public MavenProject buildWithDependencies( File projectDescriptor, 298 ArtifactRepository localRepository, 299 ProfileManager profileManager, 300 TransferListener transferListener ) 301 throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException 302 { 303 MavenProject project = build( projectDescriptor, localRepository, profileManager ); 304 305 317 Artifact projectArtifact = project.getArtifact(); 319 320 String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() ); 321 322 Map managedVersions = createManagedVersionMap( projectId, project.getDependencyManagement() ); 323 324 ensureMetadataSourceIsInitialized(); 325 326 try 327 { 328 project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) ); 329 } 330 catch ( InvalidDependencyVersionException e ) 331 { 332 throw new ProjectBuildingException( projectId, 333 "Unable to build project due to an invalid dependency version: " + 334 e.getMessage(), e ); 335 } 336 337 if ( transferListener != null ) 338 { 339 wagonManager.setDownloadMonitor( transferListener ); 340 } 341 342 ArtifactResolutionResult result = artifactResolver.resolveTransitively( project.getDependencyArtifacts(), 343 projectArtifact, managedVersions, 344 localRepository, 345 project.getRemoteArtifactRepositories(), 346 artifactMetadataSource ); 347 348 project.setArtifacts( result.getArtifacts() ); 349 350 return project; 351 } 352 353 357 private void ensureMetadataSourceIsInitialized() 358 throws ProjectBuildingException 359 { 360 if ( artifactMetadataSource == null ) 361 { 362 try 363 { 364 artifactMetadataSource = (ArtifactMetadataSource) container.lookup( ArtifactMetadataSource.ROLE ); 365 } 366 catch ( ComponentLookupException e ) 367 { 368 throw new ProjectBuildingException( "all", "Cannot lookup metadata source for building the project.", 369 e ); 370 } 371 } 372 } 373 374 private Map createManagedVersionMap( String projectId, DependencyManagement dependencyManagement ) 375 throws ProjectBuildingException 376 { 377 Map map; 378 if ( dependencyManagement != null && dependencyManagement.getDependencies() != null ) 379 { 380 map = new HashMap (); 381 for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); ) 382 { 383 Dependency d = (Dependency) i.next(); 384 385 try 386 { 387 VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() ); 388 Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), 389 versionRange, d.getType(), 390 d.getClassifier(), d.getScope(), 391 d.isOptional() ); 392 map.put( d.getManagementKey(), artifact ); 393 } 394 catch ( InvalidVersionSpecificationException e ) 395 { 396 throw new ProjectBuildingException( projectId, "Unable to parse version '" + d.getVersion() + 397 "' for dependency '" + d.getManagementKey() + "': " + e.getMessage(), e ); 398 } 399 } 400 } 401 else 402 { 403 map = Collections.EMPTY_MAP; 404 } 405 return map; 406 } 407 408 private MavenProject buildFromSourceFileInternal( File projectDescriptor, 409 ArtifactRepository localRepository, 410 ProfileManager profileManager, 411 boolean checkDistributionManagementStatus ) 412 throws ProjectBuildingException 413 { 414 Model model = readModel( "unknown", projectDescriptor, true ); 415 416 MavenProject project = buildInternal( projectDescriptor.getAbsolutePath(), 417 model, 418 localRepository, 419 buildArtifactRepositories( getSuperModel() ), 420 projectDescriptor, 421 profileManager, 422 true ); 423 424 if ( checkDistributionManagementStatus ) 425 { 426 if ( project.getDistributionManagement() != null && project.getDistributionManagement().getStatus() != null ) 427 { 428 String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() ); 429 430 throw new ProjectBuildingException( projectId, 431 "Invalid project file: distribution status must not be specified for a project outside of the repository" ); 432 } 433 } 434 435 return project; 436 } 437 438 private Model findModelFromRepository( Artifact artifact, 439 List remoteArtifactRepositories, 440 ArtifactRepository localRepository, 441 boolean allowStubModel ) 442 throws ProjectBuildingException 443 { 444 Artifact projectArtifact; 445 446 if ( "pom".equals( artifact.getType() ) ) 448 { 449 projectArtifact = artifact; 450 } 451 else 452 { 453 getLogger().warn( "Attempting to build MavenProject instance for Artifact of type: " + artifact.getType() + "; constructing POM artifact instead." ); 454 455 projectArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(), 456 artifact.getArtifactId(), 457 artifact.getVersion(), 458 artifact.getScope() ); 459 } 460 461 Model model; 462 463 String projectId = ArtifactUtils.versionlessKey( projectArtifact ); 464 465 try 466 { 467 artifactResolver.resolve( projectArtifact, remoteArtifactRepositories, localRepository ); 468 469 File file = projectArtifact.getFile(); 470 471 model = readModel( projectId, file, false ); 472 473 String downloadUrl = null; 474 475 ArtifactStatus status = ArtifactStatus.NONE; 476 477 DistributionManagement distributionManagement = model.getDistributionManagement(); 478 479 if ( distributionManagement != null ) 480 { 481 downloadUrl = distributionManagement.getDownloadUrl(); 482 483 status = ArtifactStatus.valueOf( distributionManagement.getStatus() ); 484 } 485 486 checkStatusAndUpdate( projectArtifact, status, file, remoteArtifactRepositories, localRepository ); 487 488 if ( downloadUrl != null ) 491 { 492 projectArtifact.setDownloadUrl( downloadUrl ); 493 } 494 else 495 { 496 projectArtifact.setDownloadUrl( model.getUrl() ); 497 } 498 } 499 catch ( ArtifactResolutionException e ) 500 { 501 throw new ProjectBuildingException( projectId, "Error getting POM for '" + projectId + "' from the repository: " + e.getMessage(), e ); 502 } 503 catch ( ArtifactNotFoundException e ) 504 { 505 if ( allowStubModel ) 506 { 507 getLogger().debug( "Artifact not found - using stub model: " + e.getMessage() ); 508 509 model = createStubModel( projectArtifact ); 510 } 511 else 512 { 513 throw new ProjectBuildingException( projectId, "POM '" + projectId + "' not found in repository: " + e.getMessage(), e ); 514 } 515 } 516 517 return model; 518 } 519 520 private void checkStatusAndUpdate( Artifact projectArtifact, 521 ArtifactStatus status, File file, 522 List remoteArtifactRepositories, 523 ArtifactRepository localRepository ) 524 throws ArtifactNotFoundException 525 { 526 if ( !projectArtifact.isSnapshot() && status.compareTo( ArtifactStatus.DEPLOYED ) < 0 ) 528 { 529 ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy(); 531 policy.setUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER ); 533 534 if ( policy.checkOutOfDate( new Date ( file.lastModified() ) ) ) 535 { 536 getLogger().info( 537 projectArtifact.getArtifactId() + ": updating metadata due to status of '" + status + "'" ); 538 try 539 { 540 projectArtifact.setResolved( false ); 541 artifactResolver.resolveAlways( projectArtifact, remoteArtifactRepositories, localRepository ); 542 } 543 catch ( ArtifactResolutionException e ) 544 { 545 getLogger().warn( "Error updating POM - using existing version" ); 546 getLogger().debug( "Cause", e ); 547 } 548 catch ( ArtifactNotFoundException e ) 549 { 550 getLogger().warn( "Error updating POM - not found. Removing local copy." ); 551 getLogger().debug( "Cause", e ); 552 file.delete(); 553 throw e; 554 } 555 } 556 } 557 } 558 559 private Model createStubModel( Artifact projectArtifact ) 563 { 564 getLogger().debug( "Using defaults for missing POM " + projectArtifact ); 565 566 Model model = new Model(); 567 568 model.setModelVersion( "4.0.0" ); 569 570 model.setArtifactId( projectArtifact.getArtifactId() ); 571 572 model.setGroupId( projectArtifact.getGroupId() ); 573 574 model.setVersion( projectArtifact.getVersion() ); 575 576 model.setPackaging( projectArtifact.getType() ); 578 579 model.setDistributionManagement( new DistributionManagement() ); 580 581 model.getDistributionManagement().setStatus( ArtifactStatus.GENERATED.toString() ); 582 583 return model; 584 } 585 586 private MavenProject buildInternal( String pomLocation, 590 Model model, 591 ArtifactRepository localRepository, 592 List parentSearchRepositories, 593 File projectDescriptor, 594 ProfileManager externalProfileManager, 595 boolean strict ) 596 throws ProjectBuildingException 597 { 598 File projectDir = null; 599 600 if ( projectDescriptor != null ) 601 { 602 projectDir = projectDescriptor.getAbsoluteFile().getParentFile(); 603 } 604 605 Model superModel = getSuperModel(); 606 607 ProfileManager superProjectProfileManager = new DefaultProfileManager( container ); 608 609 List activeProfiles; 610 611 superProjectProfileManager.addProfiles( superModel.getProfiles() ); 612 613 activeProfiles = injectActiveProfiles( superProjectProfileManager, superModel ); 614 615 MavenProject superProject = new MavenProject( superModel ); 616 617 superProject.setActiveProfiles( activeProfiles ); 618 619 LinkedList lineage = new LinkedList (); 621 622 Set aggregatedRemoteWagonRepositories = new LinkedHashSet (); 627 628 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); 629 630 List activeExternalProfiles; 631 try 632 { 633 if ( externalProfileManager != null ) 634 { 635 activeExternalProfiles = externalProfileManager.getActiveProfiles(); 636 } 637 else 638 { 639 activeExternalProfiles = Collections.EMPTY_LIST; 640 } 641 } 642 catch ( ProfileActivationException e ) 643 { 644 throw new ProjectBuildingException( projectId, "Failed to calculate active external profiles.", e ); 645 } 646 647 for ( Iterator i = activeExternalProfiles.iterator(); i.hasNext(); ) 648 { 649 Profile externalProfile = (Profile) i.next(); 650 651 for ( Iterator repoIterator = externalProfile.getRepositories().iterator(); repoIterator.hasNext(); ) 652 { 653 Repository mavenRepo = (Repository) repoIterator.next(); 654 655 ArtifactRepository artifactRepo = null; 656 try 657 { 658 artifactRepo = ProjectUtils.buildArtifactRepository( mavenRepo, artifactRepositoryFactory, container ); 659 } 660 catch ( InvalidRepositoryException e ) 661 { 662 throw new ProjectBuildingException( projectId, e.getMessage(), e ); 663 } 664 665 aggregatedRemoteWagonRepositories.add( artifactRepo ); 666 } 667 } 668 669 Model originalModel = ModelUtils.cloneModel( model ); 670 671 MavenProject project = null; 672 try 673 { 674 project = assembleLineage( model, 675 lineage, 676 localRepository, 677 projectDir, 678 parentSearchRepositories, 679 aggregatedRemoteWagonRepositories, 680 externalProfileManager, 681 strict ); 682 } 683 catch ( InvalidRepositoryException e ) 684 { 685 throw new ProjectBuildingException( projectId, e.getMessage(), e ); 686 } 687 688 project.setOriginalModel( originalModel ); 689 690 rawProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), new MavenProject( project ) ); 691 692 MavenProject previousProject = superProject; 694 695 Model previous = superProject.getModel(); 696 697 for ( Iterator i = lineage.iterator(); i.hasNext(); ) 698 { 699 MavenProject currentProject = (MavenProject) i.next(); 700 701 Model current = currentProject.getModel(); 702 703 String pathAdjustment = null; 704 705 try 706 { 707 pathAdjustment = previousProject.getModulePathAdjustment( currentProject ); 708 } 709 catch ( IOException e ) 710 { 711 getLogger().debug( "Cannot determine whether " + currentProject.getId() + " is a module of " + previousProject.getId() + ". Reason: " + e.getMessage(), e ); 712 } 713 714 modelInheritanceAssembler.assembleModelInheritance( current, previous, pathAdjustment ); 715 716 previous = current; 717 previousProject = currentProject; 718 } 719 720 List repositories = new ArrayList ( aggregatedRemoteWagonRepositories ); 722 723 List superRepositories = buildArtifactRepositories( superModel ); 724 725 for ( Iterator i = superRepositories.iterator(); i.hasNext(); ) 726 { 727 ArtifactRepository repository = (ArtifactRepository) i.next(); 728 729 if ( !repositories.contains( repository ) ) 730 { 731 repositories.add( repository ); 732 } 733 } 734 735 try 736 { 737 project = processProjectLogic( pomLocation, project, externalProfileManager, projectDir, strict ); 738 } 739 catch ( ModelInterpolationException e ) 740 { 741 throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e ); 742 } 743 catch ( InvalidRepositoryException e ) 744 { 745 throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e ); 746 } 747 748 processedProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project ); 749 750 if ( projectDescriptor != null ) 753 { 754 pathTranslator.alignToBaseDirectory( project.getModel(), projectDescriptor.getParentFile() ); 756 757 Build build = project.getBuild(); 758 759 project.addCompileSourceRoot( build.getSourceDirectory() ); 760 761 project.addScriptSourceRoot( build.getScriptSourceDirectory() ); 762 763 project.addTestCompileSourceRoot( build.getTestSourceDirectory() ); 764 765 project.setFile( projectDescriptor ); 767 } 768 769 MavenProject rawParent = project.getParent(); 770 771 if ( rawParent != null ) 772 { 773 String cacheKey = createCacheKey( rawParent.getGroupId(), rawParent.getArtifactId(), rawParent.getVersion() ); 774 775 MavenProject processedParent = (MavenProject) processedProjectCache.get( cacheKey ); 776 777 if ( processedParent != null ) 779 { 780 project.setParent( processedParent ); 781 } 782 } 783 784 return project; 785 } 786 787 private String safeVersionlessKey( String groupId, String artifactId ) 788 { 789 String gid = groupId; 790 791 if ( StringUtils.isEmpty( gid ) ) 792 { 793 gid = "unknown"; 794 } 795 796 String aid = artifactId; 797 798 if ( StringUtils.isEmpty( aid ) ) 799 { 800 aid = "unknown"; 801 } 802 803 return ArtifactUtils.versionlessKey( gid, aid ); 804 } 805 806 private List buildArtifactRepositories( Model model ) 807 throws ProjectBuildingException 808 { 809 try 810 { 811 return ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory, container ); 812 } 813 catch ( InvalidRepositoryException e ) 814 { 815 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); 816 817 throw new ProjectBuildingException( projectId, e.getMessage(), e ); 818 } 819 } 820 821 828 private MavenProject processProjectLogic( String pomLocation, 829 MavenProject project, 830 ProfileManager profileMgr, 831 File projectDir, 832 boolean strict ) 833 throws ProjectBuildingException, ModelInterpolationException, InvalidRepositoryException 834 { 835 Model model = project.getModel(); 836 837 List activeProfiles = project.getActiveProfiles(); 838 839 if ( activeProfiles == null ) 840 { 841 activeProfiles = new ArrayList (); 842 } 843 844 List injectedProfiles = injectActiveProfiles( profileMgr, model ); 845 846 activeProfiles.addAll( injectedProfiles ); 847 848 Map context = new HashMap ( System.getProperties() ); 852 853 if ( projectDir != null ) 854 { 855 context.put( "basedir", projectDir.getAbsolutePath() ); 856 } 857 858 context.put( "build.directory", null ); 863 context.put( "build.outputDirectory", null ); 864 context.put( "build.testOutputDirectory", null ); 865 context.put( "build.sourceDirectory", null ); 866 context.put( "build.testSourceDirectory", null ); 867 868 model = modelInterpolator.interpolate( model, context, strict ); 869 870 modelDefaultsInjector.injectDefaults( model ); 872 873 MavenProject parentProject = project.getParent(); 874 875 Model originalModel = project.getOriginalModel(); 876 877 project = new MavenProject( model ); 879 880 project.setOriginalModel( originalModel ); 881 882 project.setActiveProfiles( activeProfiles ); 883 884 Artifact projectArtifact = artifactFactory.createBuildArtifact( project.getGroupId(), project.getArtifactId(), 886 project.getVersion(), project.getPackaging() ); 887 project.setArtifact( projectArtifact ); 888 889 project.setPluginArtifactRepositories( ProjectUtils.buildArtifactRepositories( model.getPluginRepositories(), 890 artifactRepositoryFactory, 891 container ) ); 892 893 DistributionManagement dm = model.getDistributionManagement(); 894 if ( dm != null ) 895 { 896 ArtifactRepository repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getRepository(), 897 artifactRepositoryFactory, 898 container ); 899 project.setReleaseArtifactRepository( repo ); 900 901 if ( dm.getSnapshotRepository() != null ) 902 { 903 repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getSnapshotRepository(), 904 artifactRepositoryFactory, container ); 905 project.setSnapshotArtifactRepository( repo ); 906 } 907 } 908 909 project.setParent( parentProject ); 910 911 if ( parentProject != null ) 912 { 913 Artifact parentArtifact = artifactFactory.createParentArtifact( parentProject.getGroupId(), 914 parentProject.getArtifactId(), 915 parentProject.getVersion() ); 916 project.setParentArtifact( parentArtifact ); 917 } 918 919 ModelValidationResult validationResult = validator.validate( model ); 921 922 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); 923 924 if ( validationResult.getMessageCount() > 0 ) 925 { 926 throw new InvalidProjectModelException( projectId, pomLocation, "Failed to validate POM", 927 validationResult ); 928 } 929 930 project.setRemoteArtifactRepositories( 931 ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory, container ) ); 932 933 project.setPluginArtifacts( createPluginArtifacts( projectId, project.getBuildPlugins() ) ); 935 936 project.setReportArtifacts( createReportArtifacts( projectId, project.getReportPlugins() ) ); 937 938 project.setExtensionArtifacts( createExtensionArtifacts( projectId, project.getBuildExtensions() ) ); 939 940 return project; 941 } 942 943 946 private MavenProject assembleLineage( Model model, 947 LinkedList lineage, 948 ArtifactRepository localRepository, 949 File projectDir, 950 List parentSearchRepositories, 951 Set aggregatedRemoteWagonRepositories, 952 ProfileManager externalProfileManager, 953 boolean strict ) 954 throws ProjectBuildingException, InvalidRepositoryException 955 { 956 if ( !model.getRepositories().isEmpty() ) 957 { 958 List respositories = buildArtifactRepositories( model ); 959 960 for ( Iterator it = respositories.iterator(); it.hasNext(); ) 961 { 962 ArtifactRepository repository = (ArtifactRepository) it.next(); 963 964 if ( !aggregatedRemoteWagonRepositories.contains( repository ) ) 965 { 966 aggregatedRemoteWagonRepositories.add( repository ); 967 } 968 } 969 } 970 971 ProfileManager profileManager = new DefaultProfileManager( container ); 972 973 if ( externalProfileManager != null ) 974 { 975 profileManager.explicitlyActivate( externalProfileManager.getExplicitlyActivatedIds() ); 976 977 profileManager.explicitlyDeactivate( externalProfileManager.getExplicitlyDeactivatedIds() ); 978 } 979 980 List activeProfiles; 981 982 try 983 { 984 profileManager.addProfiles( model.getProfiles() ); 985 986 loadProjectExternalProfiles( profileManager, projectDir ); 987 988 activeProfiles = injectActiveProfiles( profileManager, model ); 989 } 990 catch ( ProfileActivationException e ) 991 { 992 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); 993 994 throw new ProjectBuildingException( projectId, "Failed to activate local (project-level) build profiles: " + e.getMessage(), e ); 995 } 996 997 MavenProject project = new MavenProject( model ); 998 999 project.setActiveProfiles( activeProfiles ); 1000 1001 lineage.addFirst( project ); 1002 1003 Parent parentModel = model.getParent(); 1004 1005 if ( parentModel != null ) 1006 { 1007 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); 1008 1009 if ( StringUtils.isEmpty( parentModel.getGroupId() ) ) 1010 { 1011 throw new ProjectBuildingException( projectId, "Missing groupId element from parent element" ); 1012 } 1013 else if ( StringUtils.isEmpty( parentModel.getArtifactId() ) ) 1014 { 1015 throw new ProjectBuildingException( projectId, "Missing artifactId element from parent element" ); 1016 } 1017 else if ( parentModel.getGroupId().equals( model.getGroupId() ) && 1018 parentModel.getArtifactId().equals( model.getArtifactId() ) ) 1019 { 1020 throw new ProjectBuildingException( projectId, "Parent element is a duplicate of " + "the current project " ); 1021 } 1022 else if ( StringUtils.isEmpty( parentModel.getVersion() ) ) 1023 { 1024 throw new ProjectBuildingException( projectId, "Missing version element from parent element" ); 1025 } 1026 1027 File parentDescriptor = null; 1029 1030 model = null; 1031 1032 String parentKey = createCacheKey( parentModel.getGroupId(), parentModel.getArtifactId(), parentModel.getVersion() ); 1033 MavenProject parentProject = (MavenProject) rawProjectCache.get( parentKey ); 1034 1035 if ( parentProject != null ) 1036 { 1037 model = ModelUtils.cloneModel( parentProject.getModel() ); 1038 1039 parentDescriptor = parentProject.getFile(); 1040 } 1041 1042 String parentRelativePath = parentModel.getRelativePath(); 1043 1044 if ( model == null && projectDir != null && StringUtils.isNotEmpty( parentRelativePath ) ) 1047 { 1048 parentDescriptor = new File ( projectDir, parentRelativePath ); 1049 1050 if ( getLogger().isDebugEnabled() ) 1051 { 1052 getLogger().debug( "Searching for parent-POM: " + parentModel.getId() + " of project: " + project.getId() + " in relative path: " + parentRelativePath ); 1053 } 1054 1055 if ( parentDescriptor.isDirectory() ) 1056 { 1057 if ( getLogger().isDebugEnabled() ) 1058 { 1059 getLogger().debug( "Path specified in <relativePath/> (" + parentRelativePath + 1060 ") is a directory. Searching for 'pom.xml' within this directory." ); 1061 } 1062 1063 parentDescriptor = new File ( parentDescriptor, "pom.xml" ); 1064 1065 if ( !parentDescriptor.exists() ) 1066 { 1067 if ( getLogger().isDebugEnabled() ) 1068 { 1069 getLogger().debug( "Parent-POM: " + parentModel.getId() + " for project: " + project.getId() + " cannot be loaded from relative path: " + parentDescriptor + "; path does not exist." ); 1070 } 1071 1072 parentDescriptor = null; 1073 } 1074 } 1075 1076 try 1077 { 1078 parentDescriptor = parentDescriptor.getCanonicalFile(); 1079 } 1080 catch ( IOException e ) 1081 { 1082 getLogger().debug( "Failed to canonicalize potential parent POM: \'" + parentDescriptor + "\'", e ); 1083 1084 parentDescriptor = null; 1085 } 1086 1087 if ( parentDescriptor != null && parentDescriptor.exists() ) 1088 { 1089 Model candidateParent = readModel( projectId, parentDescriptor, strict ); 1090 1091 String candidateParentGroupId = candidateParent.getGroupId(); 1092 if ( candidateParentGroupId == null && candidateParent.getParent() != null ) 1093 { 1094 candidateParentGroupId = candidateParent.getParent().getGroupId(); 1095 } 1096 1097 String candidateParentVersion = candidateParent.getVersion(); 1098 if ( candidateParentVersion == null && candidateParent.getParent() != null ) 1099 { 1100 candidateParentVersion = candidateParent.getParent().getVersion(); 1101 } 1102 1103 if ( parentModel.getGroupId().equals( candidateParentGroupId ) && 1104 parentModel.getArtifactId().equals( candidateParent.getArtifactId() ) && 1105 parentModel.getVersion().equals( candidateParentVersion ) ) 1106 { 1107 model = candidateParent; 1108 1109 getLogger().debug( "Using parent-POM from the project hierarchy at: \'" + 1110 parentModel.getRelativePath() + "\' for project: " + project.getId() ); 1111 } 1112 else 1113 { 1114 getLogger().debug( "Invalid parent-POM referenced by relative path '" + 1115 parentModel.getRelativePath() + "' in parent specification in " + project.getId() + ":" + 1116 "\n Specified: " + parentModel.getId() + "\n Found: " + candidateParent.getId() ); 1117 } 1118 } 1119 else if ( getLogger().isDebugEnabled() ) 1120 { 1121 getLogger().debug( "Parent-POM: " + parentModel.getId() + " not found in relative path: " + parentRelativePath ); 1122 } 1123 } 1124 1125 Artifact parentArtifact = null; 1126 1127 if ( model == null ) 1129 { 1130 1139 List remoteRepositories = new ArrayList ( aggregatedRemoteWagonRepositories ); 1142 remoteRepositories.addAll( parentSearchRepositories ); 1143 1144 if ( getLogger().isDebugEnabled() ) 1145 { 1146 getLogger().debug( 1147 "Retrieving parent-POM: " + parentModel.getId() + " for project: " 1148 + project.getId() + " from the repository." ); 1149 } 1150 1151 parentArtifact = artifactFactory.createParentArtifact( parentModel.getGroupId(), 1152 parentModel.getArtifactId(), 1153 parentModel.getVersion() ); 1154 1155 try 1156 { 1157 model = findModelFromRepository( parentArtifact, remoteRepositories, localRepository, false ); 1158 } 1159 catch( ProjectBuildingException e ) 1160 { 1161 throw new ProjectBuildingException( project.getId(), "Cannot find parent: " + e.getProjectId() + " for project: " + project.getId(), e ); 1162 } 1163 } 1164 1165 if ( model != null && !"pom".equals( model.getPackaging() ) ) 1166 { 1167 throw new ProjectBuildingException( projectId, "Parent: " + model.getId() + " of project: " + 1168 projectId + " has wrong packaging: " + model.getPackaging() + ". Must be 'pom'." ); 1169 } 1170 1171 File parentProjectDir = null; 1172 if ( parentDescriptor != null ) 1173 { 1174 parentProjectDir = parentDescriptor.getParentFile(); 1175 } 1176 MavenProject parent = assembleLineage( model, lineage, localRepository, parentProjectDir, 1177 parentSearchRepositories, aggregatedRemoteWagonRepositories, 1178 externalProfileManager, strict ); 1179 parent.setFile( parentDescriptor ); 1180 1181 project.setParent( parent ); 1182 1183 project.setParentArtifact( parentArtifact ); 1184 } 1185 1186 return project; 1187 } 1188 1189 private List injectActiveProfiles( ProfileManager profileManager, Model model ) 1190 throws ProjectBuildingException 1191 { 1192 List activeProfiles; 1193 1194 if ( profileManager != null ) 1195 { 1196 try 1197 { 1198 activeProfiles = profileManager.getActiveProfiles(); 1199 } 1200 catch ( ProfileActivationException e ) 1201 { 1202 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); 1203 1204 throw new ProjectBuildingException( projectId, e.getMessage(), e ); 1205 } 1206 1207 for ( Iterator it = activeProfiles.iterator(); it.hasNext(); ) 1208 { 1209 Profile profile = (Profile) it.next(); 1210 1211 profileInjector.inject( profile, model ); 1212 } 1213 } 1214 else 1215 { 1216 activeProfiles = Collections.EMPTY_LIST; 1217 } 1218 1219 return activeProfiles; 1220 } 1221 1222 private void loadProjectExternalProfiles( ProfileManager profileManager, File projectDir ) 1223 throws ProfileActivationException 1224 { 1225 if ( projectDir != null ) 1226 { 1227 try 1228 { 1229 ProfilesRoot root = profilesBuilder.buildProfiles( projectDir ); 1230 1231 if ( root != null ) 1232 { 1233 List active = root.getActiveProfiles(); 1234 1235 if ( active != null && !active.isEmpty() ) 1236 { 1237 profileManager.explicitlyActivate( root.getActiveProfiles() ); 1238 } 1239 1240 for ( Iterator it = root.getProfiles().iterator(); it.hasNext(); ) 1241 { 1242 org.apache.maven.profiles.Profile rawProfile = (org.apache.maven.profiles.Profile) it.next(); 1243 1244 Profile converted = ProfilesConversionUtils.convertFromProfileXmlProfile( rawProfile ); 1245 1246 profileManager.addProfile( converted ); 1247 } 1248 } 1249 } 1250 catch ( IOException e ) 1251 { 1252 throw new ProfileActivationException( "Cannot read profiles.xml resource from directory: " + projectDir, 1253 e ); 1254 } 1255 catch ( XmlPullParserException e ) 1256 { 1257 throw new ProfileActivationException( 1258 "Cannot parse profiles.xml resource from directory: " + projectDir, e ); 1259 } 1260 } 1261 } 1262 1263 private Model readModel( String projectId, File file, boolean strict ) 1264 throws ProjectBuildingException 1265 { 1266 Reader reader = null; 1267 try 1268 { 1269 reader = new FileReader ( file ); 1270 return readModel( projectId, file.getAbsolutePath(), reader, strict ); 1271 } 1272 catch ( FileNotFoundException e ) 1273 { 1274 throw new ProjectBuildingException( projectId, 1275 "Could not find the model file '" + file.getAbsolutePath() + "'.", e ); 1276 } 1277 catch ( IOException e ) 1278 { 1279 throw new ProjectBuildingException( projectId, "Failed to build model from file '" + 1280 file.getAbsolutePath() + "'.\nError: \'" + e.getLocalizedMessage() + "\'", e ); 1281 } 1282 finally 1283 { 1284 IOUtil.close( reader ); 1285 } 1286 } 1287 1288 private Model readModel( String projectId, String pomLocation, Reader reader, boolean strict ) 1289 throws IOException , InvalidProjectModelException 1290 { 1291 StringWriter sw = new StringWriter (); 1292 1293 IOUtil.copy( reader, sw ); 1294 1295 String modelSource = sw.toString(); 1296 1297 if ( modelSource.indexOf( "<modelVersion>4.0.0" ) < 0 ) 1298 { 1299 throw new InvalidProjectModelException( projectId, pomLocation, "Not a v4.0.0 POM." ); 1300 } 1301 1302 StringReader sReader = new StringReader ( modelSource ); 1303 1304 try 1305 { 1306 return modelReader.read( sReader, strict ); 1307 } 1308 catch ( XmlPullParserException e ) 1309 { 1310 throw new InvalidProjectModelException( projectId, pomLocation, 1311 "Parse error reading POM. Reason: " + e.getMessage(), e ); 1312 } 1313 } 1314 1315 private Model readModel( String projectId, URL url, boolean strict ) 1316 throws ProjectBuildingException 1317 { 1318 InputStreamReader reader = null; 1319 try 1320 { 1321 reader = new InputStreamReader ( url.openStream() ); 1322 return readModel( projectId, url.toExternalForm(), reader, strict ); 1323 } 1324 catch ( IOException e ) 1325 { 1326 throw new ProjectBuildingException( projectId, "Failed build model from URL \'" + url.toExternalForm() + 1327 "\'\nError: \'" + e.getLocalizedMessage() + "\'", e ); 1328 } 1329 finally 1330 { 1331 IOUtil.close( reader ); 1332 } 1333 } 1334 1335 private static String createCacheKey( String groupId, String artifactId, String version ) 1336 { 1337 return groupId + ":" + artifactId + ":" + version; 1338 } 1339 1340 protected Set createPluginArtifacts( String projectId, List plugins ) 1341 throws ProjectBuildingException 1342 { 1343 Set pluginArtifacts = new HashSet (); 1344 1345 for ( Iterator i = plugins.iterator(); i.hasNext(); ) 1346 { 1347 Plugin p = (Plugin) i.next(); 1348 1349 String version; 1350 if ( StringUtils.isEmpty( p.getVersion() ) ) 1351 { 1352 version = "RELEASE"; 1353 } 1354 else 1355 { 1356 version = p.getVersion(); 1357 } 1358 1359 Artifact artifact; 1360 try 1361 { 1362 artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(), 1363 VersionRange.createFromVersionSpec( version ) ); 1364 } 1365 catch ( InvalidVersionSpecificationException e ) 1366 { 1367 throw new ProjectBuildingException( projectId, "Unable to parse version '" + version + 1368 "' for plugin '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " + 1369 e.getMessage(), e ); 1370 } 1371 1372 if ( artifact != null ) 1373 { 1374 pluginArtifacts.add( artifact ); 1375 } 1376 } 1377 1378 return pluginArtifacts; 1379 } 1380 1381 protected Set createReportArtifacts( String projectId, List reports ) 1383 throws ProjectBuildingException 1384 { 1385 Set pluginArtifacts = new HashSet (); 1386 1387 if ( reports != null ) 1388 { 1389 for ( Iterator i = reports.iterator(); i.hasNext(); ) 1390 { 1391 ReportPlugin p = (ReportPlugin) i.next(); 1392 1393 String version; 1394 if ( StringUtils.isEmpty( p.getVersion() ) ) 1395 { 1396 version = "RELEASE"; 1397 } 1398 else 1399 { 1400 version = p.getVersion(); 1401 } 1402 1403 Artifact artifact; 1404 try 1405 { 1406 artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(), 1407 VersionRange.createFromVersionSpec( version ) ); 1408 } 1409 catch ( InvalidVersionSpecificationException e ) 1410 { 1411 throw new ProjectBuildingException( projectId, "Unable to parse version '" + version + 1412 "' for report '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " + 1413 e.getMessage(), e ); 1414 } 1415 1416 if ( artifact != null ) 1417 { 1418 pluginArtifacts.add( artifact ); 1419 } 1420 } 1421 } 1422 1423 return pluginArtifacts; 1424 } 1425 1426 protected Set createExtensionArtifacts( String projectId, List extensions ) 1428 throws ProjectBuildingException 1429 { 1430 Set extensionArtifacts = new HashSet (); 1431 1432 if ( extensions != null ) 1433 { 1434 for ( Iterator i = extensions.iterator(); i.hasNext(); ) 1435 { 1436 Extension ext = (Extension) i.next(); 1437 1438 String version; 1439 if ( StringUtils.isEmpty( ext.getVersion() ) ) 1440 { 1441 version = "RELEASE"; 1442 } 1443 else 1444 { 1445 version = ext.getVersion(); 1446 } 1447 1448 Artifact artifact; 1449 try 1450 { 1451 VersionRange versionRange = VersionRange.createFromVersionSpec( version ); 1452 artifact = 1453 artifactFactory.createExtensionArtifact( ext.getGroupId(), ext.getArtifactId(), versionRange ); 1454 } 1455 catch ( InvalidVersionSpecificationException e ) 1456 { 1457 throw new ProjectBuildingException( projectId, "Unable to parse version '" + version + 1458 "' for extension '" + ArtifactUtils.versionlessKey( ext.getGroupId(), ext.getArtifactId() ) + 1459 "': " + e.getMessage(), e ); 1460 } 1461 1462 if ( artifact != null ) 1463 { 1464 extensionArtifacts.add( artifact ); 1465 } 1466 } 1467 } 1468 1469 return extensionArtifacts; 1470 } 1471 1472 1476 private Model getSuperModel() 1477 throws ProjectBuildingException 1478 { 1479 URL url = DefaultMavenProjectBuilder.class.getResource( "pom-" + MAVEN_MODEL_VERSION + ".xml" ); 1480 1481 String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID ); 1482 1483 return readModel( projectId, url, true ); 1484 } 1485 1486 public void contextualize( Context context ) 1487 throws ContextException 1488 { 1489 this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); 1490 } 1491} 1492 | Popular Tags |