Coverage Report - org.apache.maven.project.DefaultMavenProjectBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultMavenProjectBuilder
74 %
596/809
61 %
239/392
5,31
 
 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.manager.WagonManager;
 27  
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
 28  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 29  
 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
 30  
 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
 31  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 32  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 33  
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 34  
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 35  
 import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
 36  
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 37  
 import org.apache.maven.artifact.versioning.ManagedVersionMap;
 38  
 import org.apache.maven.artifact.versioning.VersionRange;
 39  
 import org.apache.maven.model.Build;
 40  
 import org.apache.maven.model.Dependency;
 41  
 import org.apache.maven.model.DependencyManagement;
 42  
 import org.apache.maven.model.DistributionManagement;
 43  
 import org.apache.maven.model.Exclusion;
 44  
 import org.apache.maven.model.Extension;
 45  
 import org.apache.maven.model.Model;
 46  
 import org.apache.maven.model.Parent;
 47  
 import org.apache.maven.model.Plugin;
 48  
 import org.apache.maven.model.PluginExecution;
 49  
 import org.apache.maven.model.PluginManagement;
 50  
 import org.apache.maven.model.Profile;
 51  
 import org.apache.maven.model.ReportPlugin;
 52  
 import org.apache.maven.model.Repository;
 53  
 import org.apache.maven.model.Resource;
 54  
 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
 55  
 import org.apache.maven.profiles.DefaultProfileManager;
 56  
 import org.apache.maven.profiles.MavenProfilesBuilder;
 57  
 import org.apache.maven.profiles.ProfileManager;
 58  
 import org.apache.maven.profiles.ProfilesConversionUtils;
 59  
 import org.apache.maven.profiles.ProfilesRoot;
 60  
 import org.apache.maven.profiles.activation.ProfileActivationException;
 61  
 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
 62  
 import org.apache.maven.project.artifact.ProjectArtifactFactory;
 63  
 import org.apache.maven.project.inheritance.ModelInheritanceAssembler;
 64  
 import org.apache.maven.project.injection.ModelDefaultsInjector;
 65  
 import org.apache.maven.project.injection.ProfileInjector;
 66  
 import org.apache.maven.project.interpolation.ModelInterpolationException;
 67  
 import org.apache.maven.project.interpolation.ModelInterpolator;
 68  
 import org.apache.maven.project.path.PathTranslator;
 69  
 import org.apache.maven.project.validation.ModelValidationResult;
 70  
 import org.apache.maven.project.validation.ModelValidator;
 71  
 import org.apache.maven.wagon.events.TransferListener;
 72  
 import org.codehaus.plexus.PlexusConstants;
 73  
 import org.codehaus.plexus.PlexusContainer;
 74  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 75  
 import org.codehaus.plexus.context.Context;
 76  
 import org.codehaus.plexus.context.ContextException;
 77  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 78  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 79  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 80  
 import org.codehaus.plexus.util.IOUtil;
 81  
 import org.codehaus.plexus.util.ReaderFactory;
 82  
 import org.codehaus.plexus.util.StringUtils;
 83  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 84  
 
 85  
 import java.io.File;
 86  
 import java.io.FileNotFoundException;
 87  
 import java.io.IOException;
 88  
 import java.io.Reader;
 89  
 import java.io.StringReader;
 90  
 import java.net.URL;
 91  
 import java.util.ArrayList;
 92  
 import java.util.Collections;
 93  
 import java.util.Date;
 94  
 import java.util.HashMap;
 95  
 import java.util.HashSet;
 96  
 import java.util.Iterator;
 97  
 import java.util.LinkedHashSet;
 98  
 import java.util.LinkedList;
 99  
 import java.util.List;
 100  
 import java.util.Map;
 101  
 import java.util.Set;
 102  
 import java.util.TreeMap;
 103  
 
 104  
 /*:apt
 105  
 
 106  
  -----
 107  
  POM lifecycle
 108  
  -----
 109  
 
 110  
 POM Lifecycle
 111  
 
 112  
  Order of operations when building a POM
 113  
 
 114  
  * inheritance
 115  
  * path translation
 116  
  * interpolation
 117  
  * defaults injection
 118  
 
 119  
  Current processing is:
 120  
 
 121  
  * inheritance
 122  
  * interpolation
 123  
  * defaults injection
 124  
  * path translation
 125  
 
 126  
  I'm not sure how this is working at all ... i think i have a case where this is failing but i need to
 127  
  encapsulate as a test so i can fix it. Also need to think of the in working build directory versus looking
 128  
  things up from the repository i.e buildFromSource vs buildFromRepository.
 129  
 
 130  
 Notes
 131  
 
 132  
  * when the model is read it may not have a groupId, as it must be inherited
 133  
 
 134  
  * the inheritance assembler must use models that are unadulterated!
 135  
 
 136  
 */
 137  
 
 138  
 /**
 139  
  * @version $Id: DefaultMavenProjectBuilder.java 788791 2009-06-26 17:55:26Z jdcasey $
 140  
  */
 141  59
 public class DefaultMavenProjectBuilder
 142  
     extends AbstractLogEnabled
 143  
     implements MavenProjectBuilder, Initializable, Contextualizable
 144  
 {
 145  
     // TODO: remove
 146  
     private PlexusContainer container;
 147  
 
 148  
     protected MavenProfilesBuilder profilesBuilder;
 149  
 
 150  
     protected ArtifactResolver artifactResolver;
 151  
 
 152  
     protected ArtifactMetadataSource artifactMetadataSource;
 153  
 
 154  
     private ProjectArtifactFactory artifactFactory;
 155  
 
 156  
     private ModelInheritanceAssembler modelInheritanceAssembler;
 157  
 
 158  
     private ProfileInjector profileInjector;
 159  
 
 160  
     private ModelValidator validator;
 161  
 
 162  59
     private Map rawProjectCache = new HashMap();
 163  
 
 164  59
     private Map processedProjectCache = new HashMap();
 165  
 
 166  
     // TODO: make it a component
 167  
     private MavenXpp3Reader modelReader;
 168  
 
 169  
     private PathTranslator pathTranslator;
 170  
 
 171  
     private ModelDefaultsInjector modelDefaultsInjector;
 172  
 
 173  
     private ModelInterpolator modelInterpolator;
 174  
     
 175  
     private ArtifactRepositoryFactory artifactRepositoryFactory;
 176  
 
 177  
     // ----------------------------------------------------------------------
 178  
     // I am making this available for use with a new method that takes a
 179  
     // a monitor wagon monitor as a parameter so that tools can use the
 180  
     // methods here and receive callbacks. MNG-1015
 181  
     // ----------------------------------------------------------------------
 182  
 
 183  
     private WagonManager wagonManager;
 184  
 
 185  
     public static final String MAVEN_MODEL_VERSION = "4.0.0";
 186  
 
 187  
     public void initialize()
 188  
     {
 189  58
         modelReader = new MavenXpp3Reader();
 190  58
     }
 191  
 
 192  
     // ----------------------------------------------------------------------
 193  
     // MavenProjectBuilder Implementation
 194  
     // ----------------------------------------------------------------------
 195  
 
 196  
     public MavenProject build( File pom,
 197  
                                ProjectBuilderConfiguration config )
 198  
         throws ProjectBuildingException
 199  
     {
 200  10
         return buildFromSourceFileInternal( pom, config, true );
 201  
     }
 202  
 
 203  
     public MavenProject build( File pom,
 204  
                                ProjectBuilderConfiguration config,
 205  
                                boolean checkDistributionManagementStatus )
 206  
         throws ProjectBuildingException
 207  
     {
 208  0
         return buildFromSourceFileInternal( pom, config, checkDistributionManagementStatus );
 209  
     }
 210  
 
 211  
     public MavenProject build( File projectDescriptor,
 212  
                                ArtifactRepository localRepository,
 213  
                                ProfileManager profileManager )
 214  
         throws ProjectBuildingException
 215  
     {
 216  22
         ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager );
 217  22
         return buildFromSourceFileInternal( projectDescriptor, config, true );
 218  
     }
 219  
 
 220  
     public MavenProject build( File projectDescriptor,
 221  
                                ArtifactRepository localRepository,
 222  
                                ProfileManager profileManager,
 223  
                                boolean checkDistributionManagementStatus )
 224  
         throws ProjectBuildingException
 225  
     {
 226  28
         ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository ).setGlobalProfileManager( profileManager );
 227  28
         return buildFromSourceFileInternal( projectDescriptor, config, checkDistributionManagementStatus );
 228  
     }
 229  
 
 230  
     // jvz:note
 231  
     // When asked for something from the repository are we getting it from the reactor? Yes, when using this call
 232  
     // we are assuming that the reactor has been run and we have collected the projects required to satisfy it0042
 233  
     // which means the projects in the reactor are required for finding classes in <project>/target/classes. Not
 234  
     // sure this is ideal. I remove all caching from the builder and all reactor related ITs which assume
 235  
     // access to simbling project resources failed.
 236  
     public MavenProject buildFromRepository( Artifact artifact,
 237  
                                              List remoteArtifactRepositories,
 238  
                                              ArtifactRepository localRepository,
 239  
                                              boolean allowStubModel )
 240  
         throws ProjectBuildingException
 241  
     {
 242  99
         String cacheKey = createCacheKey( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
 243  
 
 244  99
         MavenProject project = (MavenProject) processedProjectCache.get( cacheKey );
 245  
 
 246  99
         if ( project != null )
 247  
         {
 248  62
             return project;
 249  
         }
 250  
 
 251  37
         Model model = findModelFromRepository( artifact, remoteArtifactRepositories, localRepository, allowStubModel );
 252  
 
 253  37
         ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository );
 254  
 
 255  37
         return buildInternal( "Artifact [" + artifact + "]", model, config, remoteArtifactRepositories,
 256  
                               null, false );
 257  
     }
 258  
 
 259  
     public MavenProject buildFromRepository( Artifact artifact,
 260  
                                              List remoteArtifactRepositories,
 261  
                                              ArtifactRepository localRepository )
 262  
         throws ProjectBuildingException
 263  
     {
 264  0
         return buildFromRepository( artifact, remoteArtifactRepositories, localRepository, true );
 265  
     }
 266  
 
 267  
     // what is using this externally? jvz.
 268  
     public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository )
 269  
         throws ProjectBuildingException
 270  
     {
 271  
         //TODO mkleint - use the (Container, Properties) constructor to make system properties embeddable
 272  0
         ProfileManager profileManager = new DefaultProfileManager( container );
 273  
 
 274  0
         return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository )
 275  
                                                                                     .setGlobalProfileManager( profileManager ) );
 276  
     }
 277  
 
 278  
     public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository,
 279  
                                                      ProfileManager profileManager )
 280  
         throws ProjectBuildingException
 281  
     {
 282  2
         return buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration().setLocalRepository( localRepository )
 283  
                                                                                     .setGlobalProfileManager( profileManager ) );
 284  
     }
 285  
 
 286  
     public MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration config )
 287  
         throws ProjectBuildingException
 288  
     {
 289  12
         Model superModel = getSuperModel();
 290  
 
 291  12
         superModel.setGroupId( STANDALONE_SUPERPOM_GROUPID );
 292  
 
 293  12
         superModel.setArtifactId( STANDALONE_SUPERPOM_ARTIFACTID );
 294  
 
 295  12
         superModel.setVersion( STANDALONE_SUPERPOM_VERSION );
 296  
 
 297  
 
 298  
         List activeProfiles;
 299  
 
 300  12
         ProfileManager profileManager = config.getGlobalProfileManager();
 301  
 
 302  12
         if ( profileManager == null )
 303  
         {
 304  10
             profileManager = new DefaultProfileManager( container );
 305  
         }
 306  
 
 307  12
         profileManager.addProfiles( superModel.getProfiles() );
 308  
 
 309  12
         String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID );
 310  
 
 311  12
         activeProfiles = injectActiveProfiles( profileManager, superModel );
 312  
 
 313  12
         MavenProject project = new MavenProject( superModel );
 314  
 
 315  12
         project.setManagedVersionMap(
 316  
             createManagedVersionMap( projectId, superModel.getDependencyManagement(), null ) );
 317  
 
 318  12
         project.setActiveProfiles( activeProfiles );
 319  
 
 320  12
         project.setOriginalModel( superModel );
 321  
 
 322  
         try
 323  
         {
 324  12
             project = processProjectLogic( "<Super-POM>", project, config, null, null, true, true );
 325  
 
 326  12
             project.setExecutionRoot( true );
 327  
 
 328  12
             return project;
 329  
         }
 330  0
         catch ( ModelInterpolationException e )
 331  
         {
 332  0
             throw new ProjectBuildingException( projectId, e.getMessage(), e );
 333  
         }
 334  0
         catch ( InvalidRepositoryException e )
 335  
         {
 336  0
             throw new ProjectBuildingException( projectId, e.getMessage(), e );
 337  
         }
 338  
     }
 339  
 
 340  
     public MavenProject buildWithDependencies( File projectDescriptor,
 341  
                                                ArtifactRepository localRepository,
 342  
                                                ProfileManager profileManager )
 343  
         throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
 344  
     {
 345  28
         return buildWithDependencies( projectDescriptor, localRepository, profileManager, null );
 346  
     }
 347  
 
 348  
     // note:jvz This was added for the embedder.
 349  
 
 350  
     /** @todo move to metadatasource itself? */
 351  
     public MavenProject buildWithDependencies( File projectDescriptor,
 352  
                                                ArtifactRepository localRepository,
 353  
                                                ProfileManager profileManager,
 354  
                                                TransferListener transferListener )
 355  
         throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
 356  
     {
 357  28
         MavenProject project = build( projectDescriptor, localRepository, profileManager, false );
 358  
 
 359  
         // ----------------------------------------------------------------------
 360  
         // Typically when the project builder is being used from maven proper
 361  
         // the transitive dependencies will not be resolved here because this
 362  
         // requires a lot of work when we may only be interested in running
 363  
         // something simple like 'm2 clean'. So the artifact collector is used
 364  
         // in the dependency resolution phase if it is required by any of the
 365  
         // goals being executed. But when used as a component in another piece
 366  
         // of code people may just want to build maven projects and have the
 367  
         // dependencies resolved for whatever reason: this is why we keep
 368  
         // this snippet of code here.
 369  
         // ----------------------------------------------------------------------
 370  
 
 371  
         // TODO: such a call in MavenMetadataSource too - packaging not really the intention of type
 372  28
         Artifact projectArtifact = project.getArtifact();
 373  
 
 374  28
         String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() );
 375  
 
 376  
         // Map managedVersions = createManagedVersionMap( projectId, project.getDependencyManagement() );
 377  28
         Map managedVersions = project.getManagedVersionMap();
 378  
 
 379  28
         ensureMetadataSourceIsInitialized();
 380  
 
 381  
         try
 382  
         {
 383  28
             project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) );
 384  
         }
 385  0
         catch ( InvalidDependencyVersionException e )
 386  
         {
 387  0
             throw new ProjectBuildingException( projectId,
 388  
                                                 "Unable to build project due to an invalid dependency version: " +
 389  
                                                     e.getMessage(), e );
 390  28
         }
 391  
 
 392  28
         if ( transferListener != null )
 393  
         {
 394  0
             wagonManager.setDownloadMonitor( transferListener );
 395  
         }
 396  
 
 397  28
         ArtifactResolutionResult result = artifactResolver.resolveTransitively( project.getDependencyArtifacts(),
 398  
                                                                                 projectArtifact, managedVersions,
 399  
                                                                                 localRepository,
 400  
                                                                                 project.getRemoteArtifactRepositories(),
 401  
                                                                                 artifactMetadataSource );
 402  
 
 403  28
         project.setArtifacts( result.getArtifacts() );
 404  
 
 405  28
         return project;
 406  
     }
 407  
 
 408  
     // ----------------------------------------------------------------------
 409  
     //
 410  
     // ----------------------------------------------------------------------
 411  
 
 412  
     private void ensureMetadataSourceIsInitialized()
 413  
         throws ProjectBuildingException
 414  
     {
 415  28
         if ( artifactMetadataSource == null )
 416  
         {
 417  
             try
 418  
             {
 419  13
                 artifactMetadataSource = (ArtifactMetadataSource) container.lookup( ArtifactMetadataSource.ROLE );
 420  
             }
 421  0
             catch ( ComponentLookupException e )
 422  
             {
 423  0
                 throw new ProjectBuildingException( "all", "Cannot lookup metadata source for building the project.",
 424  
                                                     e );
 425  13
             }
 426  
         }
 427  28
     }
 428  
 
 429  
     private Map createManagedVersionMap( String projectId,
 430  
                                          DependencyManagement dependencyManagement,
 431  
                                          MavenProject parent )
 432  
         throws ProjectBuildingException
 433  
     {
 434  109
         Map map = null;
 435  
         List deps;
 436  109
         if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null ) &&
 437  
             ( deps.size() > 0 ) )
 438  
         {
 439  24
             map = new ManagedVersionMap( map );
 440  
 
 441  24
             if ( getLogger().isDebugEnabled() )
 442  
             {
 443  0
                 getLogger().debug( "Adding managed dependencies for " + projectId );
 444  
             }
 445  
 
 446  24
             for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); )
 447  
             {
 448  68
                 Dependency d = (Dependency) i.next();
 449  
 
 450  
                 try
 451  
                 {
 452  68
                     VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
 453  
 
 454  68
                     Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(),
 455  
                                                                                   versionRange, d.getType(),
 456  
                                                                                   d.getClassifier(), d.getScope(),
 457  
                                                                                   d.isOptional() );
 458  68
                     if ( getLogger().isDebugEnabled() )
 459  
                     {
 460  0
                         getLogger().debug( "  " + artifact );
 461  
                     }
 462  
 
 463  
                     // If the dependencyManagement section listed exclusions,
 464  
                     // add them to the managed artifacts here so that transitive
 465  
                     // dependencies will be excluded if necessary.
 466  68
                     if ( ( null != d.getExclusions() ) && !d.getExclusions().isEmpty() )
 467  
                     {
 468  4
                         List exclusions = new ArrayList();
 469  
 
 470  4
                         Iterator exclItr = d.getExclusions().iterator();
 471  
 
 472  8
                         while ( exclItr.hasNext() )
 473  
                         {
 474  4
                             Exclusion e = (Exclusion) exclItr.next();
 475  4
                             exclusions.add( e.getGroupId() + ":" + e.getArtifactId() );
 476  4
                         }
 477  4
                         ExcludesArtifactFilter eaf = new ExcludesArtifactFilter( exclusions );
 478  4
                         artifact.setDependencyFilter( eaf );
 479  4
                     }
 480  
                     else
 481  
                     {
 482  64
                         artifact.setDependencyFilter( null );
 483  
                     }
 484  68
                     map.put( d.getManagementKey(), artifact );
 485  
                 }
 486  0
                 catch ( InvalidVersionSpecificationException e )
 487  
                 {
 488  0
                     throw new ProjectBuildingException( projectId, "Unable to parse version '" + d.getVersion() +
 489  
                         "' for dependency '" + d.getManagementKey() + "': " + e.getMessage(), e );
 490  68
                 }
 491  68
             }
 492  
         }
 493  85
         else if ( map == null )
 494  
         {
 495  85
             map = Collections.EMPTY_MAP;
 496  
         }
 497  
 
 498  109
         return map;
 499  
     }
 500  
 
 501  
     private MavenProject buildFromSourceFileInternal( File projectDescriptor,
 502  
                                                       ProjectBuilderConfiguration config,
 503  
                                                       boolean checkDistributionManagementStatus )
 504  
         throws ProjectBuildingException
 505  
     {
 506  60
         Model model = readModel( "unknown", projectDescriptor, true );
 507  
 
 508  60
         MavenProject project = buildInternal( projectDescriptor.getAbsolutePath(), model, config,
 509  
                                               buildArtifactRepositories( getSuperModel() ), projectDescriptor,
 510  
                                               true );
 511  
 
 512  60
         if ( checkDistributionManagementStatus )
 513  
         {
 514  32
             if ( ( project.getDistributionManagement() != null ) &&
 515  
                 ( project.getDistributionManagement().getStatus() != null ) )
 516  
             {
 517  0
                 String projectId = safeVersionlessKey( project.getGroupId(), project.getArtifactId() );
 518  
 
 519  0
                 throw new ProjectBuildingException( projectId,
 520  
                                                     "Invalid project file: distribution status must not be specified for a project outside of the repository" );
 521  
             }
 522  
         }
 523  
 
 524  60
         return project;
 525  
     }
 526  
 
 527  
     private Model findModelFromRepository( Artifact artifact,
 528  
                                            List remoteArtifactRepositories,
 529  
                                            ArtifactRepository localRepository,
 530  
                                            boolean allowStubModel )
 531  
         throws ProjectBuildingException
 532  
     {
 533  41
         String projectId = safeVersionlessKey( artifact.getGroupId(), artifact.getArtifactId() );
 534  
 
 535  41
         normalizeToArtifactRepositories( remoteArtifactRepositories, projectId );
 536  
 
 537  
         Artifact projectArtifact;
 538  
 
 539  
         // if the artifact is not a POM, we need to construct a POM artifact based on the artifact parameter given.
 540  41
         if ( "pom".equals( artifact.getType() ) )
 541  
         {
 542  41
             projectArtifact = artifact;
 543  
         }
 544  
         else
 545  
         {
 546  0
             getLogger().debug( "Attempting to build MavenProject instance for Artifact (" + artifact.getGroupId() + ":"
 547  
                                   + artifact.getArtifactId() + ":" + artifact.getVersion() + ") of type: "
 548  
                                   + artifact.getType() + "; constructing POM artifact instead." );
 549  
 
 550  0
             projectArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
 551  
                                                                      artifact.getVersion(), artifact.getScope() );
 552  
         }
 553  
 
 554  
         Model model;
 555  
 
 556  
         try
 557  
         {
 558  41
             artifactResolver.resolve( projectArtifact, remoteArtifactRepositories, localRepository );
 559  
 
 560  41
             File file = projectArtifact.getFile();
 561  
 
 562  41
             model = readModel( projectId, file, false );
 563  
 
 564  41
             String downloadUrl = null;
 565  
 
 566  41
             ArtifactStatus status = ArtifactStatus.NONE;
 567  
 
 568  41
             DistributionManagement distributionManagement = model.getDistributionManagement();
 569  
 
 570  41
             if ( distributionManagement != null )
 571  
             {
 572  0
                 downloadUrl = distributionManagement.getDownloadUrl();
 573  
 
 574  0
                 status = ArtifactStatus.valueOf( distributionManagement.getStatus() );
 575  
             }
 576  
 
 577  41
             checkStatusAndUpdate( projectArtifact, status, file, remoteArtifactRepositories, localRepository );
 578  
 
 579  
             // TODO: this is gross. Would like to give it the whole model, but maven-artifact shouldn't depend on that
 580  
             // Can a maven-core implementation of the Artifact interface store it, and be used in the exceptions?
 581  41
             if ( downloadUrl != null )
 582  
             {
 583  0
                 projectArtifact.setDownloadUrl( downloadUrl );
 584  
             }
 585  
             else
 586  
             {
 587  41
                 projectArtifact.setDownloadUrl( model.getUrl() );
 588  
             }
 589  
         }
 590  0
         catch ( ArtifactResolutionException e )
 591  
         {
 592  0
             throw new ProjectBuildingException( projectId, "Error getting POM for '" + projectId +
 593  
                 "' from the repository: " + e.getMessage(), e );
 594  
         }
 595  0
         catch ( ArtifactNotFoundException e )
 596  
         {
 597  0
             if ( allowStubModel )
 598  
             {
 599  0
                 getLogger().debug( "Artifact not found - using stub model: " + e.getMessage() );
 600  
 
 601  0
                 model = createStubModel( projectArtifact );
 602  
             }
 603  
             else
 604  
             {
 605  0
                 throw new ProjectBuildingException( projectId, "POM '" + projectId + "' not found in repository: " +
 606  
                     e.getMessage(), e );
 607  
             }
 608  41
         }
 609  
 
 610  41
         return model;
 611  
     }
 612  
 
 613  
     private List normalizeToArtifactRepositories( List remoteArtifactRepositories,
 614  
                                                   String projectId )
 615  
         throws ProjectBuildingException
 616  
     {
 617  41
         List normalized = new ArrayList( remoteArtifactRepositories.size() );
 618  
 
 619  41
         boolean normalizationNeeded = false;
 620  41
         for ( Iterator it = remoteArtifactRepositories.iterator(); it.hasNext(); )
 621  
         {
 622  41
             Object item = it.next();
 623  
 
 624  41
             if ( item instanceof ArtifactRepository )
 625  
             {
 626  41
                 normalized.add( item );
 627  
             }
 628  0
             else if ( item instanceof Repository )
 629  
             {
 630  0
                 Repository repo = (Repository) item;
 631  
                 try
 632  
                 {
 633  0
                     item = ProjectUtils.buildArtifactRepository( repo, artifactRepositoryFactory, container );
 634  
 
 635  0
                     normalized.add( item );
 636  0
                     normalizationNeeded = true;
 637  
                 }
 638  0
                 catch ( InvalidRepositoryException e )
 639  
                 {
 640  0
                     throw new ProjectBuildingException( projectId, "Error building artifact repository for id: " + repo.getId(), e );
 641  0
                 }
 642  0
             }
 643  
             else
 644  
             {
 645  0
                 throw new ProjectBuildingException( projectId, "Error building artifact repository from non-repository information item: " + item );
 646  
             }
 647  41
         }
 648  
 
 649  41
         if ( normalizationNeeded )
 650  
         {
 651  0
             return normalized;
 652  
         }
 653  
         else
 654  
         {
 655  41
             return remoteArtifactRepositories;
 656  
         }
 657  
     }
 658  
 
 659  
     private void checkStatusAndUpdate( Artifact projectArtifact,
 660  
                                        ArtifactStatus status,
 661  
                                        File file,
 662  
                                        List remoteArtifactRepositories,
 663  
                                        ArtifactRepository localRepository )
 664  
         throws ArtifactNotFoundException
 665  
     {
 666  
         // TODO: configurable actions dependant on status
 667  41
         if ( !projectArtifact.isSnapshot() && ( status.compareTo( ArtifactStatus.DEPLOYED ) < 0 ) )
 668  
         {
 669  
             // use default policy (enabled, daily update, warn on bad checksum)
 670  41
             ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy();
 671  
             // TODO: re-enable [MNG-798/865]
 672  41
             policy.setUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER );
 673  
 
 674  41
             if ( policy.checkOutOfDate( new Date( file.lastModified() ) ) )
 675  
             {
 676  0
                 getLogger().info(
 677  
                     projectArtifact.getArtifactId() + ": updating metadata due to status of '" + status + "'" );
 678  
                 try
 679  
                 {
 680  0
                     projectArtifact.setResolved( false );
 681  0
                     artifactResolver.resolveAlways( projectArtifact, remoteArtifactRepositories, localRepository );
 682  
                 }
 683  0
                 catch ( ArtifactResolutionException e )
 684  
                 {
 685  0
                     getLogger().warn( "Error updating POM - using existing version" );
 686  0
                     getLogger().debug( "Cause", e );
 687  
                 }
 688  0
                 catch ( ArtifactNotFoundException e )
 689  
                 {
 690  0
                     getLogger().warn( "Error updating POM - not found. Removing local copy." );
 691  0
                     getLogger().debug( "Cause", e );
 692  0
                     file.delete();
 693  0
                     throw e;
 694  0
                 }
 695  
             }
 696  
         }
 697  41
     }
 698  
 
 699  
     // jvz:note
 700  
     // This is used when requested artifacts do not have an associated POM. This is for the case where we are
 701  
     // using an m1 repo where the only thing required to be present are the JAR files.
 702  
     private Model createStubModel( Artifact projectArtifact )
 703  
     {
 704  0
         getLogger().debug( "Using defaults for missing POM " + projectArtifact );
 705  
 
 706  0
         Model model = new Model();
 707  
 
 708  0
         model.setModelVersion( "4.0.0" );
 709  
 
 710  0
         model.setArtifactId( projectArtifact.getArtifactId() );
 711  
 
 712  0
         model.setGroupId( projectArtifact.getGroupId() );
 713  
 
 714  0
         model.setVersion( projectArtifact.getVersion() );
 715  
 
 716  
         // TODO: not correct in some instances
 717  0
         model.setPackaging( projectArtifact.getType() );
 718  
 
 719  0
         model.setDistributionManagement( new DistributionManagement() );
 720  
 
 721  0
         model.getDistributionManagement().setStatus( ArtifactStatus.GENERATED.toString() );
 722  
 
 723  0
         return model;
 724  
     }
 725  
 
 726  
     // jvz:note
 727  
     // We've got a mixture of things going in the USD and from the repository, sometimes the descriptor
 728  
     // is a real file and sometimes null which makes things confusing.
 729  
     private MavenProject buildInternal( String pomLocation,
 730  
                                         Model model,
 731  
                                         ProjectBuilderConfiguration config,
 732  
                                         List parentSearchRepositories,
 733  
                                         File projectDescriptor,
 734  
                                         boolean strict )
 735  
         throws ProjectBuildingException
 736  
     {
 737  97
         File projectDir = null;
 738  
 
 739  97
         if ( projectDescriptor != null )
 740  
         {
 741  60
             projectDir = projectDescriptor.getAbsoluteFile().getParentFile();
 742  
         }
 743  
 
 744  97
         Model superModel = getSuperModel();
 745  
 
 746  97
         ProfileManager externalProfileManager = config.getGlobalProfileManager();
 747  
         ProfileManager superProjectProfileManager;
 748  97
         if ( externalProfileManager != null )
 749  
         {
 750  22
             superProjectProfileManager = new DefaultProfileManager(
 751  
                                                                     container,
 752  
                                                                     externalProfileManager.getRequestProperties() );
 753  
         }
 754  
         else
 755  
         {
 756  75
             superProjectProfileManager = new DefaultProfileManager( container );
 757  
         }
 758  
 
 759  
         List activeProfiles;
 760  
 
 761  97
         superProjectProfileManager.addProfiles( superModel.getProfiles() );
 762  
 
 763  97
         activeProfiles = injectActiveProfiles( superProjectProfileManager, superModel );
 764  
 
 765  97
         MavenProject superProject = new MavenProject( superModel );
 766  
 
 767  97
         superProject.setActiveProfiles( activeProfiles );
 768  
 
 769  
         //noinspection CollectionDeclaredAsConcreteClass
 770  97
         LinkedList lineage = new LinkedList();
 771  
 
 772  
         // TODO: the aRWR can get out of sync with project.model.repositories. We should do all the processing of
 773  
         // profiles, etc on the models then recreate the aggregated sets at the end from the project repositories (they
 774  
         // must still be created along the way so that parent poms can be discovered, however)
 775  
         // Use a TreeSet to ensure ordering is retained
 776  97
         Set aggregatedRemoteWagonRepositories = new LinkedHashSet();
 777  
 
 778  97
         String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 779  
 
 780  
         List activeExternalProfiles;
 781  
         try
 782  
         {
 783  97
             if ( externalProfileManager != null )
 784  
             {
 785  22
                 activeExternalProfiles = externalProfileManager.getActiveProfiles();
 786  
             }
 787  
             else
 788  
             {
 789  75
                 activeExternalProfiles = Collections.EMPTY_LIST;
 790  
             }
 791  
         }
 792  0
         catch ( ProfileActivationException e )
 793  
         {
 794  0
             throw new ProjectBuildingException( projectId, "Failed to calculate active external profiles.", e );
 795  97
         }
 796  
 
 797  97
         for ( Iterator i = activeExternalProfiles.iterator(); i.hasNext(); )
 798  
         {
 799  0
             Profile externalProfile = (Profile) i.next();
 800  
 
 801  0
             for ( Iterator repoIterator = externalProfile.getRepositories().iterator(); repoIterator.hasNext(); )
 802  
             {
 803  0
                 Repository mavenRepo = (Repository) repoIterator.next();
 804  
 
 805  0
                 ArtifactRepository artifactRepo = null;
 806  
                 try
 807  
                 {
 808  0
                     artifactRepo =
 809  
                         ProjectUtils.buildArtifactRepository( mavenRepo, artifactRepositoryFactory, container );
 810  
                 }
 811  0
                 catch ( InvalidRepositoryException e )
 812  
                 {
 813  0
                     throw new ProjectBuildingException( projectId, e.getMessage(), e );
 814  0
                 }
 815  
 
 816  0
                 aggregatedRemoteWagonRepositories.add( artifactRepo );
 817  0
             }
 818  0
         }
 819  
 
 820  97
         MavenProject project = null;
 821  
         try
 822  
         {
 823  97
             project = assembleLineage( model, lineage, config, projectDescriptor, parentSearchRepositories,
 824  
                                        aggregatedRemoteWagonRepositories, strict );
 825  
         }
 826  0
         catch ( InvalidRepositoryException e )
 827  
         {
 828  0
             throw new ProjectBuildingException( projectId, e.getMessage(), e );
 829  97
         }
 830  
 
 831  
         // we don't have to force the collision exception for superModel here, it's already been done in getSuperModel()
 832  97
         MavenProject previousProject = superProject;
 833  
 
 834  97
         Model previous = superProject.getModel();
 835  
 
 836  97
         for ( Iterator i = lineage.iterator(); i.hasNext(); )
 837  
         {
 838  144
             MavenProject currentProject = (MavenProject) i.next();
 839  
 
 840  144
             Model current = currentProject.getModel();
 841  
 
 842  144
             String pathAdjustment = null;
 843  
 
 844  
             try
 845  
             {
 846  144
                 pathAdjustment = previousProject.getModulePathAdjustment( currentProject );
 847  
             }
 848  0
             catch ( IOException e )
 849  
             {
 850  0
                 getLogger().debug( "Cannot determine whether " + currentProject.getId() + " is a module of " +
 851  
                     previousProject.getId() + ". Reason: " + e.getMessage(), e );
 852  144
             }
 853  
 
 854  144
             modelInheritanceAssembler.assembleModelInheritance( current, previous, pathAdjustment );
 855  
 
 856  144
             previous = current;
 857  144
             previousProject = currentProject;
 858  144
         }
 859  
 
 860  
         // only add the super repository if it wasn't overridden by a profile or project
 861  97
         List repositories = new ArrayList( aggregatedRemoteWagonRepositories );
 862  
 
 863  97
         List superRepositories = buildArtifactRepositories( superModel );
 864  
 
 865  97
         for ( Iterator i = superRepositories.iterator(); i.hasNext(); )
 866  
         {
 867  97
             ArtifactRepository repository = (ArtifactRepository) i.next();
 868  
 
 869  97
             if ( !repositories.contains( repository ) )
 870  
             {
 871  87
                 repositories.add( repository );
 872  
             }
 873  97
         }
 874  
 
 875  
         // merge any duplicated plugin definitions together, using the first appearance as the dominant one.
 876  97
         ModelUtils.mergeDuplicatePluginDefinitions( project.getModel().getBuild() );
 877  
 
 878  
         try
 879  
         {
 880  97
             project = processProjectLogic( pomLocation, project, config, projectDir, repositories, strict, false );
 881  
         }
 882  0
         catch ( ModelInterpolationException e )
 883  
         {
 884  0
             throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
 885  
         }
 886  0
         catch ( InvalidRepositoryException e )
 887  
         {
 888  0
             throw new InvalidProjectModelException( projectId, pomLocation, e.getMessage(), e );
 889  97
         }
 890  
 
 891  97
         processedProjectCache.put(
 892  
                                   createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project );
 893  
 
 894  
           // jvz:note
 895  
         // this only happens if we are building from a source file
 896  97
         if ( projectDescriptor != null )
 897  
         {
 898  60
             Build build = project.getBuild();
 899  
 
 900  60
             project.addCompileSourceRoot( build.getSourceDirectory() );
 901  
 
 902  60
             project.addScriptSourceRoot( build.getScriptSourceDirectory() );
 903  
 
 904  60
             project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
 905  
 
 906  
             // Only track the file of a POM in the source tree
 907  60
             project.setFile( projectDescriptor );
 908  
         }
 909  
         
 910  97
         project.setManagedVersionMap( createManagedVersionMap( projectId,
 911  
                                                                project.getDependencyManagement(),
 912  
                                                                project.getParent() ) );
 913  
 
 914  97
         return project;
 915  
     }
 916  
 
 917  
     private String safeVersionlessKey( String groupId,
 918  
                                        String artifactId )
 919  
     {
 920  600
         String gid = groupId;
 921  
 
 922  600
         if ( StringUtils.isEmpty( gid ) )
 923  
         {
 924  9
             gid = "unknown";
 925  
         }
 926  
 
 927  600
         String aid = artifactId;
 928  
 
 929  600
         if ( StringUtils.isEmpty( aid ) )
 930  
         {
 931  0
             aid = "unknown";
 932  
         }
 933  
 
 934  600
         return ArtifactUtils.versionlessKey( gid, aid );
 935  
     }
 936  
 
 937  
     private List buildArtifactRepositories( Model model )
 938  
         throws ProjectBuildingException
 939  
     {
 940  
         try
 941  
         {
 942  167
             return ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory,
 943  
                                                            container );
 944  
         }
 945  0
         catch ( InvalidRepositoryException e )
 946  
         {
 947  0
             String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 948  
 
 949  0
             throw new ProjectBuildingException( projectId, e.getMessage(), e );
 950  
         }
 951  
     }
 952  
 
 953  
     /**
 954  
      * @todo can this take in a model instead of a project and still be successful?
 955  
      * @todo In fact, does project REALLY need a MavenProject as a parent? Couldn't it have just a wrapper around a
 956  
      * model that supported parents which were also the wrapper so that inheritence was assembled. We don't really need
 957  
      * the resolved source roots, etc for the parent - that occurs for the parent when it is constructed independently
 958  
      * and projects are not cached or reused
 959  
      */
 960  
     private MavenProject processProjectLogic( String pomLocation,
 961  
                                               MavenProject project,
 962  
                                               ProjectBuilderConfiguration config,
 963  
                                               File projectDir,
 964  
                                               List remoteRepositories,
 965  
                                               boolean strict,
 966  
                                               boolean isSuperPom )
 967  
         throws ProjectBuildingException, ModelInterpolationException, InvalidRepositoryException
 968  
     {
 969  109
         Model model = project.getModel();
 970  
 
 971  109
         List activeProfiles = project.getActiveProfiles();
 972  
 
 973  109
         if ( activeProfiles == null )
 974  
         {
 975  0
             activeProfiles = new ArrayList();
 976  
         }
 977  
 
 978  109
         ProfileManager profileMgr = config == null ? null : config.getGlobalProfileManager();
 979  
 
 980  109
         List injectedProfiles = injectActiveProfiles( profileMgr, model );
 981  
 
 982  109
         activeProfiles.addAll( injectedProfiles );
 983  
         
 984  
         // --------------------------------------------------------------------------------
 985  
         
 986  109
         Build dynamicBuild = model.getBuild();
 987  
 
 988  109
         model.setBuild( ModelUtils.cloneBuild( dynamicBuild ) );
 989  
 
 990  109
         model = modelInterpolator.interpolate( model, projectDir, config, getLogger().isDebugEnabled() );
 991  
 
 992  109
         mergeDeterministicBuildElements( model.getBuild(), dynamicBuild );
 993  
 
 994  109
         model.setBuild( dynamicBuild );
 995  
         
 996  
         // MNG-3482: Make sure depMgmt is interpolated before merging.
 997  109
         if ( !isSuperPom )
 998  
         {
 999  97
             mergeManagedDependencies( model, config.getLocalRepository(), remoteRepositories );
 1000  
         }
 1001  
 
 1002  
         // interpolation is before injection, because interpolation is off-limits in the injected variables
 1003  109
         modelDefaultsInjector.injectDefaults( model );
 1004  
 
 1005  109
         MavenProject parentProject = project.getParent();
 1006  
 
 1007  109
         Model originalModel = project.getOriginalModel();
 1008  
 
 1009  
         // We will return a different project object using the new model (hence the need to return a project, not just modify the parameter)
 1010  109
         project = new MavenProject( model, getLogger() );
 1011  
 
 1012  109
         project.setOriginalModel( originalModel );
 1013  
         
 1014  109
         project.setActiveProfiles( activeProfiles );
 1015  
 
 1016  
         // TODO: maybe not strictly correct, while we should enfore that packaging has a type handler of the same id, we don't
 1017  109
         Artifact projectArtifact = artifactFactory.create( project );
 1018  
         
 1019  109
         project.setArtifact( projectArtifact );
 1020  109
         project.setProjectBuilderConfiguration( config );
 1021  
 
 1022  109
         project.setPluginArtifactRepositories( ProjectUtils.buildArtifactRepositories( model.getPluginRepositories(),
 1023  
                                                                                        artifactRepositoryFactory,
 1024  
                                                                                        container ) );
 1025  
 
 1026  109
         DistributionManagement dm = model.getDistributionManagement();
 1027  109
         if ( dm != null )
 1028  
         {
 1029  1
             ArtifactRepository repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getRepository(),
 1030  
                                                                                       artifactRepositoryFactory,
 1031  
                                                                                       container );
 1032  1
             project.setReleaseArtifactRepository( repo );
 1033  
 
 1034  1
             if ( dm.getSnapshotRepository() != null )
 1035  
             {
 1036  1
                 repo = ProjectUtils.buildDeploymentArtifactRepository( dm.getSnapshotRepository(),
 1037  
                                                                        artifactRepositoryFactory, container );
 1038  1
                 project.setSnapshotArtifactRepository( repo );
 1039  
             }
 1040  
         }
 1041  
 
 1042  109
         if ( parentProject != null )
 1043  
         {
 1044  28
             String cacheKey = createCacheKey( parentProject.getGroupId(),
 1045  
                                               parentProject.getArtifactId(),
 1046  
                                               parentProject.getVersion() );
 1047  
 
 1048  28
             MavenProject processedParent = (MavenProject) processedProjectCache.get( cacheKey );
 1049  
             Artifact parentArtifact;
 1050  
 
 1051  
             // yeah, this null check might be a bit paranoid, but better safe than sorry...
 1052  28
             if ( processedParent != null )
 1053  
             {
 1054  25
                 project.setParent( processedParent );
 1055  
 
 1056  25
                 parentArtifact = processedParent.getArtifact();
 1057  
             }
 1058  
             else
 1059  
             {
 1060  3
                 project.setParent( parentProject );
 1061  
 
 1062  3
                 parentArtifact = artifactFactory.createParentArtifact( parentProject.getGroupId(),
 1063  
                                                                                 parentProject.getArtifactId(),
 1064  
                                                                                 parentProject.getVersion() );
 1065  
             }
 1066  
 
 1067  28
             project.setParentArtifact( parentArtifact );
 1068  
         }
 1069  
 
 1070  
         // Must validate before artifact construction to make sure dependencies are good
 1071  109
         ModelValidationResult validationResult = validator.validate( model );
 1072  
 
 1073  109
         String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1074  
 
 1075  109
         if ( validationResult.getMessageCount() > 0 )
 1076  
         {
 1077  0
             throw new InvalidProjectModelException( projectId, pomLocation, "Failed to validate POM",
 1078  
                                                     validationResult );
 1079  
         }
 1080  
 
 1081  109
         project.setRemoteArtifactRepositories(
 1082  
             ProjectUtils.buildArtifactRepositories( model.getRepositories(), artifactRepositoryFactory, container ) );
 1083  
 
 1084  
         // TODO: these aren't taking active project artifacts into consideration in the reactor
 1085  109
         project.setPluginArtifacts( createPluginArtifacts( projectId, project.getBuildPlugins() ) );
 1086  
 
 1087  109
         project.setReportArtifacts( createReportArtifacts( projectId, project.getReportPlugins() ) );
 1088  
 
 1089  109
         project.setExtensionArtifacts( createExtensionArtifacts( projectId, project.getBuildExtensions() ) );
 1090  
         
 1091  109
         return project;
 1092  
     }
 1093  
 
 1094  
     private void mergeDeterministicBuildElements( Build interpolatedBuild,
 1095  
                                                   Build dynamicBuild )
 1096  
     {
 1097  109
         mergeDeterministicPluginElements( interpolatedBuild.getPlugins(), dynamicBuild.getPlugins() );
 1098  
 
 1099  109
         PluginManagement dPluginMgmt = dynamicBuild.getPluginManagement();
 1100  109
         PluginManagement iPluginMgmt = interpolatedBuild.getPluginManagement();
 1101  
 
 1102  109
         if ( dPluginMgmt != null )
 1103  
         {
 1104  109
             mergeDeterministicPluginElements( iPluginMgmt.getPlugins(), dPluginMgmt.getPlugins() );
 1105  
         }
 1106  
 
 1107  109
         if ( dynamicBuild.getExtensions() != null )
 1108  
         {
 1109  109
             dynamicBuild.setExtensions( interpolatedBuild.getExtensions() );
 1110  
         }
 1111  109
     }
 1112  
 
 1113  
     private void mergeDeterministicPluginElements( List iPlugins, List dPlugins )
 1114  
     {
 1115  218
         if ( dPlugins != null )
 1116  
         {
 1117  2317
             for ( int i = 0; i < dPlugins.size(); i++ )
 1118  
             {
 1119  2099
                 Plugin dPlugin = (Plugin) dPlugins.get( i );
 1120  2099
                 Plugin iPlugin = (Plugin) iPlugins.get( i );
 1121  
 
 1122  2099
                 dPlugin.setGroupId( iPlugin.getGroupId() );
 1123  2099
                 dPlugin.setArtifactId( iPlugin.getArtifactId() );
 1124  2099
                 dPlugin.setVersion( iPlugin.getVersion() );
 1125  
                 
 1126  2099
                 dPlugin.setDependencies( iPlugin.getDependencies() );
 1127  
                 
 1128  2099
                 List dExecutions = dPlugin.getExecutions();
 1129  2099
                 if ( dExecutions != null )
 1130  
                 {
 1131  2099
                     List iExecutions = iPlugin.getExecutions();
 1132  
                     
 1133  2109
                     for ( int j = 0; j < dExecutions.size(); j++ )
 1134  
                     {
 1135  10
                         PluginExecution dExec = (PluginExecution) dExecutions.get( j );
 1136  10
                         PluginExecution iExec = (PluginExecution) iExecutions.get( j );
 1137  
                         
 1138  10
                         dExec.setId( iExec.getId() );
 1139  
                     }
 1140  
                 }
 1141  
             }
 1142  
         }
 1143  218
     }
 1144  
 
 1145  
     /**
 1146  
      * @noinspection CollectionDeclaredAsConcreteClass
 1147  
      * @todo We need to find an effective way to unit test parts of this method!
 1148  
      * @todo Refactor this into smaller methods with discrete purposes.
 1149  
      */
 1150  
     private MavenProject assembleLineage( Model model,
 1151  
                                           LinkedList lineage,
 1152  
                                           ProjectBuilderConfiguration config,
 1153  
                                           File projectDescriptor,
 1154  
                                           List parentSearchRepositories,
 1155  
                                           Set aggregatedRemoteWagonRepositories,
 1156  
                                           boolean strict )
 1157  
         throws ProjectBuildingException, InvalidRepositoryException
 1158  
     {
 1159  144
         Model originalModel = ModelUtils.cloneModel( model );
 1160  
 
 1161  144
         File projectDir = null;
 1162  144
         if ( projectDescriptor != null )
 1163  
         {
 1164  103
             projectDir = projectDescriptor.getAbsoluteFile().getParentFile();
 1165  
         }
 1166  
 
 1167  144
         ProfileManager externalProfileManager = config.getGlobalProfileManager();
 1168  
         ProfileManager profileManager;
 1169  144
         if ( externalProfileManager != null )
 1170  
         {
 1171  54
             profileManager = new DefaultProfileManager( container, externalProfileManager.getRequestProperties() );
 1172  
         }
 1173  
         else
 1174  
         {
 1175  
             //TODO mkleint - use the (Container, Properties constructor to make system properties embeddable
 1176  90
             profileManager = new DefaultProfileManager( container );
 1177  
         }
 1178  
 
 1179  144
         if ( externalProfileManager != null )
 1180  
         {
 1181  54
             profileManager.explicitlyActivate( externalProfileManager.getExplicitlyActivatedIds() );
 1182  
 
 1183  54
             profileManager.explicitlyDeactivate( externalProfileManager.getExplicitlyDeactivatedIds() );
 1184  
         }
 1185  
 
 1186  
         List activeProfiles;
 1187  
 
 1188  
         try
 1189  
         {
 1190  144
             profileManager.addProfiles( model.getProfiles() );
 1191  
 
 1192  144
             loadProjectExternalProfiles( profileManager, projectDir );
 1193  
 
 1194  144
             activeProfiles = injectActiveProfiles( profileManager, model );
 1195  
         }
 1196  0
         catch ( ProfileActivationException e )
 1197  
         {
 1198  0
             String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1199  
 
 1200  0
             throw new ProjectBuildingException( projectId, "Failed to activate local (project-level) build profiles: " +
 1201  
                 e.getMessage(), e );
 1202  144
         }
 1203  
 
 1204  144
         if ( !model.getRepositories().isEmpty() )
 1205  
         {
 1206  10
             List respositories = buildArtifactRepositories( model );
 1207  
 
 1208  10
             for ( Iterator it = respositories.iterator(); it.hasNext(); )
 1209  
             {
 1210  10
                 ArtifactRepository repository = (ArtifactRepository) it.next();
 1211  
 
 1212  10
                 if ( !aggregatedRemoteWagonRepositories.contains( repository ) )
 1213  
                 {
 1214  10
                     aggregatedRemoteWagonRepositories.add( repository );
 1215  
                 }
 1216  10
             }
 1217  
         }
 1218  
 
 1219  144
         MavenProject project = new MavenProject( model, getLogger() );
 1220  
 
 1221  144
         project.setFile( projectDescriptor );
 1222  144
         project.setActiveProfiles( activeProfiles );
 1223  144
         project.setOriginalModel( originalModel );
 1224  
 
 1225  144
         lineage.addFirst( project );
 1226  
 
 1227  144
         Parent parentModel = model.getParent();
 1228  
 
 1229  144
         String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1230  
 
 1231  144
         if ( parentModel != null )
 1232  
         {
 1233  47
             if ( StringUtils.isEmpty( parentModel.getGroupId() ) )
 1234  
             {
 1235  0
                 throw new ProjectBuildingException( projectId, "Missing groupId element from parent element" );
 1236  
             }
 1237  47
             else if ( StringUtils.isEmpty( parentModel.getArtifactId() ) )
 1238  
             {
 1239  0
                 throw new ProjectBuildingException( projectId, "Missing artifactId element from parent element" );
 1240  
             }
 1241  47
             else if ( parentModel.getGroupId().equals( model.getGroupId() ) &&
 1242  
                 parentModel.getArtifactId().equals( model.getArtifactId() ) )
 1243  
             {
 1244  0
                 throw new ProjectBuildingException( projectId,
 1245  
                                                     "Parent element is a duplicate of " + "the current project " );
 1246  
             }
 1247  47
             else if ( StringUtils.isEmpty( parentModel.getVersion() ) )
 1248  
             {
 1249  0
                 throw new ProjectBuildingException( projectId, "Missing version element from parent element" );
 1250  
             }
 1251  
 
 1252  
             // the only way this will have a value is if we find the parent on disk...
 1253  47
             File parentDescriptor = null;
 1254  
 
 1255  47
             model = null;
 1256  
 
 1257  47
             String parentKey =
 1258  
                 createCacheKey( parentModel.getGroupId(), parentModel.getArtifactId(), parentModel.getVersion() );
 1259  47
             MavenProject parentProject = (MavenProject) rawProjectCache.get( parentKey );
 1260  
 
 1261  47
             if ( parentProject != null )
 1262  
             {
 1263  41
                 model = ModelUtils.cloneModel( parentProject.getOriginalModel() );
 1264  
 
 1265  41
                 parentDescriptor = parentProject.getFile();
 1266  
             }
 1267  
 
 1268  47
             String parentRelativePath = parentModel.getRelativePath();
 1269  
 
 1270  
             // if we can't find a cached model matching the parent spec, then let's try to look on disk using
 1271  
             // <relativePath/>
 1272  47
             if ( ( model == null ) && ( projectDir != null ) && StringUtils.isNotEmpty( parentRelativePath ) )
 1273  
             {
 1274  3
                 parentDescriptor = new File( projectDir, parentRelativePath );
 1275  
 
 1276  3
                 if ( getLogger().isDebugEnabled() )
 1277  
                 {
 1278  0
                     getLogger().debug( "Searching for parent-POM: " + parentModel.getId() + " of project: " +
 1279  
                         project.getId() + " in relative path: " + parentRelativePath );
 1280  
                 }
 1281  
 
 1282  3
                 if ( parentDescriptor.isDirectory() )
 1283  
                 {
 1284  0
                     if ( getLogger().isDebugEnabled() )
 1285  
                     {
 1286  0
                         getLogger().debug( "Path specified in <relativePath/> (" + parentRelativePath +
 1287  
                             ") is a directory. Searching for 'pom.xml' within this directory." );
 1288  
                     }
 1289  
 
 1290  0
                     parentDescriptor = new File( parentDescriptor, "pom.xml" );
 1291  
 
 1292  0
                     if ( !parentDescriptor.exists() )
 1293  
                     {
 1294  0
                         if ( getLogger().isDebugEnabled() )
 1295  
                         {
 1296  0
                             getLogger().debug( "Parent-POM: " + parentModel.getId() + " for project: " +
 1297  
                                 project.getId() + " cannot be loaded from relative path: " + parentDescriptor +
 1298  
                                 "; path does not exist." );
 1299  
                         }
 1300  
                     }
 1301  
                 }
 1302  
 
 1303  3
                 if ( parentDescriptor != null )
 1304  
                 {
 1305  
                     try
 1306  
                     {
 1307  3
                         parentDescriptor = parentDescriptor.getCanonicalFile();
 1308  
                     }
 1309  0
                     catch ( IOException e )
 1310  
                     {
 1311  0
                         getLogger().debug( "Failed to canonicalize potential parent POM: \'" + parentDescriptor + "\'",
 1312  
                                            e );
 1313  
 
 1314  0
                         parentDescriptor = null;
 1315  3
                     }
 1316  
                 }
 1317  
 
 1318  3
                 if ( ( parentDescriptor != null ) && parentDescriptor.exists() )
 1319  
                 {
 1320  2
                     Model candidateParent = readModel( projectId, parentDescriptor, strict );
 1321  
 
 1322  2
                     String candidateParentGroupId = candidateParent.getGroupId();
 1323  2
                     if ( ( candidateParentGroupId == null ) && ( candidateParent.getParent() != null ) )
 1324  
                     {
 1325  0
                         candidateParentGroupId = candidateParent.getParent().getGroupId();
 1326  
                     }
 1327  
 
 1328  2
                     String candidateParentVersion = candidateParent.getVersion();
 1329  2
                     if ( ( candidateParentVersion == null ) && ( candidateParent.getParent() != null ) )
 1330  
                     {
 1331  0
                         candidateParentVersion = candidateParent.getParent().getVersion();
 1332  
                     }
 1333  
 
 1334  2
                     if ( parentModel.getGroupId().equals( candidateParentGroupId ) &&
 1335  
                         parentModel.getArtifactId().equals( candidateParent.getArtifactId() ) &&
 1336  
                         parentModel.getVersion().equals( candidateParentVersion ) )
 1337  
                     {
 1338  2
                         model = candidateParent;
 1339  
 
 1340  2
                         getLogger().debug( "Using parent-POM from the project hierarchy at: \'" +
 1341  
                             parentModel.getRelativePath() + "\' for project: " + project.getId() );
 1342  
                     }
 1343  
                     else
 1344  
                     {
 1345  0
                         getLogger().debug( "Invalid parent-POM referenced by relative path '" +
 1346  
                             parentModel.getRelativePath() + "' in parent specification in " + project.getId() + ":" +
 1347  
                             "\n  Specified: " + parentModel.getId() + "\n  Found:     " + candidateParent.getId() );
 1348  
                     }
 1349  2
                 }
 1350  1
                 else if ( getLogger().isDebugEnabled() )
 1351  
                 {
 1352  0
                     getLogger().debug(
 1353  
                         "Parent-POM: " + parentModel.getId() + " not found in relative path: " + parentRelativePath );
 1354  
                 }
 1355  
             }
 1356  
 
 1357  47
             Artifact parentArtifact = null;
 1358  
 
 1359  
             // only resolve the parent model from the repository system if we didn't find it on disk...
 1360  47
             if ( model == null )
 1361  
             {
 1362  
                 // MNG-2302: parent's File was being populated incorrectly when parent is loaded from repo.
 1363  
                 // keep this in line with other POMs loaded from the repository...the file should be null.
 1364  4
                 parentDescriptor = null;
 1365  
 
 1366  
                 //!! (**)
 1367  
                 // ----------------------------------------------------------------------
 1368  
                 // Do we have the necessary information to actually find the parent
 1369  
                 // POMs here?? I don't think so ... Say only one remote repository is
 1370  
                 // specified and that is ibiblio then this model that we just read doesn't
 1371  
                 // have any repository information ... I think we might have to inherit
 1372  
                 // as we go in order to do this.
 1373  
                 // ----------------------------------------------------------------------
 1374  
 
 1375  
                 // we must add the repository this POM was found in too, by chance it may be located where the parent is
 1376  
                 // we can't query the parent to ask where it is :)
 1377  4
                 List remoteRepositories = new ArrayList( aggregatedRemoteWagonRepositories );
 1378  4
                 remoteRepositories.addAll( parentSearchRepositories );
 1379  
 
 1380  4
                 if ( getLogger().isDebugEnabled() )
 1381  
                 {
 1382  0
                     getLogger().debug( "Retrieving parent-POM: " + parentModel.getId() + " for project: " +
 1383  
                         project.getId() + " from the repository." );
 1384  
                 }
 1385  
 
 1386  4
                 parentArtifact = artifactFactory.createParentArtifact( parentModel.getGroupId(),
 1387  
                                                                        parentModel.getArtifactId(),
 1388  
                                                                        parentModel.getVersion() );
 1389  
 
 1390  
                 try
 1391  
                 {
 1392  4
                     model = findModelFromRepository( parentArtifact, remoteRepositories, config.getLocalRepository(), false );
 1393  
                 }
 1394  0
                 catch ( ProjectBuildingException e )
 1395  
                 {
 1396  0
                     throw new ProjectBuildingException( project.getId(), "Cannot find parent: " + e.getProjectId() +
 1397  
                         " for project: " + project.getId(), e );
 1398  4
                 }
 1399  
             }
 1400  
 
 1401  47
             if ( ( model != null ) && !"pom".equals( model.getPackaging() ) )
 1402  
             {
 1403  0
                 throw new ProjectBuildingException( projectId, "Parent: " + model.getId() + " of project: " +
 1404  
                     projectId + " has wrong packaging: " + model.getPackaging() + ". Must be 'pom'." );
 1405  
             }
 1406  
 
 1407  47
             MavenProject parent = assembleLineage( model,
 1408  
                                                    lineage,
 1409  
                                                    config,
 1410  
                                                    parentDescriptor,
 1411  
                                                    parentSearchRepositories,
 1412  
                                                    aggregatedRemoteWagonRepositories,
 1413  
                                                    strict );
 1414  
 
 1415  47
             project.setParent( parent );
 1416  
 
 1417  47
             project.setParentArtifact( parentArtifact );
 1418  
         }
 1419  
 
 1420  144
         rawProjectCache.put( createCacheKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ), new MavenProject( project ) );
 1421  
 
 1422  144
         return project;
 1423  
     }
 1424  
 
 1425  
     private void mergeManagedDependencies(Model model, ArtifactRepository localRepository, List parentSearchRepositories)
 1426  
         throws ProjectBuildingException
 1427  
     {
 1428  97
         DependencyManagement modelDepMgmt = model.getDependencyManagement();
 1429  
 
 1430  97
         if (modelDepMgmt != null)
 1431  
         {
 1432  24
             Map depsMap = new TreeMap();
 1433  24
             Iterator iter = modelDepMgmt.getDependencies().iterator();
 1434  24
             boolean doInclude = false;
 1435  92
             while (iter.hasNext())
 1436  
             {
 1437  68
                 Dependency dep = (Dependency) iter.next();
 1438  68
                 depsMap.put( dep.getManagementKey(), dep );
 1439  68
                 if ( dep.getType().equals( "pom" ) && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) )
 1440  
                 {
 1441  3
                     doInclude = true;
 1442  
                 }
 1443  68
             }
 1444  24
             Map newDeps = new TreeMap(depsMap);
 1445  24
             iter = modelDepMgmt.getDependencies().iterator();
 1446  24
             if (doInclude)
 1447  
             {
 1448  9
                 while (iter.hasNext())
 1449  
                 {
 1450  7
                     Dependency dep = (Dependency)iter.next();
 1451  7
                     if ( dep.getType().equals( "pom" )
 1452  
                          && Artifact.SCOPE_IMPORT.equals( dep.getScope() ) )
 1453  
                     {
 1454  3
                         Artifact artifact = artifactFactory.createProjectArtifact( dep.getGroupId(), dep.getArtifactId(),
 1455  
                                                                                   dep.getVersion(), dep.getScope() );
 1456  3
                         MavenProject project = buildFromRepository(artifact, parentSearchRepositories, localRepository, false);
 1457  
 
 1458  3
                         DependencyManagement depMgmt = project.getDependencyManagement();
 1459  
 
 1460  3
                         if (depMgmt != null)
 1461  
                         {
 1462  3
                             if ( getLogger().isDebugEnabled() )
 1463  
                             {
 1464  0
                                 getLogger().debug( "Importing managed dependencies for " + dep.toString() );
 1465  
                             }
 1466  
 
 1467  3
                             for ( Iterator it = depMgmt.getDependencies().iterator(); it.hasNext(); )
 1468  
                             {
 1469  8
                                 Dependency includedDep = (Dependency) it.next();
 1470  8
                                 String key = includedDep.getManagementKey();
 1471  8
                                 if (!newDeps.containsKey(key))
 1472  
                                 {
 1473  3
                                     newDeps.put( includedDep.getManagementKey(), includedDep );
 1474  
                                 }
 1475  8
                             }
 1476  3
                             newDeps.remove(dep.getManagementKey());
 1477  
                         }
 1478  
                     }
 1479  7
                 }
 1480  2
                 List deps = new ArrayList(newDeps.values());
 1481  2
                 modelDepMgmt.setDependencies(deps);
 1482  
             }
 1483  
         }
 1484  97
     }
 1485  
 
 1486  
     private List injectActiveProfiles( ProfileManager profileManager,
 1487  
                                        Model model )
 1488  
         throws ProjectBuildingException
 1489  
     {
 1490  
         List activeProfiles;
 1491  
 
 1492  362
         if ( profileManager != null )
 1493  
         {
 1494  
             try
 1495  
             {
 1496  277
                 activeProfiles = profileManager.getActiveProfiles();
 1497  
             }
 1498  0
             catch ( ProfileActivationException e )
 1499  
             {
 1500  0
                 String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
 1501  
 
 1502  0
                 throw new ProjectBuildingException( projectId, e.getMessage(), e );
 1503  277
             }
 1504  
 
 1505  277
             for ( Iterator it = activeProfiles.iterator(); it.hasNext(); )
 1506  
             {
 1507  4
                 Profile profile = (Profile) it.next();
 1508  
 
 1509  4
                 profileInjector.inject( profile, model );
 1510  4
             }
 1511  
         }
 1512  
         else
 1513  
         {
 1514  85
             activeProfiles = Collections.EMPTY_LIST;
 1515  
         }
 1516  
 
 1517  362
         return activeProfiles;
 1518  
     }
 1519  
 
 1520  
     private void loadProjectExternalProfiles( ProfileManager profileManager,
 1521  
                                               File projectDir )
 1522  
         throws ProfileActivationException
 1523  
     {
 1524  144
         if ( projectDir != null )
 1525  
         {
 1526  
             try
 1527  
             {
 1528  103
                 ProfilesRoot root = profilesBuilder.buildProfiles( projectDir );
 1529  
 
 1530  103
                 if ( root != null )
 1531  
                 {
 1532  0
                     List active = root.getActiveProfiles();
 1533  
 
 1534  0
                     if ( ( active != null ) && !active.isEmpty() )
 1535  
                     {
 1536  0
                         profileManager.explicitlyActivate( root.getActiveProfiles() );
 1537  
                     }
 1538  
 
 1539  0
                     for ( Iterator it = root.getProfiles().iterator(); it.hasNext(); )
 1540  
                     {
 1541  0
                         org.apache.maven.profiles.Profile rawProfile = (org.apache.maven.profiles.Profile) it.next();
 1542  
 
 1543  0
                         Profile converted = ProfilesConversionUtils.convertFromProfileXmlProfile( rawProfile );
 1544  
 
 1545  0
                         profileManager.addProfile( converted );
 1546  0
                     }
 1547  
                 }
 1548  
             }
 1549  0
             catch ( IOException e )
 1550  
             {
 1551  0
                 throw new ProfileActivationException( "Cannot read profiles.xml resource from directory: " + projectDir,
 1552  
                                                       e );
 1553  
             }
 1554  0
             catch ( XmlPullParserException e )
 1555  
             {
 1556  0
                 throw new ProfileActivationException(
 1557  
                     "Cannot parse profiles.xml resource from directory: " + projectDir, e );
 1558  103
             }
 1559  
         }
 1560  144
     }
 1561  
 
 1562  
     private Model readModel( String projectId,
 1563  
                              File file,
 1564  
                              boolean strict )
 1565  
         throws ProjectBuildingException
 1566  
     {
 1567  103
         Reader reader = null;
 1568  
         try
 1569  
         {
 1570  103
             reader = ReaderFactory.newXmlReader( file );
 1571  103
             return readModel( projectId, file.getAbsolutePath(), reader, strict );
 1572  
         }
 1573  0
         catch ( FileNotFoundException e )
 1574  
         {
 1575  0
             throw new ProjectBuildingException( projectId,
 1576  
                                                 "Could not find the model file '" + file.getAbsolutePath() + "'.", e );
 1577  
         }
 1578  0
         catch ( IOException e )
 1579  
         {
 1580  0
             throw new ProjectBuildingException( projectId, "Failed to build model from file '" +
 1581  
                 file.getAbsolutePath() + "'.\nError: \'" + e.getLocalizedMessage() + "\'", e );
 1582  
         }
 1583  
         finally
 1584  
         {
 1585  103
             IOUtil.close( reader );
 1586  
         }
 1587  
     }
 1588  
 
 1589  
     private Model readModel( String projectId,
 1590  
                              String pomLocation,
 1591  
                              Reader reader,
 1592  
                              boolean strict )
 1593  
         throws IOException, InvalidProjectModelException
 1594  
     {
 1595  272
         String modelSource = IOUtil.toString( reader );
 1596  
 
 1597  272
         if ( modelSource.indexOf( "<modelVersion>" + MAVEN_MODEL_VERSION ) < 0 )
 1598  
         {
 1599  0
             throw new InvalidProjectModelException( projectId, pomLocation, "Not a v" + MAVEN_MODEL_VERSION  + " POM." );
 1600  
         }
 1601  
 
 1602  272
         StringReader sReader = new StringReader( modelSource );
 1603  
 
 1604  
         try
 1605  
         {
 1606  272
             return modelReader.read( sReader, strict );
 1607  
         }
 1608  0
         catch ( XmlPullParserException e )
 1609  
         {
 1610  0
             throw new InvalidProjectModelException( projectId, pomLocation,
 1611  
                                                     "Parse error reading POM. Reason: " + e.getMessage(), e );
 1612  
         }
 1613  
     }
 1614  
 
 1615  
     private Model readModel( String projectId,
 1616  
                              URL url,
 1617  
                              boolean strict )
 1618  
         throws ProjectBuildingException
 1619  
     {
 1620  169
         Reader reader = null;
 1621  
         try
 1622  
         {
 1623  169
             reader = ReaderFactory.newXmlReader( url.openStream() );
 1624  169
             return readModel( projectId, url.toExternalForm(), reader, strict );
 1625  
         }
 1626  0
         catch ( IOException e )
 1627  
         {
 1628  0
             throw new ProjectBuildingException( projectId, "Failed build model from URL \'" + url.toExternalForm() +
 1629  
                 "\'\nError: \'" + e.getLocalizedMessage() + "\'", e );
 1630  
         }
 1631  
         finally
 1632  
         {
 1633  169
             IOUtil.close( reader );
 1634  
         }
 1635  
     }
 1636  
 
 1637  
     private static String createCacheKey( String groupId,
 1638  
                                           String artifactId,
 1639  
                                           String version )
 1640  
     {
 1641  415
         return groupId + ":" + artifactId + ":" + version;
 1642  
     }
 1643  
 
 1644  
     protected Set createPluginArtifacts( String projectId,
 1645  
                                          List plugins )
 1646  
         throws ProjectBuildingException
 1647  
     {
 1648  109
         Set pluginArtifacts = new LinkedHashSet();
 1649  
 
 1650  109
         for ( Iterator i = plugins.iterator(); i.hasNext(); )
 1651  
         {
 1652  28
             Plugin p = (Plugin) i.next();
 1653  
 
 1654  
             String version;
 1655  28
             if ( StringUtils.isEmpty( p.getVersion() ) )
 1656  
             {
 1657  1
                 version = "RELEASE";
 1658  
             }
 1659  
             else
 1660  
             {
 1661  27
                 version = p.getVersion();
 1662  
             }
 1663  
 
 1664  
             Artifact artifact;
 1665  
             try
 1666  
             {
 1667  28
                 artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(),
 1668  
                                                                  VersionRange.createFromVersionSpec( version ) );
 1669  
             }
 1670  0
             catch ( InvalidVersionSpecificationException e )
 1671  
             {
 1672  0
                 throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
 1673  
                     "' for plugin '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " +
 1674  
                     e.getMessage(), e );
 1675  28
             }
 1676  
 
 1677  28
             if ( artifact != null )
 1678  
             {
 1679  28
                 pluginArtifacts.add( artifact );
 1680  
             }
 1681  28
         }
 1682  
 
 1683  109
         return pluginArtifacts;
 1684  
     }
 1685  
 
 1686  
     // TODO: share with createPluginArtifacts?
 1687  
     protected Set createReportArtifacts( String projectId,
 1688  
                                          List reports )
 1689  
         throws ProjectBuildingException
 1690  
     {
 1691  109
         Set pluginArtifacts = new LinkedHashSet();
 1692  
 
 1693  109
         if ( reports != null )
 1694  
         {
 1695  109
             for ( Iterator i = reports.iterator(); i.hasNext(); )
 1696  
             {
 1697  0
                 ReportPlugin p = (ReportPlugin) i.next();
 1698  
 
 1699  
                 String version;
 1700  0
                 if ( StringUtils.isEmpty( p.getVersion() ) )
 1701  
                 {
 1702  0
                     version = "RELEASE";
 1703  
                 }
 1704  
                 else
 1705  
                 {
 1706  0
                     version = p.getVersion();
 1707  
                 }
 1708  
 
 1709  
                 Artifact artifact;
 1710  
                 try
 1711  
                 {
 1712  0
                     artifact = artifactFactory.createPluginArtifact( p.getGroupId(), p.getArtifactId(),
 1713  
                                                                      VersionRange.createFromVersionSpec( version ) );
 1714  
                 }
 1715  0
                 catch ( InvalidVersionSpecificationException e )
 1716  
                 {
 1717  0
                     throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
 1718  
                         "' for report '" + ArtifactUtils.versionlessKey( p.getGroupId(), p.getArtifactId() ) + "': " +
 1719  
                         e.getMessage(), e );
 1720  0
                 }
 1721  
 
 1722  0
                 if ( artifact != null )
 1723  
                 {
 1724  0
                     pluginArtifacts.add( artifact );
 1725  
                 }
 1726  0
             }
 1727  
         }
 1728  
 
 1729  109
         return pluginArtifacts;
 1730  
     }
 1731  
 
 1732  
     // TODO: share with createPluginArtifacts?
 1733  
     protected Set createExtensionArtifacts( String projectId,
 1734  
                                             List extensions )
 1735  
         throws ProjectBuildingException
 1736  
     {
 1737  109
         Set extensionArtifacts = new LinkedHashSet();
 1738  
 
 1739  109
         if ( extensions != null )
 1740  
         {
 1741  109
             for ( Iterator i = extensions.iterator(); i.hasNext(); )
 1742  
             {
 1743  0
                 Extension ext = (Extension) i.next();
 1744  
 
 1745  
                 String version;
 1746  0
                 if ( StringUtils.isEmpty( ext.getVersion() ) )
 1747  
                 {
 1748  0
                     version = "RELEASE";
 1749  
                 }
 1750  
                 else
 1751  
                 {
 1752  0
                     version = ext.getVersion();
 1753  
                 }
 1754  
 
 1755  
                 Artifact artifact;
 1756  
                 try
 1757  
                 {
 1758  0
                     VersionRange versionRange = VersionRange.createFromVersionSpec( version );
 1759  0
                     artifact =
 1760  
                         artifactFactory.createExtensionArtifact( ext.getGroupId(), ext.getArtifactId(), versionRange );
 1761  
                 }
 1762  0
                 catch ( InvalidVersionSpecificationException e )
 1763  
                 {
 1764  0
                     throw new ProjectBuildingException( projectId, "Unable to parse version '" + version +
 1765  
                         "' for extension '" + ArtifactUtils.versionlessKey( ext.getGroupId(), ext.getArtifactId() ) +
 1766  
                         "': " + e.getMessage(), e );
 1767  0
                 }
 1768  
 
 1769  0
                 if ( artifact != null )
 1770  
                 {
 1771  0
                     extensionArtifacts.add( artifact );
 1772  
                 }
 1773  0
             }
 1774  
         }
 1775  
 
 1776  109
         return extensionArtifacts;
 1777  
     }
 1778  
 
 1779  
     // ----------------------------------------------------------------------
 1780  
     //
 1781  
     // ----------------------------------------------------------------------
 1782  
 
 1783  
     private Model getSuperModel()
 1784  
         throws ProjectBuildingException
 1785  
     {
 1786  169
         URL url = DefaultMavenProjectBuilder.class.getResource( "pom-" + MAVEN_MODEL_VERSION + ".xml" );
 1787  
 
 1788  169
         String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID );
 1789  
 
 1790  169
         return readModel( projectId, url, true );
 1791  
     }
 1792  
 
 1793  
     public void contextualize( Context context )
 1794  
         throws ContextException
 1795  
     {
 1796  58
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 1797  58
     }
 1798  
 
 1799  
     /**
 1800  
      * {@inheritDoc}
 1801  
      */
 1802  
     public void calculateConcreteState( MavenProject project, ProjectBuilderConfiguration config )
 1803  
         throws ModelInterpolationException
 1804  
     {
 1805  15
         calculateConcreteStateInternal( project, config, true, new HashSet() );
 1806  15
     }
 1807  
     
 1808  
     /**
 1809  
      * {@inheritDoc}
 1810  
      */
 1811  
     public void calculateConcreteState( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences )
 1812  
         throws ModelInterpolationException
 1813  
     {
 1814  0
         calculateConcreteStateInternal( project, config, processProjectReferences, ( processProjectReferences ? new HashSet() : null ) );
 1815  0
     }
 1816  
     
 1817  
     /*
 1818  
      * NOTE: This is a code hotspot, PLEASE be careful about the performance of logic inside or
 1819  
      * called from this method. 
 1820  
      * 
 1821  
      * NOTE: If processProjectReferences == false, processedProjects MUST NOT BE USED. It will be null.
 1822  
      */
 1823  
     private void calculateConcreteStateInternal( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences, Set processedProjects )
 1824  
         throws ModelInterpolationException
 1825  
     {
 1826  15
         if ( processProjectReferences )
 1827  
         {
 1828  15
             processedProjects.add( project.getId() );
 1829  
         }
 1830  
         
 1831  15
         restoreDynamicStateInternal( project, config, processProjectReferences, processProjectReferences ? new HashSet( processedProjects ) : null );
 1832  
         
 1833  15
         if ( !project.isConcrete() )
 1834  
         {
 1835  15
             if ( project.getParent() != null )
 1836  
             {
 1837  0
                 calculateConcreteStateInternal( project.getParent(), config, processProjectReferences, processedProjects );
 1838  
             }
 1839  
             
 1840  15
             Build build = project.getBuild();
 1841  15
             if ( build != null )
 1842  
             {
 1843  15
                 initResourceMergeIds( build.getResources() );
 1844  15
                 initResourceMergeIds( build.getTestResources() );
 1845  
             }
 1846  
 
 1847  
             // NOTE: Since interpolation makes a copy through serialization, we don't need this.
 1848  
             // See note below.
 1849  
             //
 1850  
             // Model model = ModelUtils.cloneModel( project.getModel() );
 1851  
 
 1852  15
             File basedir = project.getBasedir();
 1853  
 
 1854  
             // NOTE: If we ever get past serialization/deserialization for interpolation, we'll need to copy the model here!
 1855  15
             Model model = ModelUtils.cloneModel( project.getModel() );
 1856  15
             model = modelInterpolator.interpolate( model, project.getBasedir(), config, getLogger().isDebugEnabled() );
 1857  
 
 1858  15
             List originalInterpolatedCompileSourceRoots = interpolateListOfStrings( project.getCompileSourceRoots(),
 1859  
                                                                                model,
 1860  
                                                                                project.getBasedir(),
 1861  
                                                                                config,
 1862  
                                                                                getLogger().isDebugEnabled() );
 1863  
 
 1864  15
             project.preserveCompileSourceRoots( originalInterpolatedCompileSourceRoots );
 1865  
 
 1866  15
             project.setCompileSourceRoots( originalInterpolatedCompileSourceRoots == null ? null
 1867  
                             : translateListOfPaths( originalInterpolatedCompileSourceRoots, basedir ) );
 1868  
 
 1869  15
             List originalInterpolatedTestCompileSourceRoots = interpolateListOfStrings( project.getTestCompileSourceRoots(),
 1870  
                                                                                    model,
 1871  
                                                                                    project.getBasedir(),
 1872  
                                                                                    config,
 1873  
                                                                                    getLogger().isDebugEnabled() );
 1874  
 
 1875  15
             project.preserveTestCompileSourceRoots( originalInterpolatedTestCompileSourceRoots );
 1876  15
             project.setTestCompileSourceRoots( originalInterpolatedTestCompileSourceRoots == null ? null
 1877  
                             : translateListOfPaths( originalInterpolatedTestCompileSourceRoots, basedir ) );
 1878  
 
 1879  15
             List originalInterpolatedScriptSourceRoots = interpolateListOfStrings( project.getScriptSourceRoots(),
 1880  
                                                                               model,
 1881  
                                                                               project.getBasedir(),
 1882  
                                                                               config,
 1883  
                                                                               getLogger().isDebugEnabled() );
 1884  
 
 1885  15
             project.preserveScriptSourceRoots( originalInterpolatedScriptSourceRoots );
 1886  
             
 1887  
             // TODO: MNG-3731
 1888  15
             project.setScriptSourceRoots( originalInterpolatedScriptSourceRoots );
 1889  
 //            project.setScriptSourceRoots( originalInterpolatedScriptSourceRoots == null ? null
 1890  
 //                            : translateListOfPaths( originalInterpolatedScriptSourceRoots, basedir ) );
 1891  
 
 1892  15
             if ( basedir != null )
 1893  
             {
 1894  15
                 pathTranslator.alignToBaseDirectory( model, basedir );
 1895  
             }
 1896  
 
 1897  15
             project.preserveBuild( ModelUtils.cloneBuild( model.getBuild() ) );
 1898  15
             project.preserveProperties();
 1899  15
             project.preserveBasedir();
 1900  15
             project.setBuild( model.getBuild() );
 1901  
             
 1902  15
             if ( project.getExecutionProject() != null )
 1903  
             {
 1904  0
                 calculateConcreteStateInternal( project.getExecutionProject(), config, processProjectReferences, processedProjects );
 1905  
             }
 1906  
             
 1907  15
             project.setConcrete( true );
 1908  
         }
 1909  
 
 1910  15
         if ( processProjectReferences )
 1911  
         {
 1912  15
             calculateConcreteProjectReferences( project, config, processedProjects );
 1913  
         }
 1914  15
     }
 1915  
 
 1916  
     private void initResourceMergeIds( List resources )
 1917  
     {
 1918  30
         if ( resources != null )
 1919  
         {
 1920  30
             for ( Iterator it = resources.iterator(); it.hasNext(); )
 1921  
             {
 1922  31
                 Resource resource = (Resource) it.next();
 1923  
 
 1924  31
                 resource.initMergeId();
 1925  31
             }
 1926  
         }
 1927  30
     }
 1928  
 
 1929  
     private void calculateConcreteProjectReferences( MavenProject project,
 1930  
                                                      ProjectBuilderConfiguration config,
 1931  
                                                      Set processedProjects )
 1932  
         throws ModelInterpolationException
 1933  
     {
 1934  15
         Map projectRefs = project.getProjectReferences();
 1935  
 
 1936  15
         if ( projectRefs != null )
 1937  
         {
 1938  15
             for ( Iterator it = projectRefs.values().iterator(); it.hasNext(); )
 1939  
             {
 1940  0
                 MavenProject reference = (MavenProject) it.next();
 1941  0
                 if ( !processedProjects.contains( reference.getId() ) )
 1942  
                 {
 1943  0
                     calculateConcreteStateInternal( reference, config, true, processedProjects );
 1944  
                 }
 1945  0
             }
 1946  
         }
 1947  15
     }
 1948  
 
 1949  
     private List translateListOfPaths( List paths, File basedir )
 1950  
     {
 1951  30
         if ( paths == null )
 1952  
         {
 1953  0
             return null;
 1954  
         }
 1955  30
         else if ( basedir == null )
 1956  
         {
 1957  0
             return paths;
 1958  
         }
 1959  
 
 1960  30
         List result = new ArrayList( paths.size() );
 1961  30
         for ( Iterator it = paths.iterator(); it.hasNext(); )
 1962  
         {
 1963  33
             String path = (String) it.next();
 1964  
 
 1965  33
             String aligned = pathTranslator.alignToBaseDirectory( path, basedir );
 1966  
 
 1967  33
             result.add( aligned );
 1968  33
         }
 1969  
 
 1970  30
         return result;
 1971  
     }
 1972  
 
 1973  
     /**
 1974  
      * {@inheritDoc}
 1975  
      */
 1976  
     public void restoreDynamicState( MavenProject project, ProjectBuilderConfiguration config )
 1977  
         throws ModelInterpolationException
 1978  
     {
 1979  9
         restoreDynamicStateInternal( project, config, true, new HashSet() );
 1980  9
     }
 1981  
     
 1982  
     /**
 1983  
      * {@inheritDoc}
 1984  
      */
 1985  
     public void restoreDynamicState( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences )
 1986  
         throws ModelInterpolationException
 1987  
     {
 1988  0
         restoreDynamicStateInternal( project, config, processProjectReferences, ( processProjectReferences ? new HashSet() : null ) );
 1989  0
     }
 1990  
     
 1991  
     /*
 1992  
      * NOTE: This is a code hotspot, PLEASE be careful about the performance of logic inside or
 1993  
      * called from this method. 
 1994  
      * 
 1995  
      * NOTE: If processProjectReferences == false, processedProjects MUST NOT BE USED. It will be null.
 1996  
      */
 1997  
     private void restoreDynamicStateInternal( MavenProject project, ProjectBuilderConfiguration config, boolean processProjectReferences, Set processedProjects )
 1998  
         throws ModelInterpolationException
 1999  
     {
 2000  24
         if ( processProjectReferences )
 2001  
         {
 2002  24
             processedProjects.add( project.getId() );
 2003  
         }
 2004  
         
 2005  24
         if ( project.isConcrete() && projectWasChanged( project ) )
 2006  
         {
 2007  8
             if ( project.getParent() != null )
 2008  
             {
 2009  0
                 restoreDynamicStateInternal( project.getParent(), config, processProjectReferences, processedProjects );
 2010  
             }
 2011  
             
 2012  8
             restoreBuildRoots( project, config, getLogger().isDebugEnabled() );
 2013  8
             restoreModelBuildSection( project, config, getLogger().isDebugEnabled() );
 2014  
             
 2015  8
             if ( project.getExecutionProject() != null )
 2016  
             {
 2017  0
                 restoreDynamicStateInternal( project.getExecutionProject(), config, processProjectReferences, processedProjects );
 2018  
             }
 2019  
             
 2020  8
             project.setConcrete( false );
 2021  
         }
 2022  
 
 2023  24
         if ( processProjectReferences )
 2024  
         {
 2025  24
             restoreDynamicProjectReferences( project, config, processedProjects );
 2026  
         }
 2027  24
     }
 2028  
 
 2029  
     private boolean projectWasChanged( MavenProject project )
 2030  
     {
 2031  9
         if ( !objectEquals( project.getBasedir(), project.getPreservedBasedir() ) )
 2032  
         {
 2033  0
             return true;
 2034  
         }
 2035  
         
 2036  9
         if ( !objectEquals( project.getProperties(), project.getPreservedProperties() ) )
 2037  
         {
 2038  6
             return true;
 2039  
         }
 2040  
         
 2041  3
         Build oBuild = project.getOriginalInterpolatedBuild();
 2042  3
         Build build = project.getBuild();
 2043  
         
 2044  3
         if ( !objectEquals( oBuild.getDirectory(), build.getDirectory() ) )
 2045  
         {
 2046  2
             return true;
 2047  
         }
 2048  
         
 2049  1
         if ( !objectEquals( oBuild.getOutputDirectory(), build.getOutputDirectory() ) )
 2050  
         {
 2051  0
             return true;
 2052  
         }
 2053  
         
 2054  1
         if ( !objectEquals( oBuild.getSourceDirectory(), build.getSourceDirectory() ) )
 2055  
         {
 2056  0
             return true;
 2057  
         }
 2058  
         
 2059  1
         if ( !objectEquals( oBuild.getTestSourceDirectory(), build.getTestSourceDirectory() ) )
 2060  
         {
 2061  0
             return true;
 2062  
         }
 2063  
         
 2064  1
         if ( !objectEquals( oBuild.getScriptSourceDirectory(), build.getScriptSourceDirectory() ) )
 2065  
         {
 2066  0
             return true;
 2067  
         }
 2068  
         
 2069  1
         return false;
 2070  
     }
 2071  
 
 2072  
     private boolean objectEquals( Object obj1, Object obj2 )
 2073  
     {
 2074  25
         return obj1 == null ? obj2 == null : obj2 != null && ( obj1 == obj2 || obj1.equals( obj2 ) );
 2075  
     }
 2076  
 
 2077  
     private void propagateNewPlugins( MavenProject project )
 2078  
     {
 2079  8
         Build changedBuild = project.getBuild();
 2080  8
         Build dynamicBuild = project.getDynamicBuild();
 2081  
         
 2082  8
         if ( changedBuild == null || dynamicBuild == null )
 2083  
         {
 2084  0
             return;
 2085  
         }
 2086  
         
 2087  8
         List changedPlugins = changedBuild.getPlugins();
 2088  8
         List dynamicPlugins = dynamicBuild.getPlugins();
 2089  
         
 2090  8
         if ( changedPlugins != null && dynamicPlugins != null && changedPlugins.size() != dynamicPlugins.size() )
 2091  
         {
 2092  0
             changedPlugins.removeAll( dynamicPlugins );
 2093  0
             if ( !changedPlugins.isEmpty() )
 2094  
             {
 2095  0
                 for ( Iterator it = changedPlugins.iterator(); it.hasNext(); )
 2096  
                 {
 2097  0
                     Plugin plugin = (Plugin) it.next();
 2098  
                     
 2099  0
                     dynamicBuild.addPlugin( plugin );
 2100  0
                 }
 2101  
             }
 2102  
         }
 2103  
         
 2104  8
         dynamicBuild.flushPluginMap();
 2105  8
     }
 2106  
 
 2107  
     private void restoreDynamicProjectReferences( MavenProject project,
 2108  
                                                   ProjectBuilderConfiguration config,
 2109  
                                                   Set processedProjects )
 2110  
         throws ModelInterpolationException
 2111  
     {
 2112  24
         Map projectRefs = project.getProjectReferences();
 2113  24
         if ( projectRefs != null )
 2114  
         {
 2115  24
             for ( Iterator it = projectRefs.values().iterator(); it.hasNext(); )
 2116  
             {
 2117  0
                 MavenProject projectRef = (MavenProject) it.next();
 2118  0
                 if ( !processedProjects.contains( projectRef.getId() ) )
 2119  
                 {
 2120  0
                     restoreDynamicStateInternal( projectRef, config, true, processedProjects );
 2121  
                 }
 2122  0
             }
 2123  
         }
 2124  24
     }
 2125  
 
 2126  
     private void restoreBuildRoots( MavenProject project,
 2127  
                                     ProjectBuilderConfiguration config,
 2128  
                                     boolean debugMessages )
 2129  
         throws ModelInterpolationException
 2130  
     {
 2131  8
         project.setCompileSourceRoots( restoreListOfStrings( project.getDynamicCompileSourceRoots(),
 2132  
                                                              project.getOriginalInterpolatedCompileSourceRoots(),
 2133  
                                                              project.getCompileSourceRoots(),
 2134  
                                                              project,
 2135  
                                                              config,
 2136  
                                                              debugMessages ) );
 2137  
 
 2138  8
         project.setTestCompileSourceRoots( restoreListOfStrings( project.getDynamicTestCompileSourceRoots(),
 2139  
                                                                  project.getOriginalInterpolatedTestCompileSourceRoots(),
 2140  
                                                                  project.getTestCompileSourceRoots(),
 2141  
                                                                  project,
 2142  
                                                                  config,
 2143  
                                                                  debugMessages ) );
 2144  
 
 2145  8
         project.setScriptSourceRoots( restoreListOfStrings( project.getDynamicScriptSourceRoots(),
 2146  
                                                             project.getOriginalInterpolatedScriptSourceRoots(),
 2147  
                                                             project.getScriptSourceRoots(),
 2148  
                                                             project,
 2149  
                                                             config,
 2150  
                                                             debugMessages ) );
 2151  
 
 2152  8
         project.clearRestorableRoots();
 2153  8
     }
 2154  
 
 2155  
     private void restoreModelBuildSection( MavenProject project,
 2156  
                                            ProjectBuilderConfiguration config,
 2157  
                                            boolean debugMessages )
 2158  
         throws ModelInterpolationException
 2159  
     {
 2160  8
         Build changedBuild = project.getBuild();
 2161  8
         Build dynamicBuild = project.getDynamicBuild();
 2162  8
         Build originalInterpolatedBuild = project.getOriginalInterpolatedBuild();
 2163  
 
 2164  8
         dynamicBuild.setResources( restoreResources( dynamicBuild.getResources(),
 2165  
                                                          originalInterpolatedBuild.getResources(),
 2166  
                                                          changedBuild.getResources(),
 2167  
                                                          project,
 2168  
                                                          config,
 2169  
                                                          debugMessages ) );
 2170  
 
 2171  8
         dynamicBuild.setTestResources( restoreResources( dynamicBuild.getTestResources(),
 2172  
                                                          originalInterpolatedBuild.getTestResources(),
 2173  
                                                          changedBuild.getTestResources(),
 2174  
                                                          project,
 2175  
                                                          config,
 2176  
                                                          debugMessages ) );
 2177  
 
 2178  8
         dynamicBuild.setFilters( restoreListOfStrings( dynamicBuild.getFilters(),
 2179  
                                                            originalInterpolatedBuild.getFilters(),
 2180  
                                                            changedBuild.getFilters(),
 2181  
                                                            project,
 2182  
                                                            config,
 2183  
                                                            debugMessages ) );
 2184  
 
 2185  8
         dynamicBuild.setFinalName( restoreString( dynamicBuild.getFinalName(),
 2186  
                                                   originalInterpolatedBuild.getFinalName(),
 2187  
                                                   changedBuild.getFinalName(),
 2188  
                                                   project,
 2189  
                                                   config,
 2190  
                                                   debugMessages ) );
 2191  
 
 2192  8
         dynamicBuild.setDefaultGoal( restoreString( dynamicBuild.getDefaultGoal(),
 2193  
                                                   originalInterpolatedBuild.getDefaultGoal(),
 2194  
                                                   changedBuild.getDefaultGoal(),
 2195  
                                                   project,
 2196  
                                                   config,
 2197  
                                                   debugMessages ) );
 2198  
 
 2199  8
         dynamicBuild.setSourceDirectory( restoreString( dynamicBuild.getSourceDirectory(),
 2200  
                                                             originalInterpolatedBuild.getSourceDirectory(),
 2201  
                                                             changedBuild.getSourceDirectory(),
 2202  
                                                             project,
 2203  
                                                             config,
 2204  
                                                             debugMessages ) );
 2205  
 
 2206  8
         dynamicBuild.setTestSourceDirectory( restoreString( dynamicBuild.getTestSourceDirectory(),
 2207  
                                                                 originalInterpolatedBuild.getTestSourceDirectory(),
 2208  
                                                                 changedBuild.getTestSourceDirectory(),
 2209  
                                                                 project,
 2210  
                                                                 config,
 2211  
                                                                 debugMessages ) );
 2212  
 
 2213  8
         dynamicBuild.setScriptSourceDirectory( restoreString( dynamicBuild.getScriptSourceDirectory(),
 2214  
                                                                   originalInterpolatedBuild.getScriptSourceDirectory(),
 2215  
                                                                   changedBuild.getScriptSourceDirectory(),
 2216  
                                                                   project,
 2217  
                                                                   config,
 2218  
                                                                   debugMessages ) );
 2219  
 
 2220  8
         dynamicBuild.setOutputDirectory( restoreString( dynamicBuild.getOutputDirectory(),
 2221  
                                                             originalInterpolatedBuild.getOutputDirectory(),
 2222  
                                                             changedBuild.getOutputDirectory(),
 2223  
                                                             project,
 2224  
                                                             config,
 2225  
                                                             debugMessages ) );
 2226  
 
 2227  8
         dynamicBuild.setTestOutputDirectory( restoreString( dynamicBuild.getTestOutputDirectory(),
 2228  
                                                                 originalInterpolatedBuild.getTestOutputDirectory(),
 2229  
                                                                 changedBuild.getTestOutputDirectory(),
 2230  
                                                                 project,
 2231  
                                                                 config,
 2232  
                                                                 debugMessages ) );
 2233  
 
 2234  8
         dynamicBuild.setDirectory( restoreString( dynamicBuild.getDirectory(),
 2235  
                                                       originalInterpolatedBuild.getDirectory(),
 2236  
                                                       changedBuild.getDirectory(),
 2237  
                                                       project,
 2238  
                                                       config,
 2239  
                                                       debugMessages ) );
 2240  
 
 2241  8
         propagateNewPlugins( project );
 2242  
         
 2243  8
         project.setBuild( dynamicBuild );
 2244  
 
 2245  8
         project.clearRestorableBuild();
 2246  8
     }
 2247  
 
 2248  
     private List interpolateListOfStrings( List originalStrings,
 2249  
                                            Model model,
 2250  
                                            File projectDir,
 2251  
                                            ProjectBuilderConfiguration config,
 2252  
                                            boolean debugMessages )
 2253  
         throws ModelInterpolationException
 2254  
     {
 2255  45
         if ( originalStrings == null )
 2256  
         {
 2257  0
             return null;
 2258  
         }
 2259  
 
 2260  45
         List result = new ArrayList();
 2261  
 
 2262  45
         for ( Iterator it = originalStrings.iterator(); it.hasNext(); )
 2263  
         {
 2264  49
             String original = (String) it.next();
 2265  49
             String interpolated = modelInterpolator.interpolate( original, model, projectDir, config, debugMessages );
 2266  
 
 2267  49
             result.add( interpolated );
 2268  49
         }
 2269  
 
 2270  45
         return result;
 2271  
     }
 2272  
 
 2273  
     private String restoreString( String originalString,
 2274  
                                       String originalInterpolatedString,
 2275  
                                       String changedString,
 2276  
                                       MavenProject project,
 2277  
                                       ProjectBuilderConfiguration config,
 2278  
                                       boolean debugMessages )
 2279  
         throws ModelInterpolationException
 2280  
     {
 2281  64
         if ( originalString == null )
 2282  
         {
 2283  8
             return changedString;
 2284  
         }
 2285  56
         else if ( changedString == null )
 2286  
         {
 2287  0
             return originalString;
 2288  
         }
 2289  
 
 2290  56
         Model model = project.getModel();
 2291  
 
 2292  
         String relativeChangedString;
 2293  56
         if ( project.getBasedir() != null )
 2294  
         {
 2295  56
             relativeChangedString = pathTranslator.unalignFromBaseDirectory( changedString, project.getBasedir() );
 2296  
         }
 2297  
         else
 2298  
         {
 2299  0
             relativeChangedString = changedString;
 2300  
         }
 2301  
 
 2302  56
         String interpolatedOriginal = modelInterpolator.interpolate( originalString,
 2303  
                                                                      model,
 2304  
                                                                      project.getBasedir(),
 2305  
                                                                      config,
 2306  
                                                                      debugMessages );
 2307  
         
 2308  56
         interpolatedOriginal = pathTranslator.unalignFromBaseDirectory( interpolatedOriginal, project.getBasedir() );
 2309  
 
 2310  56
         String interpolatedOriginal2 = modelInterpolator.interpolate( originalInterpolatedString,
 2311  
                                                                       model,
 2312  
                                                                       project.getBasedir(),
 2313  
                                                                       config,
 2314  
                                                                       debugMessages );
 2315  
         
 2316  56
         interpolatedOriginal2 = pathTranslator.alignToBaseDirectory( interpolatedOriginal2, project.getBasedir() );
 2317  
 
 2318  56
         String interpolatedChanged = modelInterpolator.interpolate( changedString,
 2319  
                                                                     model,
 2320  
                                                                     project.getBasedir(),
 2321  
                                                                     config,
 2322  
                                                                     debugMessages );
 2323  
         
 2324  56
         interpolatedChanged = pathTranslator.alignToBaseDirectory( interpolatedChanged, project.getBasedir() );
 2325  
 
 2326  56
         String relativeInterpolatedChanged = modelInterpolator.interpolate( relativeChangedString,
 2327  
                                                                             model,
 2328  
                                                                             project.getBasedir(),
 2329  
                                                                             config,
 2330  
                                                                             debugMessages );
 2331  
 
 2332  56
         if ( interpolatedOriginal.equals( interpolatedChanged ) || interpolatedOriginal2.equals( interpolatedChanged ) )
 2333  
         {
 2334  54
             return originalString;
 2335  
         }
 2336  2
         else if ( interpolatedOriginal.equals( relativeInterpolatedChanged )
 2337  
             || interpolatedOriginal2.equals( relativeInterpolatedChanged ) )
 2338  
         {
 2339  0
             return originalString;
 2340  
         }
 2341  
 
 2342  2
         return relativeChangedString;
 2343  
     }
 2344  
 
 2345  
     private List restoreListOfStrings( List originalStrings,
 2346  
                                            List originalInterpolatedStrings,
 2347  
                                            List changedStrings,
 2348  
                                            MavenProject project,
 2349  
                                            ProjectBuilderConfiguration config,
 2350  
                                            boolean debugMessages )
 2351  
         throws ModelInterpolationException
 2352  
     {
 2353  32
         if ( originalStrings == null )
 2354  
         {
 2355  0
             return changedStrings;
 2356  
         }
 2357  32
         else if ( changedStrings == null )
 2358  
         {
 2359  0
             return originalStrings;
 2360  
         }
 2361  
 
 2362  32
         List result = new ArrayList();
 2363  
 
 2364  32
         Map orig = new HashMap();
 2365  62
         for ( int idx = 0; idx < originalStrings.size(); idx++ )
 2366  
         {
 2367  30
             String[] permutations = new String[2];
 2368  
 
 2369  30
             permutations[0] = pathTranslator.alignToBaseDirectory( (String) originalInterpolatedStrings.get( idx ), project.getBasedir() );
 2370  30
             permutations[1] = (String) originalStrings.get( idx );
 2371  
 
 2372  30
             orig.put( permutations[0], permutations );
 2373  
         }
 2374  
 
 2375  32
         for ( Iterator it = changedStrings.iterator(); it.hasNext(); )
 2376  
         {
 2377  35
             String changedString = (String) it.next();
 2378  
             String relativeChangedString;
 2379  35
             if ( project.getBasedir() != null )
 2380  
             {
 2381  35
                 relativeChangedString = pathTranslator.unalignFromBaseDirectory( changedString, project.getBasedir() );
 2382  
             }
 2383  
             else
 2384  
             {
 2385  0
                 relativeChangedString = changedString;
 2386  
             }
 2387  
 
 2388  35
             String interpolated = modelInterpolator.interpolate( changedString,
 2389  
                                                                  project.getModel(),
 2390  
                                                                  project.getBasedir(),
 2391  
                                                                  config,
 2392  
                                                                  debugMessages );
 2393  
             
 2394  35
             interpolated = pathTranslator.alignToBaseDirectory( interpolated, project.getBasedir() );
 2395  
 
 2396  35
             String relativeInterpolated = modelInterpolator.interpolate( relativeChangedString,
 2397  
                                                                          project.getModel(),
 2398  
                                                                          project.getBasedir(),
 2399  
                                                                          config,
 2400  
                                                                          debugMessages );
 2401  
             
 2402  35
             String[] original = (String[]) orig.get( interpolated );
 2403  35
             if ( original == null )
 2404  
             {
 2405  5
                 original = (String[]) orig.get( relativeInterpolated );
 2406  
             }
 2407  
 
 2408  35
             if ( original == null )
 2409  
             {
 2410  5
                 result.add( relativeChangedString );
 2411  
             }
 2412  
             else
 2413  
             {
 2414  30
                 result.add( original[1] );
 2415  
             }
 2416  35
         }
 2417  
 
 2418  32
         return result;
 2419  
     }
 2420  
 
 2421  
     private List restoreResources( List originalResources,
 2422  
                                        List originalInterpolatedResources,
 2423  
                                        List changedResources,
 2424  
                                        MavenProject project,
 2425  
                                        ProjectBuilderConfiguration config,
 2426  
                                        boolean debugMessages )
 2427  
         throws ModelInterpolationException
 2428  
     {
 2429  16
         if ( originalResources == null || changedResources == null )
 2430  
         {
 2431  0
             return originalResources;
 2432  
         }
 2433  
 
 2434  16
         List result = new ArrayList();
 2435  
 
 2436  16
         Map originalResourcesByMergeId = new HashMap();
 2437  32
         for ( int idx = 0; idx < originalResources.size(); idx++ )
 2438  
         {
 2439  16
             Resource[] permutations = new Resource[2];
 2440  
 
 2441  16
             permutations[0] = (Resource) originalInterpolatedResources.get( idx );
 2442  16
             permutations[1] = (Resource) originalResources.get( idx );
 2443  
 
 2444  16
             originalResourcesByMergeId.put( permutations[0].getMergeId(), permutations );
 2445  
         }
 2446  
 
 2447  16
         for ( Iterator it = changedResources.iterator(); it.hasNext(); )
 2448  
         {
 2449  17
             Resource resource = (Resource) it.next();
 2450  17
             String mergeId = resource.getMergeId();
 2451  17
             if ( mergeId == null || !originalResourcesByMergeId.containsKey( mergeId ) )
 2452  
             {
 2453  1
                 result.add( resource );
 2454  
             }
 2455  
             else
 2456  
             {
 2457  16
                 Resource originalInterpolatedResource = ( (Resource[]) originalResourcesByMergeId.get( mergeId ) )[0];
 2458  16
                 Resource originalResource = ( (Resource[]) originalResourcesByMergeId.get( mergeId ) )[1];
 2459  
 
 2460  16
                 String dir = modelInterpolator.interpolate( resource.getDirectory(), project.getModel(), project.getBasedir(), config, getLogger().isDebugEnabled() );
 2461  16
                 String oDir = originalInterpolatedResource.getDirectory();
 2462  
 
 2463  16
                 if ( !dir.equals( oDir ) )
 2464  
                 {
 2465  0
                     originalResource.setDirectory( pathTranslator.unalignFromBaseDirectory( dir, project.getBasedir() ) );
 2466  
                 }
 2467  
 
 2468  16
                 if ( resource.getTargetPath() != null )
 2469  
                 {
 2470  0
                     String target = modelInterpolator.interpolate( resource.getTargetPath(), project.getModel(), project.getBasedir(), config, getLogger().isDebugEnabled() );
 2471  
 
 2472  0
                     String oTarget = originalInterpolatedResource.getTargetPath();
 2473  
 
 2474  0
                     if ( !target.equals( oTarget ) )
 2475  
                     {
 2476  0
                         originalResource.setTargetPath( pathTranslator.unalignFromBaseDirectory( target, project.getBasedir() ) );
 2477  
                     }
 2478  
                 }
 2479  
 
 2480  16
                 originalResource.setFiltering( resource.isFiltering() );
 2481  
 
 2482  16
                 originalResource.setExcludes( collectRestoredListOfPatterns( resource.getExcludes(),
 2483  
                                                                              originalResource.getExcludes(),
 2484  
                                                                              originalInterpolatedResource.getExcludes() ) );
 2485  
 
 2486  16
                 originalResource.setIncludes( collectRestoredListOfPatterns( resource.getIncludes(),
 2487  
                                                                              originalResource.getIncludes(),
 2488  
                                                                              originalInterpolatedResource.getIncludes() ) );
 2489  
 
 2490  16
                 result.add( originalResource );
 2491  
             }
 2492  17
         }
 2493  
 
 2494  16
         return result;
 2495  
     }
 2496  
 
 2497  
     private List collectRestoredListOfPatterns( List patterns,
 2498  
                                                         List originalPatterns,
 2499  
                                                         List originalInterpolatedPatterns )
 2500  
     {
 2501  32
         LinkedHashSet collectedPatterns = new LinkedHashSet();
 2502  
 
 2503  32
         collectedPatterns.addAll( originalPatterns );
 2504  
 
 2505  32
         for ( Iterator it = patterns.iterator(); it.hasNext(); )
 2506  
         {
 2507  0
             String pattern = (String) it.next();
 2508  0
             if ( !originalInterpolatedPatterns.contains( pattern ) )
 2509  
             {
 2510  0
                 collectedPatterns.add( pattern );
 2511  
             }
 2512  0
         }
 2513  
 
 2514  32
         return collectedPatterns.isEmpty() ? Collections.EMPTY_LIST
 2515  
                         : new ArrayList( collectedPatterns );
 2516  
     }
 2517  
 
 2518  
 }