Save This Page
Home » maven-2.0.9-src » org.apache » maven » project » [javadoc | source]
    1   package org.apache.maven.project;
    2   
    3   /*
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
   10    * with the License.  You may obtain a copy of the License at
   11    *
   12    *  http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing,
   15    * software distributed under the License is distributed on an
   16    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   17    * KIND, either express or implied.  See the License for the
   18    * specific language governing permissions and limitations
   19    * under the License.
   20    */
   21   
   22   import org.apache.maven.artifact.Artifact;
   23   import org.apache.maven.artifact.ArtifactStatus;
   24   import org.apache.maven.artifact.ArtifactUtils;
   25   import org.apache.maven.artifact.InvalidRepositoryException;
   26   import org.apache.maven.artifact.factory.ArtifactFactory;
   27   import org.apache.maven.artifact.manager.WagonManager;
   28   import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
   29   import org.apache.maven.artifact.repository.ArtifactRepository;
   30   import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
   31   import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
   32   import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
   33   import org.apache.maven.artifact.resolver.ArtifactResolutionException;
   34   import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
   35   import org.apache.maven.artifact.resolver.ArtifactResolver;
   36   import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
   37   import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
   38   import org.apache.maven.artifact.versioning.ManagedVersionMap;
   39   import org.apache.maven.artifact.versioning.VersionRange;
   40   import org.apache.maven.model.Build;
   41   import org.apache.maven.model.Dependency;
   42   import org.apache.maven.model.DependencyManagement;
   43   import org.apache.maven.model.DistributionManagement;
   44   import org.apache.maven.model.Exclusion;
   45   import org.apache.maven.model.Extension;
   46   import org.apache.maven.model.Model;
   47   import org.apache.maven.model.Parent;
   48   import org.apache.maven.model.Plugin;
   49   import org.apache.maven.model.Profile;
   50   import org.apache.maven.model.ReportPlugin;
   51   import org.apache.maven.model.Repository;
   52   import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
   53   import org.apache.maven.profiles.DefaultProfileManager;
   54   import org.apache.maven.profiles.MavenProfilesBuilder;
   55   import org.apache.maven.profiles.ProfileManager;
   56   import org.apache.maven.profiles.ProfilesConversionUtils;
   57   import org.apache.maven.profiles.ProfilesRoot;
   58   import org.apache.maven.profiles.activation.ProfileActivationException;
   59   import org.apache.maven.project.artifact.InvalidDependencyVersionException;
   60   import org.apache.maven.project.inheritance.ModelInheritanceAssembler;
   61   import org.apache.maven.project.injection.ModelDefaultsInjector;
   62   import org.apache.maven.project.injection.ProfileInjector;
   63   import org.apache.maven.project.interpolation.ModelInterpolationException;
   64   import org.apache.maven.project.interpolation.ModelInterpolator;
   65   import org.apache.maven.project.path.PathTranslator;
   66   import org.apache.maven.project.validation.ModelValidationResult;
   67   import org.apache.maven.project.validation.ModelValidator;
   68   import org.apache.maven.wagon.events.TransferListener;
   69   import org.codehaus.plexus.PlexusConstants;
   70   import org.codehaus.plexus.PlexusContainer;
   71   import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
   72   import org.codehaus.plexus.context.Context;
   73   import org.codehaus.plexus.context.ContextException;
   74   import org.codehaus.plexus.logging.AbstractLogEnabled;
   75   import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
   76   import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
   77   import org.codehaus.plexus.util.IOUtil;
   78   import org.codehaus.plexus.util.ReaderFactory;
   79   import org.codehaus.plexus.util.StringUtils;
   80   import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
   81   
   82   import java.io.File;
   83   import java.io.FileNotFoundException;
   84   import java.io.IOException;
   85   import java.io.Reader;
   86   import java.io.StringReader;
   87   import java.net.URL;
   88   import java.util.ArrayList;
   89   import java.util.Collections;
   90   import java.util.Date;
   91   import java.util.HashMap;
   92   import java.util.HashSet;
   93   import java.util.Iterator;
   94   import java.util.LinkedHashSet;
   95   import java.util.LinkedList;
   96   import java.util.List;
   97   import java.util.Map;
   98   import java.util.Properties;
   99   import java.util.Set;
  100   import java.util.TreeMap;
  101   
  102   /*:apt
  103   
  104    -----
  105    POM lifecycle
  106    -----
  107   
  108   POM Lifecycle
  109   
  110    Order of operations when building a POM
  111   
  112    * inheritance
  113    * path translation
  114    * interpolation
  115    * defaults injection
  116   
  117    Current processing is:
  118   
  119    * inheritance
  120    * interpolation
  121    * defaults injection
  122    * path translation
  123   
  124    I'm not sure how this is working at all ... i think i have a case where this is failing but i need to
  125    encapsulate as a test so i can fix it. Also need to think of the in working build directory versus looking
  126    things up from the repository i.e buildFromSource vs buildFromRepository.
  127   
  128   Notes
  129   
  130    * when the model is read it may not have a groupId, as it must be inherited
  131   
  132    * the inheritance assembler must use models that are unadulterated!
  133   
  134   */
  135   
  136   /**
  137    * @version $Id: DefaultMavenProjectBuilder.java 644411 2008-04-03 17:15:48Z jdcasey $
  138    */
  139   public class DefaultMavenProjectBuilder
  140       extends AbstractLogEnabled
  141       implements MavenProjectBuilder, Initializable, Contextualizable
  142   {
  143       // TODO: remove
  144       private PlexusContainer container;
  145   
  146       protected MavenProfilesBuilder profilesBuilder;
  147   
  148       protected ArtifactResolver artifactResolver;
  149   
  150       protected ArtifactMetadataSource artifactMetadataSource;
  151   
  152       private ArtifactFactory artifactFactory;
  153   
  154       private ModelInheritanceAssembler modelInheritanceAssembler;
  155   
  156       private ProfileInjector profileInjector;
  157   
  158       private ModelValidator validator;
  159   
  160       private Map rawProjectCache = new HashMap();
  161   
  162       private Map processedProjectCache = new HashMap();
  163   
  164       // TODO: make it a component
  165       private MavenXpp3Reader modelReader;
  166   
  167       private PathTranslator pathTranslator;
  168   
  169       private ModelDefaultsInjector modelDefaultsInjector;
  170   
  171       private ModelInterpolator modelInterpolator;
  172   
  173       private ArtifactRepositoryFactory artifactRepositoryFactory;
  174   
  175       // ----------------------------------------------------------------------
  176       // I am making this available for use with a new method that takes a
  177       // a monitor wagon monitor as a parameter so that tools can use the
  178       // methods here and receive callbacks. MNG-1015
  179       // ----------------------------------------------------------------------
  180   
  181       private WagonManager wagonManager;
  182   
  183       public static final String MAVEN_MODEL_VERSION = "4.0.0";
  184   
  185       public void initialize()
  186       {
  187           modelReader = new MavenXpp3Reader();
  188       }
  189   
  190       // ----------------------------------------------------------------------
  191       // MavenProjectBuilder Implementation
  192       // ----------------------------------------------------------------------
  193   
  194       public MavenProject build( File pom,
  195                                  ProjectBuilderConfiguration config )
  196           throws ProjectBuildingException
  197       {
  198           return buildFromSourceFileInternal( pom, config, true );
  199       }
  200   
  201       public MavenProject build( File pom,
  202                                  ProjectBuilderConfiguration config,
  203                                  boolean checkDistributionManagementStatus )
  204           throws ProjectBuildingException
  205       {
  206           return buildFromSourceFileInternal( pom, config, checkDistributionManagementStatus );
  207       }
  208   
  209       public MavenProject build( File projectDescriptor,
  210                                  ArtifactRepository localRepository,
  211                                  ProfileManager profileManager )
  212           throws ProjectBuildingException
  213       {
  214           ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager );
  215           return buildFromSourceFileInternal( projectDescriptor, config, true );
  216       }
  217   
  218       public MavenProject build( File projectDescriptor,
  219                                  ArtifactRepository localRepository,
  220                                  ProfileManager profileManager,
  221                                  boolean checkDistributionManagementStatus )
  222           throws ProjectBuildingException
  223       {
  224           ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager );
  225           return buildFromSourceFileInternal( projectDescriptor, config, checkDistributionManagementStatus );
  226       }
  227   
  228       // jvz:note
  229       // When asked for something from the repository are we getting it from the reactor? Yes, when using this call
  230       // we are assuming that the reactor has been run and we have collected the projects required to satisfy it0042
  231       // which means the projects in the reactor are required for finding classes in <project>/target/classes. Not
  232       // sure this is ideal. I remove all caching from the builder and all reactor related ITs which assume
  233       // access to simbling project resources failed.
  234       public MavenProject buildFromRepository( Artifact artifact,
  235                                                List remoteArtifactRepositories,
  236                                                ArtifactRepository localRepository,
  237                                                boolean allowStubModel )
  238           throws ProjectBuildingException
  239       {
  240           String cacheKey = createCacheKey( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
  241   
  242           MavenProject project = (MavenProject) processedProjectCache.get( cacheKey );
  243   
  244           if ( project != null )
  245           {
  246               return project;
  247           }
  248   
  249           Model model = findModelFromRepository( artifact, remoteArtifactRepositories, localRepository, allowStubModel );
  250   
  251           ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository );
  252   
  253           return buildInternal( "Artifact [" + artifact + "]", model, config, remoteArtifactRepositories,
  254                                 null, false );
  255       }
  256   
  257       public MavenProject buildFromRepository( Artifact artifact,
  258                                                List remoteArtifactRepositories,
  259                                                ArtifactRepository localRepository )
  260           throws ProjectBuildingException
  261       {
  262           return buildFromRepository( artifact, remoteArtifactRepositories, localRepository, true );
  263       }
  264   
  265       // what is using this externally? jvz.
  266       public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository )
  267           throws ProjectBuildingException
  268       {
  269           //TODO mkleint - use the (Container, Properties) constructor to make system properties embeddable
  270           ProfileManager profileManager = new DefaultProfileManager( container );
  271   
  272           return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository )
  273                                                                                       .setGlobalProfileManager( profileManager ) );
  274       }
  275   
  276       public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository,
  277                                                        ProfileManager profileManager )
  278           throws ProjectBuildingException
  279       {
  280           return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository )
  281                                                                                       .setGlobalProfileManager( profileManager ) );
  282       }
  283   
  284       public MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration config )
  285           throws ProjectBuildingException
  286       {
  287           Model superModel = getSuperModel();
  288   
  289           superModel.setGroupId( STANDALONE_SUPERPOM_GROUPID );
  290   
  291           superModel.setArtifactId( STANDALONE_SUPERPOM_ARTIFACTID );
  292   
  293           superModel.setVersion( STANDALONE_SUPERPOM_VERSION );
  294   
  295   
  296           List activeProfiles;
  297   
  298           ProfileManager profileManager = config.getGlobalProfileManager();
  299   
  300           if ( profileManager == null )
  301           {
  302               profileManager = new DefaultProfileManager( container );
  303           }
  304   
  305           profileManager.addProfiles( superModel.getProfiles() );
  306   
  307           String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID );
  308   
  309           activeProfiles = injectActiveProfiles( profileManager, superModel );
  310   
  311           MavenProject project = new MavenProject( superModel );
  312   
  313           project.setManagedVersionMap(
  314               createManagedVersionMap( projectId, superModel.getDependencyManagement(), null ) );
  315   
  316           project.setActiveProfiles( activeProfiles );
  317   
  318           project.setOriginalModel( superModel );
  319   
  320           try
  321           {
  322               project = processProjectLogic( "<Super-POM>", project, config, null, null, true, true );
  323   
  324               project.setExecutionRoot( true );
  325   
  326               return project;
  327           }
  328           catch ( ModelInterpolationException e )
  329           {
  330               throw new ProjectBuildingException( projectId, e.getMessage(), e );
  331           }
  332           catch ( InvalidRepositoryException e )
  333           {
  334               throw new ProjectBuildingException( projectId, e.getMessage(), e );
  335           }
  336       }
  337   
  338       public MavenProject buildWithDependencies( File projectDescriptor,
  339                                                  ArtifactRepository localRepository,
  340                                                  ProfileManager profileManager )
  341           throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
  342       {
  343           return buildWithDependencies( projectDescriptor, localRepository, profileManager, null );
  344       }
  345   
  346       // note:jvz This was added for the embedder.
  347   
  348       /** @todo move to metadatasource itself? */
  349       public MavenProject buildWithDependencies( File projectDescriptor,
  350                                                  ArtifactRepository localRepository,
  351                                                  ProfileManager profileManager,
  352                                                  TransferListener transferListener )
  353           throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
  354       {
  355           MavenProject project = build( projectDescriptor, localRepository, profileManager, false );
  356   
  357           // ----------------------------------------------------------------------
  358           // Typically when the project builder is being used from maven proper
  359           // the transitive dependencies will not be resolved here because this
  360           // requires a lot of work when we may only be interested in running
  361           // something simple like 'm2 clean'. So the artifact collector is used
  362           // in the dependency resolution phase if it is required by any of the
  363           // goals being executed. But when used as a component in another piece
  364           // of code people may just want to build maven projects and have the
  365           // dependencies resolved for whatever reason: this is why we keep
  366           // this snippet of code here.
  367           // ----------------------------------------------------------------------
  368   
  369           // TODO: such a call in MavenMetadataSource too - packaging not really the intention of type
  370           Artifact projectArtifact = project.getArtifact();
  371   
  372           String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() );
  373   
  374           // Map managedVersions = createManagedVersionMap( projectId, project.getDependencyManagement() );
  375           Map managedVersions = project.getManagedVersionMap();
  376   
  377           ensureMetadataSourceIsInitialized();
  378   
  379           try
  380           {
  381               project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) );
  382           }
  383           catch ( InvalidDependencyVersionException e )
  384           {
  385               throw new ProjectBuildingException( projectId,
  386                                                   "Unable to build project due to an invalid dependency version: " +
  387                                                       e.getMessage(), e );
  388           }
  389   
  390           if ( transferListener != null )
  391           {
  392               wagonManager.setDownloadMonitor( transferListener );
  393           }
  394   
  395           ArtifactResolutionResult result = artifactResolver.resolveTransitively( project.getDependencyArtifacts(),
  396                                                                                   projectArtifact, managedVersions,
  397                                                                                   localRepository,
  398                                                                                   project.getRemoteArtifactRepositories(),
  399                                                                                   artifactMetadataSource );
  400   
  401           project.setArtifacts( result.getArtifacts() );
  402   
  403           return project;
  404       }
  405   
  406       // ----------------------------------------------------------------------
  407       //
  408       // ----------------------------------------------------------------------
  409   
  410       private void ensureMetadataSourceIsInitialized()
  411           throws ProjectBuildingException
  412       {
  413           if ( artifactMetadataSource == null )
  414           {
  415               try
  416               {
  417                   artifactMetadataSource = (ArtifactMetadataSource) container.lookup( ArtifactMetadataSource.ROLE );
  418               }
  419               catch ( ComponentLookupException e )
  420               {
  421                   throw new ProjectBuildingException( "all", "Cannot lookup metadata source for building the project.",
  422                                                       e );
  423               }
  424           }
  425       }
  426   
  427       private Map createManagedVersionMap( String projectId,
  428                                            DependencyManagement dependencyManagement,
  429                                            MavenProject parent )
  430           throws ProjectBuildingException
  431       {
  432           Map map = null;
  433           List deps;
  434           if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null ) &&
  435               ( deps.size() > 0 ) )
  436           {
  437               map = new ManagedVersionMap( map );
  438   
  439               if ( getLogger().isDebugEnabled() )
  440               {
  441                   getLogger().debug( "Adding managed dependencies for " + projectId );
  442               }
  443   
  444               for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); )
  445               {
  446                   Dependency d = (Dependency) i.next();
  447   
  448                   try
  449                   {
  450                       VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
  451   
  452                       Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(),
  453                                                                                     versionRange, d.getType(),
  454                                                                                     d.getClassifier(), d.getScope(),
  455                                                                                     d.isOptional() );
  456                       if ( getLogger().isDebugEnabled() )
  457                       {
  458                           getLogger().debug( "  " + artifact );
  459                       }
  460   
  461                       // If the dependencyManagement section listed exclusions,
  462                       // add them to the managed artifacts here so that transitive
  463                       // dependencies will be excluded if necessary.
  464                       if ( ( null != d.getExclusions() ) && !d.getExclusions().isEmpty() )
  465                       {
  466                           List exclusions = new ArrayList();
  467   
  468                           Iterator exclItr = d.getExclusions().iterator();
  469   
  470                           while ( exclItr.hasNext() )
  471                           {
  472                               Exclusion e = (Exclusion) exclItr.next();
  473                               exclusions.add( e.getGroupId() + ":" + e.getArtifactId() );
  474                           }
  475                           ExcludesArtifactFilter eaf = new ExcludesArtifactFilter( exclusions );
  476                           artifact.setDependencyFilter( eaf );
  477                       }
  478                       else
  479                       {
  480                           artifact.setDependencyFilter( null );
  481                       }
  482                       map.put( d.getManagementKey(), artifact );
  483                   }
  484                   catch ( InvalidVersionSpecificationException e )
  485                   {
  486                       throw new ProjectBuildingException( projectId, "Unable to parse version '" + d.getVersion() +
  487                           "' for dependency '" + d.getManagementKey() + "': " + e.getMessage(), e );
  488                   }
  489               }
  490           }
  491           else if ( map == null )
  492           {
  493               map = Collections.EMPTY_MAP;
  494           }
  495   
  496           return map;
  497       }
  498   
  499       private MavenProject buildFromSourceFileInternal( File projectDescriptor,
  500                                                         ProjectBuilderConfiguration config,
  501                                                         boolean checkDistributionManagementStatus )
  502           throws ProjectBuildingException
  503       {
  504           Model model = readModel( "unknown", projectDescriptor, true );
  505   
  506           MavenProject project = buildInternal( projectDescriptor.getAbsolutePath(), model, config,
  507                                                 buildArtifactRepositories( getSuperModel() ), projectDescriptor,
  508                                                 true );
  509   
  510           if ( checkDistributionManagementStatus )
  511           {
  512               if ( ( project.getDistributionManagement() != null ) &&
  513                   ( project.getDistributionManagement().getStatus() != null ) )
  514               {
  515                   String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() );
  516   
  517                   throw new ProjectBuildingException( projectId,
  518                                                       "Invalid project file: distribution status must not be specified for a project outside of the repository" );
  519               }
  520           }
  521   
  522           return project;
  523       }
  524   
  525       private Model findModelFromRepository( Artifact artifact,
  526                                              List remoteArtifactRepositories,
  527                                              ArtifactRepository localRepository,
  528                                              boolean allowStubModel )
  529           throws ProjectBuildingException
  530       {
  531           String projectId = safeVersionlessKey( artifact.getGroupId(), artifact.getArtifactId() );
  532   
  533           normalizeToArtifactRepositories( remoteArtifactRepositories, projectId );
  534   
  535           Artifact projectArtifact;
  536   
  537           // if the artifact is not a POM, we need to construct a POM artifact based on the artifact parameter given.
  538           if ( "pom".equals( artifact.getType() ) )
  539           {
  540               projectArtifact = artifact;
  541           }
  542           else
  543           {
  544               getLogger().warn( "Attempting to build MavenProject instance for Artifact (" + artifact.getGroupId() + ":"
  545                                     + artifact.getArtifactId() + ":" + artifact.getVersion() + ") of type: "
  546                                     + artifact.getType() + "; constructing POM artifact instead." );
  547   
  548               projectArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
  549                                                                        artifact.getVersion(), artifact.getScope() );
  550           }
  551   
  552           Model model;
  553   
  554           try
  555           {
  556               artifactResolver.resolve( projectArtifact, remoteArtifactRepositories, localRepository );
  557   
  558               File file = projectArtifact.getFile();
  559   
  560               model = readModel( projectId, file, false );
  561   
  562               String downloadUrl = null;
  563   
  564               ArtifactStatus status = ArtifactStatus.NONE;
  565   
  566               DistributionManagement distributionManagement = model.getDistributionManagement();
  567   
  568               if ( distributionManagement != null )
  569               {
  570                   downloadUrl = distributionManagement.getDownloadUrl();
  571   
  572                   status = ArtifactStatus.valueOf( distributionManagement.getStatus() );
  573               }
  574   
  575               checkStatusAndUpdate( projectArtifact, status, file, remoteArtifactRepositories, localRepository );
  576   
  577               // TODO: this is gross. Would like to give it the whole model, but maven-artifact shouldn't depend on that
  578               // Can a maven-core implementation of the Artifact interface store it, and be used in the exceptions?
  579               if ( downloadUrl != null )
  580               {
  581                   projectArtifact.setDownloadUrl( downloadUrl );
  582               }
  583               else
  584               {
  585                   projectArtifact.setDownloadUrl( model.getUrl() );
  586               }
  587           }
  588           catch ( ArtifactResolutionException e )
  589           {
  590               throw new ProjectBuildingException( projectId, "Error getting POM for '" + projectId +
  591                   "' from the repository: " + e.getMessage(), e );
  592           }
  593           catch ( ArtifactNotFoundException e )
  594           {
  595               if ( allowStubModel )
  596               {
  597                   getLogger().debug( "Artifact not found - using stub model: " + e.getMessage() );
  598   
  599                   model = createStubModel( projectArtifact );
  600               }
  601               else
  602               {
  603                   throw new ProjectBuildingException( projectId, "POM '" + projectId + "' not found in repository: " +
  604                       e.getMessage(), e );
  605               }
  606           }
  607   
  608           return model;
  609       }
  610   
  611       private List normalizeToArtifactRepositories( List remoteArtifactRepositories,
  612                                                     String projectId )
  613           throws ProjectBuildingException
  614       {
  615           List normalized = new ArrayList( remoteArtifactRepositories.size() );
  616   
  617           boolean normalizationNeeded = false;
  618           for ( Iterator it = remoteArtifactRepositories.iterator(); it.hasNext(); )
  619           {
  620               Object item = it.next();
  621   
  622               if ( item instanceof ArtifactRepository )
  623               {
  624                   normalized.add( item );
  625               }
  626               else if ( item instanceof Repository )
  627               {
  628                   Repository repo = (Repository) item;
  629                   try
  630                   {
  631                       item = ProjectUtils.buildArtifactRepository( repo, artifactRepositoryFactory, container );
  632   
  633                       normalized.add( item );
  634                       normalizationNeeded = true;
  635                   }
  636                   catch ( InvalidRepositoryException e )
  637                   {
  638                       throw new ProjectBuildingException( projectId, "Error building artifact repository for id: " + repo.getId(), e );
  639                   }
  640               }
  641               else
  642               {
  643                   throw new ProjectBuildingException( projectId, "Error building artifact repository from non-repository information item: " + item );
  644               }
  645           }
  646   
  647           if ( normalizationNeeded )
  648           {
  649               return normalized;
  650           }
  651           else
  652           {
  653               return remoteArtifactRepositories;
  654           }
  655       }
  656   
  657       private void checkStatusAndUpdate( Artifact projectArtifact,
  658                                          ArtifactStatus status,
  659                                          File file,
  660                                          List remoteArtifactRepositories,
  661                                          ArtifactRepository localRepository )
  662           throws ArtifactNotFoundException
  663       {
  664           // TODO: configurable actions dependant on status
  665           if ( !projectArtifact.isSnapshot() && ( status.compareTo( ArtifactStatus.DEPLOYED ) < 0 ) )
  666           {
  667               // use default policy (enabled, daily update, warn on bad checksum)
  668               ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy();
  669               // TODO: re-enable [MNG-798/865]
  670               policy.setUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER );
  671   
  672               if ( policy.checkOutOfDate( new Date( file.lastModified() ) ) )
  673               {
  674                   getLogger().info(
  675                       projectArtifact.getArtifactId() + ": updating metadata due to status of '" + status + "'" );
  676                   try
  677                   {
  678                       projectArtifact.setResolved( false );
  679                       artifactResolver.resolveAlways( projectArtifact, remoteArtifactRepositories, localRepository );
  680                   }
  681                   catch ( ArtifactResolutionException e )
  682                   {
  683                       getLogger().warn( "Error updating POM - using existing version" );
  684                       getLogger().debug( "Cause", e );
  685                   }
  686                   catch ( ArtifactNotFoundException e )
  687                   {
  688                       getLogger().warn( "Error updating POM - not found. Removing local copy." );
  689                       getLogger().debug( "Cause", e );
  690                       file.delete();
  691                       throw e;
  692                   }
  693               }
  694           }
  695       }
  696   
  697       // jvz:note
  698       // This is used when requested artifacts do not have an associated POM. This is for the case where we are
  699       // using an m1 repo where the only thing required to be present are the JAR files.
  700       private Model createStubModel( Artifact projectArtifact )
  701       {
  702           getLogger().debug( "Using defaults for missing POM " + projectArtifact );
  703   
  704           Model model = new Model();
  705   
  706           model.setModelVersion( "4.0.0" );
  707   
  708           model.setArtifactId( projectArtifact.getArtifactId() );
  709   
  710           model.setGroupId( projectArtifact.getGroupId() );
  711   
  712           model.setVersion( projectArtifact.getVersion() );
  713   
  714           // TODO: not correct in some instances
  715           model.setPackaging( projectArtifact.getType() );
  716   
  717           model.setDistributionManagement( new DistributionManagement() );
  718   
  719           model.getDistributionManagement().setStatus( ArtifactStatus.GENERATED.toString() );
  720   
  721           return model;
  722       }
  723   
  724       // jvz:note
  725       // We've got a mixture of things going in the USD and from the repository, sometimes the descriptor
  726       // is a real file and sometimes null which makes things confusing.
  727       private MavenProject buildInternal( String pomLocation,
  728                                           Model model,
  729                                           ProjectBuilderConfiguration config,
  730                                           List parentSearchRepositories,
  731                                           File projectDescriptor,
  732                                           boolean strict )
  733           throws ProjectBuildingException
  734       {
  735           File projectDir = null;
  736   
  737           if ( projectDescriptor != null )
  738           {
  739               projectDir = projectDescriptor.getAbsoluteFile().getParentFile();
  740           }
  741   
  742           Model superModel = getSuperModel();
  743   
  744           ProfileManager externalProfileManager = config.getGlobalProfileManager();
  745           ProfileManager superProjectProfileManager;
  746           if ( externalProfileManager != null )
  747           {
  748               superProjectProfileManager = new DefaultProfileManager(
  749                                                                       container,
  750                                                                       externalProfileManager.getRequestProperties() );
  751           }
  752           else
  753           {
  754               superProjectProfileManager = new DefaultProfileManager( container );
  755           }
  756   
  757           List activeProfiles;
  758   
  759           superProjectProfileManager.addProfiles( superModel.getProfiles() );
  760   
  761           activeProfiles = injectActiveProfiles( superProjectProfileManager, superModel );
  762   
  763           MavenProject superProject = new MavenProject( superModel );
  764   
  765           superProject.setActiveProfiles( activeProfiles );
  766   
  767           //noinspection CollectionDeclaredAsConcreteClass
  768           LinkedList lineage = new LinkedList();
  769   
  770           // TODO: the aRWR can get out of sync with project.model.repositories. We should do all the processing of
  771           // profiles, etc on the models then recreate the aggregated sets at the end from the project repositories (they
  772           // must still be created along the way so that parent poms can be discovered, however)
  773           // Use a TreeSet to ensure ordering is retained
  774           Set aggregatedRemoteWagonRepositories = new LinkedHashSet();
  775   
  776           String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
  777   
  778           List activeExternalProfiles;
  779           try
  780           {
  781               if ( externalProfileManager != null )
  782               {
  783                   activeExternalProfiles = externalProfileManager.getActiveProfiles();
  784               }
  785               else
  786               {
  787                   activeExternalProfiles = Collections.EMPTY_LIST;
  788               }
  789           }
  790           catch ( ProfileActivationException e )
  791           {
  792               throw new ProjectBuildingException( projectId, "Failed to calculate active external profiles.", e );
  793           }
  794   
  795           for ( Iterator i = activeExternalProfiles.iterator(); i.hasNext(); )
  796           {
  797               Profile externalProfile = (Profile) i.next();
  798   
  799               for ( Iterator repoIterator = externalProfile.getRepositories().iterator(); repoIterator.hasNext(); )
  800               {
  801                   Repository mavenRepo = (Repository) repoIterator.next();
  802   
  803                   ArtifactRepository artifactRepo = null;
  804                   try
  805                   {
  806                       artifactRepo =
  807                           ProjectUtils.buildArtifactRepository( mavenRepo, artifactRepositoryFactory, container );
  808                   }
  809                   catch ( InvalidRepositoryException e )
  810                   {
  811                       throw new ProjectBuildingException( projectId, e.getMessage(), e );
  812                   }
  813   
  814                   aggregatedRemoteWagonRepositories.add( artifactRepo );
  815               }
  816           }
  817   
  818           MavenProject project = null;
  819           try
  820           {
  821               project = assembleLineage( model, lineage, config, projectDir, parentSearchRepositories,
  822                                          aggregatedRemoteWagonRepositories, strict );
  823           }
  824           catch ( InvalidRepositoryException e )
  825           {
  826               throw new ProjectBuildingException( projectId, e.getMessage(), e );
  827           }
  828   
  829           // we don't have to force the collision exception for superModel here, it's already been done in getSuperModel()
  830           MavenProject previousProject = superProject;
  831   
  832           Model previous = superProject.getModel();
  833   
  834           for ( Iterator i = lineage.iterator(); i.hasNext(); )
  835           {
  836               MavenProject currentProject = (MavenProject) i.next();
  837   
  838               Model current = currentProject.getModel();
  839   
  840               String pathAdjustment = null;
  841   
  842               try
  843               {
  844                   pathAdjustment = previousProject.getModulePathAdjustment( currentProject );
  845               }
  846               catch ( IOException e )
  847               {
  848                   getLogger().debug( "Cannot determine whether " + currentProject.getId() + " is a module of " +
  849                       previousProject.getId() + ". Reason: " + e.getMessage(), e );
  850               }
  851   
  852               modelInheritanceAssembler.assembleModelInheritance( current, previous, pathAdjustment );
  853   
  854               previous = current;
  855               previousProject = currentProject;
  856           }
  857   
  858           // only add the super repository if it wasn't overridden by a profile or project
  859           List repositories = new ArrayList( aggregatedRemoteWagonRepositories );
  860   
  861           List superRepositories = buildArtifactRepositories( superModel );
  862   
  863           for ( Iterator i = superRepositories.iterator(); i.hasNext(); )
  864           {
  865               ArtifactRepository repository = (ArtifactRepository) i.next();
  866   
  867               if ( !repositories.contains( repository ) )
  868               {
  869                   repositories.add( repository );
  870               }
  871           }
  872   
  873           // merge any duplicated plugin definitions together, using the first appearance as the dominant one.
  874           ModelUtils.mergeDuplicatePluginDefinitions( project.getModel().getBuild() );
  875   
  876           try
  877           {
  878               project = processProjectLogic( pomLocation, project, config, projectDir, repositories, strict, false );
  879           }
  880           catch ( ModelInterpolationException e )
  881           {
  882               throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
  883           }
  884           catch ( InvalidRepositoryException e )
  885           {
  886               throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
  887           }
  888   
  889           processedProjectCache.put(
  890                                     createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project );
  891   
  892             // jvz:note
  893           // this only happens if we are building from a source file
  894           if ( projectDescriptor != null )
  895           {
  896               // Only translate the base directory for files in the source tree
  897               pathTranslator.alignToBaseDirectory( project.getModel(),
  898                                                    projectDir );
  899   
  900               Build build = project.getBuild();
  901   
  902               project.addCompileSourceRoot( build.getSourceDirectory() );
  903   
  904               project.addScriptSourceRoot( build.getScriptSourceDirectory() );
  905   
  906               project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
  907   
  908               // Only track the file of a POM in the source tree
  909               project.setFile( projectDescriptor );
  910           }
  911   
  912           project.setManagedVersionMap( createManagedVersionMap( projectId,
  913                                                                  project.getDependencyManagement(),
  914                                                                  project.getParent() ) );
  915   
  916           return project;
  917       }
  918   
  919       private String safeVersionlessKey( String groupId,
  920                                          String artifactId )
  921       {
  922           String gid = groupId;
  923   
  924           if ( StringUtils.isEmpty( gid ) )
  925           {
  926               gid = "unknown";
  927           }
  928   
  929           String aid = artifactId;
  930   
  931           if ( StringUtils.isEmpty( aid ) )
  932           {
  933               aid = "unknown";
  934           }
  935   
  936           return ArtifactUtils.versionlessKey( gid, aid );
  937       }
  938   
  939       private List buildArtifactRepositories( Model model )
  940           throws ProjectBuildingException
  941       {
  942           try
  943           {
  944               return ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory,
  945                                                              container );
  946           }
  947           catch ( InvalidRepositoryException e )
  948           {
  949               String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
  950   
  951               throw new ProjectBuildingException( projectId, e.getMessage(), e );
  952           }
  953       }
  954   
  955       /**
  956        * @todo can this take in a model instead of a project and still be successful?
  957        * @todo In fact, does project REALLY need a MavenProject as a parent? Couldn't it have just a wrapper around a
  958        * model that supported parents which were also the wrapper so that inheritence was assembled. We don't really need
  959        * the resolved source roots, etc for the parent - that occurs for the parent when it is constructed independently
  960        * and projects are not cached or reused
  961        */
  962       private MavenProject processProjectLogic( String pomLocation,
  963                                                 MavenProject project,
  964                                                 ProjectBuilderConfiguration config,
  965                                                 File projectDir,
  966                                                 List remoteRepositories,
  967                                                 boolean strict,
  968                                                 boolean isSuperPom )
  969           throws ProjectBuildingException, ModelInterpolationException, InvalidRepositoryException
  970       {
  971           Model model = project.getModel();
  972   
  973           List activeProfiles = project.getActiveProfiles();
  974   
  975           if ( activeProfiles == null )
  976           {
  977               activeProfiles = new ArrayList();
  978           }
  979   
  980           ProfileManager profileMgr = config == null ? null : config.getGlobalProfileManager();
  981   
  982           List injectedProfiles = injectActiveProfiles( profileMgr, model );
  983   
  984           activeProfiles.addAll( injectedProfiles );
  985   
  986           // We don't need all the project methods that are added over those in the model, but we do need basedir
  987           Map context = new HashMap();
  988   
  989           Build build = model.getBuild();
  990   
  991           if ( projectDir != null )
  992           {
  993               context.put( "basedir", projectDir.getAbsolutePath() );
  994   
  995               // MNG-1927, MNG-2124, MNG-3355:
  996               // If the build section is present and the project directory is non-null, we should make
  997               // sure interpolation of the directories below uses translated paths.
  998               // Afterward, we'll double back and translate any paths that weren't covered during interpolation via the
  999               // code below...
 1000               context.put( "build.directory", pathTranslator.alignToBaseDirectory( build.getDirectory(), projectDir ) );
 1001               context.put( "build.outputDirectory", pathTranslator.alignToBaseDirectory( build.getOutputDirectory(), projectDir ) );
 1002               context.put( "build.testOutputDirectory", pathTranslator.alignToBaseDirectory( build.getTestOutputDirectory(), projectDir ) );
 1003               context.put( "build.sourceDirectory", pathTranslator.alignToBaseDirectory( build.getSourceDirectory(), projectDir ) );
 1004               context.put( "build.testSourceDirectory", pathTranslator.alignToBaseDirectory( build.getTestSourceDirectory(), projectDir ) );
 1005           }
 1006   
 1007           if ( !isSuperPom )
 1008           {
 1009               Properties userProps = config.getUserProperties();
 1010               if ( userProps != null )
 1011               {
 1012                   context.putAll( userProps );
 1013               }
 1014           }
 1015   
 1016           model = modelInterpolator.interpolate( model, context, strict );
 1017   
 1018           // second pass allows ${user.home} to work, if it needs to.
 1019           // [MNG-2339] ensure the system properties are still interpolated for backwards compat, but the model values must win
 1020           if ( config.getExecutionProperties() != null && !config.getExecutionProperties().isEmpty() )
 1021           {
 1022               context.putAll( config.getExecutionProperties() );
 1023           }
 1024   
 1025           model = modelInterpolator.interpolate( model, context, strict );
 1026   
 1027           // MNG-3482: Make sure depMgmt is interpolated before merging.
 1028           if ( !isSuperPom )
 1029           {
 1030               mergeManagedDependencies( model, config.getLocalRepository(), remoteRepositories );
 1031           }
 1032   
 1033           // interpolation is before injection, because interpolation is off-limits in the injected variables
 1034           modelDefaultsInjector.injectDefaults( model );
 1035   
 1036           MavenProject parentProject = project.getParent();
 1037   
 1038           Model originalModel = project.getOriginalModel();
 1039   
 1040           // We will return a different project object using the new model (hence the need to return a project, not just modify the parameter)
 1041           project = new MavenProject( model );
 1042   
 1043           project.setOriginalModel( originalModel );
 1044   
 1045           project.setActiveProfiles( activeProfiles );
 1046   
 1047           // TODO: maybe not strictly correct, while we should enfore that packaging has a type handler of the same id, we don't
 1048           Artifact projectArtifact = artifactFactory.createBuildArtifact( project.getGroupId(), project.getArtifactId(),
 1049                                                                           project.getVersion(), project.getPackaging() );
 1050   
 1051           project.setArtifact( projectArtifact );
 1052   
 1053           project.setPluginArtifactRepositories( ProjectUtils.buildArtifactRepositories( model.getPluginRepositories(),
 1054                                                                                          artifactRepositoryFactory,
 1055                                                                                          container ) );
 1056   
 1057           DistributionManagement dm = model.getDistributionManagement();
 1058           if ( dm != null )
 1059           {
 1060               ArtifactRepository repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getRepository(),
 1061                                                                                         artifactRepositoryFactory,
 1062                                                                                         container );
 1063               project.setReleaseArtifactRepository( repo );
 1064   
 1065               if ( dm.getSnapshotRepository() != null )
 1066               {
 1067                   repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getSnapshotRepository(),
 1068                                                                          artifactRepositoryFactory, container );
 1069                   project.setSnapshotArtifactRepository( repo );
 1070               }
 1071           }
 1072   
 1073           if ( parentProject != null )
 1074           {
 1075               String cacheKey = createCacheKey( parentProject.getGroupId(),
 1076                                                 parentProject.getArtifactId(),
 1077                                                 parentProject.getVersion() );
 1078   
 1079               MavenProject processedParent = (MavenProject) processedProjectCache.get( cacheKey );
 1080               Artifact parentArtifact;
 1081   
 1082               // yeah, this null check might be a bit paranoid, but better safe than sorry...
 1083               if ( processedParent != null )
 1084               {
 1085                   project.setParent( processedParent );
 1086   
 1087                   parentArtifact = processedParent.getArtifact();
 1088               }
 1089               else
 1090               {
 1091                   project.setParent( parentProject );
 1092   
 1093                   parentArtifact = artifactFactory.createParentArtifact( parentProject.getGroupId(),
 1094                                                                                   parentProject.getArtifactId(),
 1095                                                                                   parentProject.getVersion() );
 1096               }
 1097   
 1098               project.setParentArtifact( parentArtifact );
 1099           }
 1100   
 1101           // Must validate before artifact construction to make sure dependencies are good
 1102           ModelValidationResult validationResult = validator.validate( model );
 1103   
 1104           String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1105   
 1106           if ( validationResult.getMessageCount() > 0 )
 1107           {
 1108               throw new InvalidProjectModelException( projectId, pomLocation, "Failed to validate POM",
 1109                                                       validationResult );
 1110           }
 1111   
 1112           project.setRemoteArtifactRepositories(
 1113               ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory, container ) );
 1114   
 1115           // TODO: these aren't taking active project artifacts into consideration in the reactor
 1116           project.setPluginArtifacts( createPluginArtifacts( projectId, project.getBuildPlugins() ) );
 1117   
 1118           project.setReportArtifacts( createReportArtifacts( projectId, project.getReportPlugins() ) );
 1119   
 1120           project.setExtensionArtifacts( createExtensionArtifacts( projectId, project.getBuildExtensions() ) );
 1121   
 1122           return project;
 1123       }
 1124   
 1125       /**
 1126        * @noinspection CollectionDeclaredAsConcreteClass
 1127        * @todo We need to find an effective way to unit test parts of this method!
 1128        * @todo Refactor this into smaller methods with discrete purposes.
 1129        */
 1130       private MavenProject assembleLineage( Model model,
 1131                                             LinkedList lineage,
 1132                                             ProjectBuilderConfiguration config,
 1133                                             File projectDir,
 1134                                             List parentSearchRepositories,
 1135                                             Set aggregatedRemoteWagonRepositories,
 1136                                             boolean strict )
 1137           throws ProjectBuildingException, InvalidRepositoryException
 1138       {
 1139           Model originalModel = ModelUtils.cloneModel( model );
 1140   
 1141   
 1142           if ( !model.getRepositories().isEmpty() )
 1143           {
 1144               List respositories = buildArtifactRepositories( model );
 1145   
 1146               for ( Iterator it = respositories.iterator(); it.hasNext(); )
 1147               {
 1148                   ArtifactRepository repository = (ArtifactRepository) it.next();
 1149   
 1150                   if ( !aggregatedRemoteWagonRepositories.contains( repository ) )
 1151                   {
 1152                       aggregatedRemoteWagonRepositories.add( repository );
 1153                   }
 1154               }
 1155           }
 1156   
 1157           ProfileManager externalProfileManager = config.getGlobalProfileManager();
 1158           ProfileManager profileManager;
 1159           if ( externalProfileManager != null )
 1160           {
 1161               profileManager = new DefaultProfileManager( container, externalProfileManager.getRequestProperties() );
 1162           }
 1163           else
 1164           {
 1165               //TODO mkleint - use the (Container, Properties constructor to make system properties embeddable
 1166               profileManager = new DefaultProfileManager( container );
 1167           }
 1168   
 1169           if ( externalProfileManager != null )
 1170           {
 1171               profileManager.explicitlyActivate( externalProfileManager.getExplicitlyActivatedIds() );
 1172   
 1173               profileManager.explicitlyDeactivate( externalProfileManager.getExplicitlyDeactivatedIds() );
 1174           }
 1175   
 1176           List activeProfiles;
 1177   
 1178           try
 1179           {
 1180               profileManager.addProfiles( model.getProfiles() );
 1181   
 1182               loadProjectExternalProfiles( profileManager, projectDir );
 1183   
 1184               activeProfiles = injectActiveProfiles( profileManager, model );
 1185           }
 1186           catch ( ProfileActivationException e )
 1187           {
 1188               String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1189   
 1190               throw new ProjectBuildingException( projectId, "Failed to activate local (project-level) build profiles: " +
 1191                   e.getMessage(), e );
 1192           }
 1193   
 1194           MavenProject project = new MavenProject( model );
 1195   
 1196           project.setActiveProfiles( activeProfiles );
 1197           project.setOriginalModel( originalModel );
 1198   
 1199           lineage.addFirst( project );
 1200   
 1201           Parent parentModel = model.getParent();
 1202   
 1203           String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1204   
 1205           if ( parentModel != null )
 1206           {
 1207               if ( StringUtils.isEmpty( parentModel.getGroupId() ) )
 1208               {
 1209                   throw new ProjectBuildingException( projectId, "Missing groupId element from parent element" );
 1210               }
 1211               else if ( StringUtils.isEmpty( parentModel.getArtifactId() ) )
 1212               {
 1213                   throw new ProjectBuildingException( projectId, "Missing artifactId element from parent element" );
 1214               }
 1215               else if ( parentModel.getGroupId().equals( model.getGroupId() ) &&
 1216                   parentModel.getArtifactId().equals( model.getArtifactId() ) )
 1217               {
 1218                   throw new ProjectBuildingException( projectId,
 1219                                                       "Parent element is a duplicate of " + "the current project " );
 1220               }
 1221               else if ( StringUtils.isEmpty( parentModel.getVersion() ) )
 1222               {
 1223                   throw new ProjectBuildingException( projectId, "Missing version element from parent element" );
 1224               }
 1225   
 1226               // the only way this will have a value is if we find the parent on disk...
 1227               File parentDescriptor = null;
 1228   
 1229               model = null;
 1230   
 1231               String parentKey =
 1232                   createCacheKey( parentModel.getGroupId(), parentModel.getArtifactId(), parentModel.getVersion() );
 1233               MavenProject parentProject = (MavenProject) rawProjectCache.get( parentKey );
 1234   
 1235               if ( parentProject != null )
 1236               {
 1237                   model = ModelUtils.cloneModel( parentProject.getModel() );
 1238   
 1239                   parentDescriptor = parentProject.getFile();
 1240               }
 1241   
 1242               String parentRelativePath = parentModel.getRelativePath();
 1243   
 1244               // if we can't find a cached model matching the parent spec, then let's try to look on disk using
 1245               // <relativePath/>
 1246               if ( ( model == null ) && ( projectDir != null ) && StringUtils.isNotEmpty( parentRelativePath ) )
 1247               {
 1248                   parentDescriptor = new File( projectDir, parentRelativePath );
 1249   
 1250                   if ( getLogger().isDebugEnabled() )
 1251                   {
 1252                       getLogger().debug( "Searching for parent-POM: " + parentModel.getId() + " of project: " +
 1253                           project.getId() + " in relative path: " + parentRelativePath );
 1254                   }
 1255   
 1256                   if ( parentDescriptor.isDirectory() )
 1257                   {
 1258                       if ( getLogger().isDebugEnabled() )
 1259                       {
 1260                           getLogger().debug( "Path specified in <relativePath/> (" + parentRelativePath +
 1261                               ") is a directory. Searching for 'pom.xml' within this directory." );
 1262                       }
 1263   
 1264                       parentDescriptor = new File( parentDescriptor, "pom.xml" );
 1265   
 1266                       if ( !parentDescriptor.exists() )
 1267                       {
 1268                           if ( getLogger().isDebugEnabled() )
 1269                           {
 1270                               getLogger().debug( "Parent-POM: " + parentModel.getId() + " for project: " +
 1271                                   project.getId() + " cannot be loaded from relative path: " + parentDescriptor +
 1272                                   "; path does not exist." );
 1273                           }
 1274                       }
 1275                   }
 1276   
 1277                   if ( parentDescriptor != null )
 1278                   {
 1279                       try
 1280                       {
 1281                           parentDescriptor = parentDescriptor.getCanonicalFile();
 1282                       }
 1283                       catch ( IOException e )
 1284                       {
 1285                           getLogger().debug( "Failed to canonicalize potential parent POM: \'" + parentDescriptor + "\'",
 1286                                              e );
 1287   
 1288                           parentDescriptor = null;
 1289                       }
 1290                   }
 1291   
 1292                   if ( ( parentDescriptor != null ) && parentDescriptor.exists() )
 1293                   {
 1294                       Model candidateParent = readModel( projectId, parentDescriptor, strict );
 1295   
 1296                       String candidateParentGroupId = candidateParent.getGroupId();
 1297                       if ( ( candidateParentGroupId == null ) && ( candidateParent.getParent() != null ) )
 1298                       {
 1299                           candidateParentGroupId = candidateParent.getParent().getGroupId();
 1300                       }
 1301   
 1302                       String candidateParentVersion = candidateParent.getVersion();
 1303                       if ( ( candidateParentVersion == null ) && ( candidateParent.getParent() != null ) )
 1304                       {
 1305                           candidateParentVersion = candidateParent.getParent().getVersion();
 1306                       }
 1307   
 1308                       if ( parentModel.getGroupId().equals( candidateParentGroupId ) &&
 1309                           parentModel.getArtifactId().equals( candidateParent.getArtifactId() ) &&
 1310                           parentModel.getVersion().equals( candidateParentVersion ) )
 1311                       {
 1312                           model = candidateParent;
 1313   
 1314                           getLogger().debug( "Using parent-POM from the project hierarchy at: \'" +
 1315                               parentModel.getRelativePath() + "\' for project: " + project.getId() );
 1316                       }
 1317                       else
 1318                       {
 1319                           getLogger().debug( "Invalid parent-POM referenced by relative path '" +
 1320                               parentModel.getRelativePath() + "' in parent specification in " + project.getId() + ":" +
 1321                               "\n  Specified: " + parentModel.getId() + "\n  Found:     " + candidateParent.getId() );
 1322                       }
 1323                   }
 1324                   else if ( getLogger().isDebugEnabled() )
 1325                   {
 1326                       getLogger().debug(
 1327                           "Parent-POM: " + parentModel.getId() + " not found in relative path: " + parentRelativePath );
 1328                   }
 1329               }
 1330   
 1331               Artifact parentArtifact = null;
 1332   
 1333               // only resolve the parent model from the repository system if we didn't find it on disk...
 1334               if ( model == null )
 1335               {
 1336                   // MNG-2302: parent's File was being populated incorrectly when parent is loaded from repo.
 1337                   // keep this in line with other POMs loaded from the repository...the file should be null.
 1338                   parentDescriptor = null;
 1339   
 1340                   //!! (**)
 1341                   // ----------------------------------------------------------------------
 1342                   // Do we have the necessary information to actually find the parent
 1343                   // POMs here?? I don't think so ... Say only one remote repository is
 1344                   // specified and that is ibiblio then this model that we just read doesn't
 1345                   // have any repository information ... I think we might have to inherit
 1346                   // as we go in order to do this.
 1347                   // ----------------------------------------------------------------------
 1348   
 1349                   // we must add the repository this POM was found in too, by chance it may be located where the parent is
 1350                   // we can't query the parent to ask where it is :)
 1351                   List remoteRepositories = new ArrayList( aggregatedRemoteWagonRepositories );
 1352                   remoteRepositories.addAll( parentSearchRepositories );
 1353   
 1354                   if ( getLogger().isDebugEnabled() )
 1355                   {
 1356                       getLogger().debug( "Retrieving parent-POM: " + parentModel.getId() + " for project: " +
 1357                           project.getId() + " from the repository." );
 1358                   }
 1359   
 1360                   parentArtifact = artifactFactory.createParentArtifact( parentModel.getGroupId(),
 1361                                                                          parentModel.getArtifactId(),
 1362                                                                          parentModel.getVersion() );
 1363   
 1364                   try
 1365                   {
 1366                       model = findModelFromRepository( parentArtifact, remoteRepositories, config.getLocalRepository(), false );
 1367                   }
 1368                   catch ( ProjectBuildingException e )
 1369                   {
 1370                       throw new ProjectBuildingException( project.getId(), "Cannot find parent: " + e.getProjectId() +
 1371                           " for project: " + project.getId(), e );
 1372                   }
 1373               }
 1374   
 1375               if ( ( model != null ) && !"pom".equals( model.getPackaging() ) )
 1376               {
 1377                   throw new ProjectBuildingException( projectId, "Parent: " + model.getId() + " of project: " +
 1378                       projectId + " has wrong packaging: " + model.getPackaging() + ". Must be 'pom'." );
 1379               }
 1380   
 1381               File parentProjectDir = null;
 1382               if ( parentDescriptor != null )
 1383               {
 1384                   parentProjectDir = parentDescriptor.getParentFile();
 1385               }
 1386   
 1387               MavenProject parent = assembleLineage( model,
 1388                                                      lineage,
 1389                                                      config,
 1390                                                      parentProjectDir,
 1391                                                      parentSearchRepositories,
 1392                                                      aggregatedRemoteWagonRepositories,
 1393                                                      strict );
 1394   
 1395               parent.setFile( parentDescriptor );
 1396   
 1397               project.setParent( parent );
 1398   
 1399               project.setParentArtifact( parentArtifact );
 1400           }
 1401   
 1402           rawProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), new MavenProject( project ) );
 1403   
 1404           return project;
 1405       }
 1406   
 1407       private void mergeManagedDependencies(Model model, ArtifactRepository localRepository, List parentSearchRepositories)
 1408           throws ProjectBuildingException
 1409       {
 1410           DependencyManagement modelDepMgmt = model.getDependencyManagement();
 1411   
 1412           if (modelDepMgmt != null)
 1413           {
 1414               Map depsMap = new TreeMap();
 1415               Iterator iter = modelDepMgmt.getDependencies().iterator();
 1416               boolean doInclude = false;
 1417               while (iter.hasNext())
 1418               {
 1419                   Dependency dep = (Dependency) iter.next();
 1420                   depsMap.put( dep.getManagementKey(), dep );
 1421                   if ( dep.getType().equals( "pom" ) && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) )
 1422                   {
 1423                       doInclude = true;
 1424                   }
 1425               }
 1426               Map newDeps = new TreeMap(depsMap);
 1427               iter = modelDepMgmt.getDependencies().iterator();
 1428               if (doInclude)
 1429               {
 1430                   while (iter.hasNext())
 1431                   {
 1432                       Dependency dep = (Dependency)iter.next();
 1433                       if ( dep.getType().equals( "pom" )
 1434                            && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) )
 1435                       {
 1436                           Artifact artifact = artifactFactory.createProjectArtifact( dep.getGroupId(), dep.getArtifactId(),
 1437                                                                                     dep.getVersion(), dep.getScope() );
 1438                           MavenProject project = buildFromRepository(artifact, parentSearchRepositories, localRepository, false);
 1439   
 1440                           DependencyManagement depMgmt = project.getDependencyManagement();
 1441   
 1442                           if (depMgmt != null)
 1443                           {
 1444                               if ( getLogger().isDebugEnabled() )
 1445                               {
 1446                                   getLogger().debug( "Importing managed dependencies for " + dep.toString() );
 1447                               }
 1448   
 1449                               for ( Iterator it = depMgmt.getDependencies().iterator(); it.hasNext(); )
 1450                               {
 1451                                   Dependency includedDep = (Dependency) it.next();
 1452                                   String key = includedDep.getManagementKey();
 1453                                   if (!newDeps.containsKey(key))
 1454                                   {
 1455                                       newDeps.put( includedDep.getManagementKey(), includedDep );
 1456                                   }
 1457                               }
 1458                               newDeps.remove(dep.getManagementKey());
 1459                           }
 1460                       }
 1461                   }
 1462                   List deps = new ArrayList(newDeps.values());
 1463                   modelDepMgmt.setDependencies(deps);
 1464               }
 1465           }
 1466       }
 1467   
 1468       private List injectActiveProfiles( ProfileManager profileManager,
 1469                                          Model model )
 1470           throws ProjectBuildingException
 1471       {
 1472           List activeProfiles;
 1473   
 1474           if ( profileManager != null )
 1475           {
 1476               try
 1477               {
 1478                   activeProfiles = profileManager.getActiveProfiles();
 1479               }
 1480               catch ( ProfileActivationException e )
 1481               {
 1482                   String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1483   
 1484                   throw new ProjectBuildingException( projectId, e.getMessage(), e );
 1485               }
 1486   
 1487               for ( Iterator it = activeProfiles.iterator(); it.hasNext(); )
 1488               {
 1489                   Profile profile = (Profile) it.next();
 1490   
 1491                   profileInjector.inject( profile, model );
 1492               }
 1493           }
 1494           else
 1495           {
 1496               activeProfiles = Collections.EMPTY_LIST;
 1497           }
 1498   
 1499           return activeProfiles;
 1500       }
 1501   
 1502       private void loadProjectExternalProfiles( ProfileManager profileManager,
 1503                                                 File projectDir )
 1504           throws ProfileActivationException
 1505       {
 1506           if ( projectDir != null )
 1507           {
 1508               try
 1509               {
 1510                   ProfilesRoot root = profilesBuilder.buildProfiles( projectDir );
 1511   
 1512                   if ( root != null )
 1513                   {
 1514                       List active = root.getActiveProfiles();
 1515   
 1516                       if ( ( active != null ) && !active.isEmpty() )
 1517                       {
 1518                           profileManager.explicitlyActivate( root.getActiveProfiles() );
 1519                       }
 1520   
 1521                       for ( Iterator it = root.getProfiles().iterator(); it.hasNext(); )
 1522                       {
 1523                           org.apache.maven.profiles.Profile rawProfile = (org.apache.maven.profiles.Profile) it.next();
 1524   
 1525                           Profile converted = ProfilesConversionUtils.convertFromProfileXmlProfile( rawProfile );
 1526   
 1527                           profileManager.addProfile( converted );
 1528                       }
 1529                   }
 1530               }
 1531               catch ( IOException e )
 1532               {
 1533                   throw new ProfileActivationException( "Cannot read profiles.xml resource from directory: " + projectDir,
 1534                                                         e );
 1535               }
 1536               catch ( XmlPullParserException e )
 1537               {
 1538                   throw new ProfileActivationException(
 1539                       "Cannot parse profiles.xml resource from directory: " + projectDir, e );
 1540               }
 1541           }
 1542       }
 1543   
 1544       private Model readModel( String projectId,
 1545                                File file,
 1546                                boolean strict )
 1547           throws ProjectBuildingException
 1548       {
 1549           Reader reader = null;
 1550           try
 1551           {
 1552               reader = ReaderFactory.newXmlReader( file );
 1553               return readModel( projectId, file.getAbsolutePath(), reader, strict );
 1554           }
 1555           catch ( FileNotFoundException e )
 1556           {
 1557               throw new ProjectBuildingException( projectId,
 1558                                                   "Could not find the model file '" + file.getAbsolutePath() + "'.", e );
 1559           }
 1560           catch ( IOException e )
 1561           {
 1562               throw new ProjectBuildingException( projectId, "Failed to build model from file '" +
 1563                   file.getAbsolutePath() + "'.\nError: \'" + e.getLocalizedMessage() + "\'", e );
 1564           }
 1565           finally
 1566           {
 1567               IOUtil.close( reader );
 1568           }
 1569       }
 1570   
 1571       private Model readModel( String projectId,
 1572                                String pomLocation,
 1573                                Reader reader,
 1574                                boolean strict )
 1575           throws IOException, InvalidProjectModelException
 1576       {
 1577           String modelSource = IOUtil.toString( reader );
 1578   
 1579           if ( modelSource.indexOf( "<modelVersion>" + MAVEN_MODEL_VERSION ) < 0 )
 1580           {
 1581               throw new InvalidProjectModelException( projectId, pomLocation, "Not a v" + MAVEN_MODEL_VERSION  + " POM." );
 1582           }
 1583   
 1584           StringReader sReader = new StringReader( modelSource );
 1585   
 1586           try
 1587           {
 1588               return modelReader.read( sReader, strict );
 1589           }
 1590           catch ( XmlPullParserException e )
 1591           {
 1592               throw new InvalidProjectModelException( projectId, pomLocation,
 1593                                                       "Parse error reading POM. Reason: " + e.getMessage(), e );
 1594           }
 1595       }
 1596   
 1597       private Model readModel( String projectId,
 1598                                URL url,
 1599                                boolean strict )
 1600           throws ProjectBuildingException
 1601       {
 1602           Reader reader = null;
 1603           try
 1604           {
 1605               reader = ReaderFactory.newXmlReader( url.openStream() );
 1606               return readModel( projectId, url.toExternalForm(), reader, strict );
 1607           }
 1608           catch ( IOException e )
 1609           {
 1610               throw new ProjectBuildingException( projectId, "Failed build model from URL \'" + url.toExternalForm() +
 1611                   "\'\nError: \'" + e.getLocalizedMessage() + "\'", e );
 1612           }
 1613           finally
 1614           {
 1615               IOUtil.close( reader );
 1616           }
 1617       }
 1618   
 1619       private static String createCacheKey( String groupId,
 1620                                             String artifactId,
 1621                                             String version )
 1622       {
 1623           return groupId + ":" + artifactId + ":" + version;
 1624       }
 1625   
 1626       protected Set createPluginArtifacts( String projectId,
 1627                                            List plugins )
 1628           throws ProjectBuildingException
 1629       {
 1630           Set pluginArtifacts = new HashSet();
 1631   
 1632           for ( Iterator i = plugins.iterator(); i.hasNext(); )
 1633           {
 1634               Plugin p = (Plugin) i.next();
 1635   
 1636               String version;
 1637               if ( StringUtils.isEmpty( p.getVersion() ) )
 1638               {
 1639                   version = "RELEASE";
 1640               }
 1641               else
 1642               {
 1643                   version = p.getVersion();
 1644               }
 1645   
 1646               Artifact artifact;
 1647               try
 1648               {
 1649                   artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(),
 1650                                                                    VersionRange.createFromVersionSpec( version ) );
 1651               }
 1652               catch ( InvalidVersionSpecificationException e )
 1653               {
 1654                   throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
 1655                       "' for plugin '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " +
 1656                       e.getMessage(), e );
 1657               }
 1658   
 1659               if ( artifact != null )
 1660               {
 1661                   pluginArtifacts.add( artifact );
 1662               }
 1663           }
 1664   
 1665           return pluginArtifacts;
 1666       }
 1667   
 1668       // TODO: share with createPluginArtifacts?
 1669       protected Set createReportArtifacts( String projectId,
 1670                                            List reports )
 1671           throws ProjectBuildingException
 1672       {
 1673           Set pluginArtifacts = new HashSet();
 1674   
 1675           if ( reports != null )
 1676           {
 1677               for ( Iterator i = reports.iterator(); i.hasNext(); )
 1678               {
 1679                   ReportPlugin p = (ReportPlugin) i.next();
 1680   
 1681                   String version;
 1682                   if ( StringUtils.isEmpty( p.getVersion() ) )
 1683                   {
 1684                       version = "RELEASE";
 1685                   }
 1686                   else
 1687                   {
 1688                       version = p.getVersion();
 1689                   }
 1690   
 1691                   Artifact artifact;
 1692                   try
 1693                   {
 1694                       artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(),
 1695                                                                        VersionRange.createFromVersionSpec( version ) );
 1696                   }
 1697                   catch ( InvalidVersionSpecificationException e )
 1698                   {
 1699                       throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
 1700                           "' for report '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " +
 1701                           e.getMessage(), e );
 1702                   }
 1703   
 1704                   if ( artifact != null )
 1705                   {
 1706                       pluginArtifacts.add( artifact );
 1707                   }
 1708               }
 1709           }
 1710   
 1711           return pluginArtifacts;
 1712       }
 1713   
 1714       // TODO: share with createPluginArtifacts?
 1715       protected Set createExtensionArtifacts( String projectId,
 1716                                               List extensions )
 1717           throws ProjectBuildingException
 1718       {
 1719           Set extensionArtifacts = new HashSet();
 1720   
 1721           if ( extensions != null )
 1722           {
 1723               for ( Iterator i = extensions.iterator(); i.hasNext(); )
 1724               {
 1725                   Extension ext = (Extension) i.next();
 1726   
 1727                   String version;
 1728                   if ( StringUtils.isEmpty( ext.getVersion() ) )
 1729                   {
 1730                       version = "RELEASE";
 1731                   }
 1732                   else
 1733                   {
 1734                       version = ext.getVersion();
 1735                   }
 1736   
 1737                   Artifact artifact;
 1738                   try
 1739                   {
 1740                       VersionRange versionRange = VersionRange.createFromVersionSpec( version );
 1741                       artifact =
 1742                           artifactFactory.createExtensionArtifact( ext.getGroupId(), ext.getArtifactId(), versionRange );
 1743                   }
 1744                   catch ( InvalidVersionSpecificationException e )
 1745                   {
 1746                       throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
 1747                           "' for extension '" + ArtifactUtils.versionlessKey( ext.getGroupId(), ext.getArtifactId() ) +
 1748                           "': " + e.getMessage(), e );
 1749                   }
 1750   
 1751                   if ( artifact != null )
 1752                   {
 1753                       extensionArtifacts.add( artifact );
 1754                   }
 1755               }
 1756           }
 1757   
 1758           return extensionArtifacts;
 1759       }
 1760   
 1761       // ----------------------------------------------------------------------
 1762       //
 1763       // ----------------------------------------------------------------------
 1764   
 1765       private Model getSuperModel()
 1766           throws ProjectBuildingException
 1767       {
 1768           URL url = DefaultMavenProjectBuilder.class.getResource( "pom-" + MAVEN_MODEL_VERSION + ".xml" );
 1769   
 1770           String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID );
 1771   
 1772           return readModel( projectId, url, true );
 1773       }
 1774   
 1775       public void contextualize( Context context )
 1776           throws ContextException
 1777       {
 1778           container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 1779       }
 1780   
 1781   }

Save This Page
Home » maven-2.0.9-src » org.apache » maven » project » [javadoc | source]