View Javadoc
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.RepositoryUtils;
23  import org.apache.maven.artifact.Artifact;
24  import org.apache.maven.artifact.ArtifactUtils;
25  import org.apache.maven.artifact.DependencyResolutionRequiredException;
26  import org.apache.maven.artifact.InvalidRepositoryException;
27  import org.apache.maven.artifact.factory.ArtifactFactory;
28  import org.apache.maven.artifact.repository.ArtifactRepository;
29  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
30  import org.apache.maven.model.Build;
31  import org.apache.maven.model.CiManagement;
32  import org.apache.maven.model.Contributor;
33  import org.apache.maven.model.Dependency;
34  import org.apache.maven.model.DependencyManagement;
35  import org.apache.maven.model.Developer;
36  import org.apache.maven.model.DistributionManagement;
37  import org.apache.maven.model.Extension;
38  import org.apache.maven.model.IssueManagement;
39  import org.apache.maven.model.License;
40  import org.apache.maven.model.MailingList;
41  import org.apache.maven.model.Model;
42  import org.apache.maven.model.Organization;
43  import org.apache.maven.model.Plugin;
44  import org.apache.maven.model.PluginExecution;
45  import org.apache.maven.model.PluginManagement;
46  import org.apache.maven.model.Prerequisites;
47  import org.apache.maven.model.Profile;
48  import org.apache.maven.model.ReportPlugin;
49  import org.apache.maven.model.ReportSet;
50  import org.apache.maven.model.Reporting;
51  import org.apache.maven.model.Repository;
52  import org.apache.maven.model.Resource;
53  import org.apache.maven.model.Scm;
54  import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
55  import org.apache.maven.project.artifact.InvalidDependencyVersionException;
56  import org.apache.maven.project.artifact.MavenMetadataSource;
57  import org.apache.maven.repository.RepositorySystem;
58  import org.codehaus.plexus.classworlds.realm.ClassRealm;
59  import org.codehaus.plexus.logging.Logger;
60  import org.codehaus.plexus.util.StringUtils;
61  import org.codehaus.plexus.util.xml.Xpp3Dom;
62  import org.eclipse.aether.graph.DependencyFilter;
63  import org.eclipse.aether.repository.RemoteRepository;
64  
65  import java.io.File;
66  import java.io.IOException;
67  import java.io.Writer;
68  import java.util.ArrayList;
69  import java.util.Arrays;
70  import java.util.Collections;
71  import java.util.HashMap;
72  import java.util.HashSet;
73  import java.util.LinkedHashMap;
74  import java.util.LinkedHashSet;
75  import java.util.List;
76  import java.util.Map;
77  import java.util.Properties;
78  import java.util.Set;
79  
80  /**
81   * The concern of the project is provide runtime values based on the model.
82   * <p/>
83   * The values in the model remain untouched but during the process of building a project notions
84   * like inheritance and interpolation can be added. This allows to have an entity which is useful in
85   * a runtime while preserving the model so that it can be marshalled and unmarshalled without being
86   * tainted by runtime requirements.
87   * <p/>
88   * We need to leave the model intact because we don't want the following:
89   * <ol>
90   * <li>We don't want interpolated values being written back into the model.
91   * <li>We don't want inherited values being written back into the model.
92   * </ol>
93   */
94  public class MavenProject
95      implements Cloneable
96  {
97      public static final String EMPTY_PROJECT_GROUP_ID = "unknown";
98  
99      public static final String EMPTY_PROJECT_ARTIFACT_ID = "empty-project";
100 
101     public static final String EMPTY_PROJECT_VERSION = "0";
102 
103     private static final MavenProject ERROR_BUILDING_PARENT = new MavenProject();
104 
105     private Model model;
106 
107     private MavenProject parent;
108 
109     private File file;
110 
111     private Set<Artifact> resolvedArtifacts;
112 
113     private ArtifactFilter artifactFilter;
114 
115     private Set<Artifact> artifacts;
116 
117     private Artifact parentArtifact;
118 
119     private Set<Artifact> pluginArtifacts;
120 
121     private List<ArtifactRepository> remoteArtifactRepositories;
122 
123     private List<ArtifactRepository> pluginArtifactRepositories;
124 
125     private List<RemoteRepository> remoteProjectRepositories;
126 
127     private List<RemoteRepository> remotePluginRepositories;
128 
129     private List<Artifact> attachedArtifacts;
130 
131     private MavenProject executionProject;
132 
133     private List<MavenProject> collectedProjects;
134 
135     private List<String> compileSourceRoots = new ArrayList<String>();
136 
137     private List<String> testCompileSourceRoots = new ArrayList<String>();
138 
139     private List<String> scriptSourceRoots = new ArrayList<String>();
140 
141     private ArtifactRepository releaseArtifactRepository;
142 
143     private ArtifactRepository snapshotArtifactRepository;
144 
145     private List<Profile> activeProfiles = new ArrayList<Profile>();
146 
147     private Map<String, List<String>> injectedProfileIds = new LinkedHashMap<String, List<String>>();
148 
149     private Set<Artifact> dependencyArtifacts;
150 
151     private Artifact artifact;
152 
153     // calculated.
154     private Map<String, Artifact> artifactMap;
155 
156     private Model originalModel;
157 
158     private Map<String, Artifact> pluginArtifactMap;
159 
160     private Set<Artifact> reportArtifacts;
161 
162     private Map<String, Artifact> reportArtifactMap;
163 
164     private Set<Artifact> extensionArtifacts;
165 
166     private Map<String, Artifact> extensionArtifactMap;
167 
168     private Map<String, Artifact> managedVersionMap;
169 
170     private Map<String, MavenProject> projectReferences = new HashMap<String, MavenProject>();
171 
172     private boolean executionRoot;
173 
174     private Map<String, String> moduleAdjustments;
175 
176     private ProjectBuilder mavenProjectBuilder;
177 
178     private ProjectBuildingRequest projectBuilderConfiguration;
179 
180     private RepositorySystem repositorySystem;
181     
182     private File parentFile;
183 
184     private Map<String, Object> context;
185 
186     private ClassRealm classRealm;
187 
188     private DependencyFilter extensionDependencyFilter;
189 
190     private final Set<String> lifecyclePhases = Collections.synchronizedSet( new LinkedHashSet<String>() );
191 
192     private Logger logger;
193 
194     public MavenProject()
195     {
196         Model model = new Model();
197 
198         model.setGroupId( EMPTY_PROJECT_GROUP_ID );
199         model.setArtifactId( EMPTY_PROJECT_ARTIFACT_ID );
200         model.setVersion( EMPTY_PROJECT_VERSION );
201 
202         setModel( model );
203     }
204 
205     public MavenProject( Model model )
206     {
207         setModel( model );
208     }
209 
210     /**
211      * @deprecated use {@link #clone()} so subclasses can provide a copy of the same class
212      */
213     @Deprecated
214     public MavenProject( MavenProject project )
215     {
216         repositorySystem = project.repositorySystem;
217         logger = project.logger;
218         mavenProjectBuilder = project.mavenProjectBuilder;
219         projectBuilderConfiguration = project.projectBuilderConfiguration;
220         deepCopy( project );
221     }
222     
223     @Deprecated
224     public MavenProject( Model model, RepositorySystem repositorySystem )
225     {        
226         this.repositorySystem = repositorySystem;
227         setModel( model );
228     }
229 
230     public File getParentFile()
231     {
232         return parentFile;
233     }
234 
235     public void setParentFile( File parentFile )
236     {
237         this.parentFile = parentFile;
238     }
239 
240     /**
241      * Constructor
242      * 
243      * @param repositorySystem - may not be null
244      * @param mavenProjectBuilder
245      * @param projectBuilderConfiguration
246      * @throws InvalidRepositoryException
247      */
248     MavenProject( RepositorySystem repositorySystem, ProjectBuilder mavenProjectBuilder,
249                   ProjectBuildingRequest projectBuilderConfiguration, Logger logger )
250     {
251         if ( repositorySystem == null )
252         {
253             throw new IllegalArgumentException( "mavenTools: null" );
254         }
255 
256         this.mavenProjectBuilder = mavenProjectBuilder;
257         this.projectBuilderConfiguration = projectBuilderConfiguration;
258         this.repositorySystem = repositorySystem;
259         this.logger = logger;
260     }
261 
262     @Deprecated
263     public Set<Artifact> createArtifacts( ArtifactFactory artifactFactory, String inheritedScope, ArtifactFilter filter )
264         throws InvalidDependencyVersionException
265     {
266         return MavenMetadataSource.createArtifacts( artifactFactory, getDependencies(), inheritedScope, filter, this );
267     }
268 
269     // TODO: Find a way to use <relativePath/> here...it's tricky, because the moduleProject
270     // usually doesn't have a file associated with it yet.
271     public String getModulePathAdjustment( MavenProject moduleProject )
272         throws IOException
273     {
274         // FIXME: This is hacky. What if module directory doesn't match artifactid, and parent
275         // is coming from the repository??
276         String module = moduleProject.getArtifactId();
277 
278         File moduleFile = moduleProject.getFile();
279 
280         if ( moduleFile != null )
281         {
282             File moduleDir = moduleFile.getCanonicalFile().getParentFile();
283 
284             module = moduleDir.getName();
285         }
286 
287         if ( moduleAdjustments == null )
288         {
289             moduleAdjustments = new HashMap<String, String>();
290 
291             List<String> modules = getModules();
292             if ( modules != null )
293             {
294                 for ( String modulePath : modules )
295                 {
296                     String moduleName = modulePath;
297 
298                     if ( moduleName.endsWith( "/" ) || moduleName.endsWith( "\\" ) )
299                     {
300                         moduleName = moduleName.substring( 0, moduleName.length() - 1 );
301                     }
302 
303                     int lastSlash = moduleName.lastIndexOf( '/' );
304 
305                     if ( lastSlash < 0 )
306                     {
307                         lastSlash = moduleName.lastIndexOf( '\\' );
308                     }
309 
310                     String adjustment = null;
311 
312                     if ( lastSlash > -1 )
313                     {
314                         moduleName = moduleName.substring( lastSlash + 1 );
315                         adjustment = modulePath.substring( 0, lastSlash );
316                     }
317 
318                     moduleAdjustments.put( moduleName, adjustment );
319                 }
320             }
321         }
322 
323         return moduleAdjustments.get( module );
324     }
325 
326     // ----------------------------------------------------------------------
327     // Accessors
328     // ----------------------------------------------------------------------
329 
330     public Artifact getArtifact()
331     {
332         return artifact;
333     }
334 
335     public void setArtifact( Artifact artifact )
336     {
337         this.artifact = artifact;
338     }
339 
340     //@todo I would like to get rid of this. jvz.
341     public Model getModel()
342     {
343         return model;
344     }
345 
346     /**
347      * Returns the project corresponding to a declared parent.
348      * @return the parent, or null if no parent is declared or there was an error building it
349      */
350     public MavenProject getParent()
351     {
352         if ( parent == null )
353         {
354             /*
355              * TODO: This is suboptimal. Without a cache in the project builder, rebuilding the parent chain currently
356              * causes O(n^2) parser invocations for an inheritance hierarchy of depth n.
357              */
358             if ( parentFile != null )
359             {
360                 checkProjectBuildingRequest();
361                 ProjectBuildingRequest request = new DefaultProjectBuildingRequest( projectBuilderConfiguration );
362                 request.setRemoteRepositories( getRemoteArtifactRepositories() );
363 
364                 try
365                 {
366                     parent = mavenProjectBuilder.build( parentFile, request ).getProject();
367                 }
368                 catch ( ProjectBuildingException e )
369                 {
370                     if ( logger != null )
371                     {
372                         logger.error( "Failed to build parent project for " + getId(), e );
373                     }
374                     parent = ERROR_BUILDING_PARENT;
375                 }
376             }
377             else if ( model.getParent() != null )
378             {
379                 checkProjectBuildingRequest();
380                 ProjectBuildingRequest request = new DefaultProjectBuildingRequest( projectBuilderConfiguration );
381                 request.setRemoteRepositories( getRemoteArtifactRepositories() );
382                 request.setResolveVersionRanges( true );
383 
384                 try
385                 {
386                     parent = mavenProjectBuilder.build( repositorySystem.createProjectArtifact(
387                         model.getParent().getGroupId(), model.getParent().getArtifactId(),
388                         model.getParent().getVersion() ), request ).getProject();
389 
390                     if ( !model.getParent().getVersion().equals( parent.getVersion() ) )
391                     {
392                         if ( model.getVersion() == null )
393                         {
394                             if ( logger != null )
395                             {
396                                 logger.error( "Failed to build parent project for " + getId()
397                                                   + ": Parent version must be a constant" );
398 
399                             }
400                             parent = ERROR_BUILDING_PARENT;
401                         }
402                         else
403                         {
404                             if ( model.getVersion().indexOf( "${" ) > -1 )
405                             {
406                                 if ( logger != null )
407                                 {
408                                     logger.error( "Failed to build parent project for " + getId() + ": The version '"
409                                                       + model.getParent().getVersion() + "' must be a constant" );
410 
411                                 }
412                                 parent = ERROR_BUILDING_PARENT;
413                             }
414                         }
415 
416                         // MNG-2199: What else to check here ?
417                     }
418                 }
419                 catch ( ProjectBuildingException e )
420                 {
421                     if ( logger != null )
422                     {
423                         logger.error( "Failed to build parent project for " + getId(), e );
424                     }
425                     parent = ERROR_BUILDING_PARENT;
426                 }
427             }
428         }
429         return parent == ERROR_BUILDING_PARENT ? null : parent;
430     }
431 
432     public void setParent( MavenProject parent )
433     {
434         this.parent = parent;
435     }
436     
437     public boolean hasParent()
438     {
439         return getParent() != null;
440     }
441 
442     public File getFile()
443     {
444         return file;
445     }
446 
447     public void setFile( File file )
448     {
449         this.file = file;
450     }
451 
452     public File getBasedir()
453     {
454         if ( getFile() != null )
455         {
456             return getFile().getParentFile();
457         }
458         else
459         {
460             // repository based POM
461             return null;
462         }
463     }
464 
465     public void setDependencies( List<Dependency> dependencies )
466     {
467         getModel().setDependencies( dependencies );
468     }
469 
470     public List<Dependency> getDependencies()
471     {
472         return getModel().getDependencies();
473     }
474 
475     public DependencyManagement getDependencyManagement()
476     {
477         return getModel().getDependencyManagement();
478     }
479 
480     // ----------------------------------------------------------------------
481     // Test and compile sourceroots.
482     // ----------------------------------------------------------------------
483 
484     private void addPath( List<String> paths, String path )
485     {
486         if ( path != null )
487         {
488             path = path.trim();
489             if ( path.length() > 0 )
490             {
491                 File file = new File( path );
492                 if ( file.isAbsolute() )
493                 {
494                     path = file.getAbsolutePath();
495                 }
496                 else
497                 {
498                     path = new File( getBasedir(), path ).getAbsolutePath();
499                 }
500 
501                 if ( !paths.contains( path ) )
502                 {
503                     paths.add( path );
504                 }
505             }
506         }
507     }
508 
509     public void addCompileSourceRoot( String path )
510     {
511         addPath( getCompileSourceRoots(), path );
512     }
513 
514     public void addScriptSourceRoot( String path )
515     {
516         if ( path != null )
517         {
518             path = path.trim();
519             if ( path.length() != 0 && !getScriptSourceRoots().contains( path ) )
520             {
521                 getScriptSourceRoots().add( path );
522             }
523         }
524     }
525 
526     public void addTestCompileSourceRoot( String path )
527     {
528         addPath( getTestCompileSourceRoots(), path );
529     }
530 
531     public List<String> getCompileSourceRoots()
532     {
533         return compileSourceRoots;
534     }
535 
536     public List<String> getScriptSourceRoots()
537     {
538         return scriptSourceRoots;
539     }
540 
541     public List<String> getTestCompileSourceRoots()
542     {
543         return testCompileSourceRoots;
544     }
545 
546     public List<String> getCompileClasspathElements()
547         throws DependencyResolutionRequiredException
548     {
549         List<String> list = new ArrayList<String>( getArtifacts().size() + 1 );
550 
551         String d = getBuild().getOutputDirectory();
552         if ( d != null )
553         {
554             list.add( d );
555         }
556 
557         for ( Artifact a : getArtifacts() )
558         {                        
559             if ( a.getArtifactHandler().isAddedToClasspath()
560             // TODO: let the scope handler deal with this
561                 && ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) )
562             {
563                 addArtifactPath( a, list );
564             }
565         }
566 
567         return list;
568     }
569 
570     @Deprecated
571     public List<Artifact> getCompileArtifacts()
572     {
573         List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
574 
575         for ( Artifact a : getArtifacts() )
576         {
577             // TODO: classpath check doesn't belong here - that's the other method
578             if ( a.getArtifactHandler().isAddedToClasspath()
579             // TODO: let the scope handler deal with this
580                 && ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) ) )
581             {
582                 list.add( a );
583             }
584         }
585         return list;
586     }
587 
588     @Deprecated
589     public List<Dependency> getCompileDependencies()
590     {
591         Set<Artifact> artifacts = getArtifacts();
592 
593         if ( ( artifacts == null ) || artifacts.isEmpty() )
594         {
595             return Collections.emptyList();
596         }
597 
598         List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
599 
600         for ( Artifact a : getArtifacts()  )
601         {
602             // TODO: let the scope handler deal with this
603             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
604             {
605                 Dependency dependency = new Dependency();
606 
607                 dependency.setArtifactId( a.getArtifactId() );
608                 dependency.setGroupId( a.getGroupId() );
609                 dependency.setVersion( a.getVersion() );
610                 dependency.setScope( a.getScope() );
611                 dependency.setType( a.getType() );
612                 dependency.setClassifier( a.getClassifier() );
613 
614                 list.add( dependency );
615             }
616         }
617         return list;
618     }
619 
620     //TODO: this checking for file == null happens because the resolver has been confused about the root
621     // artifact or not. things like the stupid dummy artifact coming from surefire.
622     public List<String> getTestClasspathElements()
623         throws DependencyResolutionRequiredException
624     {
625         List<String> list = new ArrayList<String>( getArtifacts().size() + 2 );
626 
627         String d = getBuild().getTestOutputDirectory();
628         if ( d != null )
629         {
630             list.add( d );
631         }
632 
633         d = getBuild().getOutputDirectory();
634         if ( d != null )
635         {
636             list.add( d );
637         }
638         
639         for ( Artifact a : getArtifacts() )
640         {            
641             if ( a.getArtifactHandler().isAddedToClasspath() )
642             {                
643                 addArtifactPath( a, list );
644             }
645         }
646 
647         return list;
648     }
649 
650     @Deprecated
651     public List<Artifact> getTestArtifacts()
652     {
653         List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
654 
655         for ( Artifact a : getArtifacts() )
656         {
657             // TODO: classpath check doesn't belong here - that's the other method
658             if ( a.getArtifactHandler().isAddedToClasspath() )
659             {
660                 list.add( a );
661             }
662         }
663         return list;
664     }
665 
666     @Deprecated
667     public List<Dependency> getTestDependencies()
668     {
669         Set<Artifact> artifacts = getArtifacts();
670 
671         if ( ( artifacts == null ) || artifacts.isEmpty() )
672         {
673             return Collections.emptyList();
674         }
675 
676         List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
677 
678         for ( Artifact a : getArtifacts()  )
679         {
680             Dependency dependency = new Dependency();
681 
682             dependency.setArtifactId( a.getArtifactId() );
683             dependency.setGroupId( a.getGroupId() );
684             dependency.setVersion( a.getVersion() );
685             dependency.setScope( a.getScope() );
686             dependency.setType( a.getType() );
687             dependency.setClassifier( a.getClassifier() );
688 
689             list.add( dependency );
690         }
691         return list;
692     }
693 
694     public List<String> getRuntimeClasspathElements()
695         throws DependencyResolutionRequiredException
696     {
697         List<String> list = new ArrayList<String>( getArtifacts().size() + 1 );
698 
699         String d = getBuild().getOutputDirectory();
700         if ( d != null )
701         {
702             list.add( d );
703         }
704 
705         for ( Artifact a : getArtifacts() )
706         {
707             if ( a.getArtifactHandler().isAddedToClasspath()
708             // TODO: let the scope handler deal with this
709                 && ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) ) )
710             {
711                 addArtifactPath( a, list );
712             }
713         }
714         return list;
715     }
716 
717     @Deprecated
718     public List<Artifact> getRuntimeArtifacts()
719     {
720         List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
721 
722         for ( Artifact a : getArtifacts()  )
723         {
724             // TODO: classpath check doesn't belong here - that's the other method
725             if ( a.getArtifactHandler().isAddedToClasspath()
726             // TODO: let the scope handler deal with this
727                 && ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) ) )
728             {
729                 list.add( a );
730             }
731         }
732         return list;
733     }
734 
735     @Deprecated
736     public List<Dependency> getRuntimeDependencies()
737     {
738         Set<Artifact> artifacts = getArtifacts();
739 
740         if ( ( artifacts == null ) || artifacts.isEmpty() )
741         {
742             return Collections.emptyList();
743         }
744 
745         List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
746 
747         for ( Artifact a : getArtifacts()  )
748         {
749             // TODO: let the scope handler deal with this
750             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
751             {
752                 Dependency dependency = new Dependency();
753 
754                 dependency.setArtifactId( a.getArtifactId() );
755                 dependency.setGroupId( a.getGroupId() );
756                 dependency.setVersion( a.getVersion() );
757                 dependency.setScope( a.getScope() );
758                 dependency.setType( a.getType() );
759                 dependency.setClassifier( a.getClassifier() );
760 
761                 list.add( dependency );
762             }
763         }
764         return list;
765     }
766 
767     public List<String> getSystemClasspathElements()
768         throws DependencyResolutionRequiredException
769     {
770         List<String> list = new ArrayList<String>( getArtifacts().size() );
771 
772         String d = getBuild().getOutputDirectory();
773         if ( d != null )
774         {
775             list.add( d );
776         }
777 
778         for ( Artifact a : getArtifacts() )
779         {
780             if ( a.getArtifactHandler().isAddedToClasspath()
781             // TODO: let the scope handler deal with this
782                 && Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
783             {
784                 addArtifactPath( a, list );
785             }
786         }
787         return list;
788     }
789 
790     @Deprecated
791     public List<Artifact> getSystemArtifacts()
792     {
793         List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
794 
795         for ( Artifact a : getArtifacts()  )
796         {
797             // TODO: classpath check doesn't belong here - that's the other method
798             if ( a.getArtifactHandler().isAddedToClasspath()
799             // TODO: let the scope handler deal with this
800                 && Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
801             {
802                 list.add( a );
803             }
804         }
805         return list;
806     }
807 
808     @Deprecated
809     public List<Dependency> getSystemDependencies()
810     {
811         Set<Artifact> artifacts = getArtifacts();
812 
813         if ( ( artifacts == null ) || artifacts.isEmpty() )
814         {
815             return Collections.emptyList();
816         }
817 
818         List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
819 
820         for ( Artifact a : getArtifacts()  )
821         {
822             // TODO: let the scope handler deal with this
823             if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
824             {
825                 Dependency dependency = new Dependency();
826 
827                 dependency.setArtifactId( a.getArtifactId() );
828                 dependency.setGroupId( a.getGroupId() );
829                 dependency.setVersion( a.getVersion() );
830                 dependency.setScope( a.getScope() );
831                 dependency.setType( a.getType() );
832                 dependency.setClassifier( a.getClassifier() );
833 
834                 list.add( dependency );
835             }
836         }
837         return list;
838     }
839 
840     // ----------------------------------------------------------------------
841     // Delegate to the model
842     // ----------------------------------------------------------------------
843 
844     public void setModelVersion( String pomVersion )
845     {
846         getModel().setModelVersion( pomVersion );
847     }
848 
849     public String getModelVersion()
850     {
851         return getModel().getModelVersion();
852     }
853 
854     public String getId()
855     {
856         return getModel().getId();
857     }
858 
859     public void setGroupId( String groupId )
860     {
861         getModel().setGroupId( groupId );
862     }
863 
864     public String getGroupId()
865     {
866         String groupId = getModel().getGroupId();
867 
868         if ( ( groupId == null ) && ( getModel().getParent() != null ) )
869         {
870             groupId = getModel().getParent().getGroupId();
871         }
872 
873         return groupId;
874     }
875 
876     public void setArtifactId( String artifactId )
877     {
878         getModel().setArtifactId( artifactId );
879     }
880 
881     public String getArtifactId()
882     {
883         return getModel().getArtifactId();
884     }
885 
886     public void setName( String name )
887     {
888         getModel().setName( name );
889     }
890 
891     public String getName()
892     {
893         // TODO: this should not be allowed to be null.
894         if ( getModel().getName() != null )
895         {
896             return getModel().getName();
897         }
898         else
899         {
900             return getArtifactId();
901         }
902     }
903 
904     public void setVersion( String version )
905     {
906         getModel().setVersion( version );
907     }
908 
909     public String getVersion()
910     {
911         String version = getModel().getVersion();
912 
913         if ( ( version == null ) && ( getModel().getParent() != null ) )
914         {
915             version = getModel().getParent().getVersion();
916         }
917 
918         return version;
919     }
920 
921     public String getPackaging()
922     {
923         return getModel().getPackaging();
924     }
925 
926     public void setPackaging( String packaging )
927     {
928         getModel().setPackaging( packaging );
929     }
930 
931     public void setInceptionYear( String inceptionYear )
932     {
933         getModel().setInceptionYear( inceptionYear );
934     }
935 
936     public String getInceptionYear()
937     {
938         return getModel().getInceptionYear();
939     }
940 
941     public void setUrl( String url )
942     {
943         getModel().setUrl( url );
944     }
945 
946     public String getUrl()
947     {
948         return getModel().getUrl();
949     }
950 
951     public Prerequisites getPrerequisites()
952     {
953         return getModel().getPrerequisites();
954     }
955 
956     public void setIssueManagement( IssueManagement issueManagement )
957     {
958         getModel().setIssueManagement( issueManagement );
959     }
960 
961     public CiManagement getCiManagement()
962     {
963         return getModel().getCiManagement();
964     }
965 
966     public void setCiManagement( CiManagement ciManagement )
967     {
968         getModel().setCiManagement( ciManagement );
969     }
970 
971     public IssueManagement getIssueManagement()
972     {
973         return getModel().getIssueManagement();
974     }
975 
976     public void setDistributionManagement( DistributionManagement distributionManagement )
977     {
978         getModel().setDistributionManagement( distributionManagement );
979     }
980 
981     public DistributionManagement getDistributionManagement()
982     {
983         return getModel().getDistributionManagement();
984     }
985 
986     public void setDescription( String description )
987     {
988         getModel().setDescription( description );
989     }
990 
991     public String getDescription()
992     {
993         return getModel().getDescription();
994     }
995 
996     public void setOrganization( Organization organization )
997     {
998         getModel().setOrganization( organization );
999     }
1000 
1001     public Organization getOrganization()
1002     {
1003         return getModel().getOrganization();
1004     }
1005 
1006     public void setScm( Scm scm )
1007     {
1008         getModel().setScm( scm );
1009     }
1010 
1011     public Scm getScm()
1012     {
1013         return getModel().getScm();
1014     }
1015 
1016     public void setMailingLists( List<MailingList> mailingLists )
1017     {
1018         getModel().setMailingLists( mailingLists );
1019     }
1020 
1021     public List<MailingList> getMailingLists()
1022     {
1023         return getModel().getMailingLists();
1024     }
1025 
1026     public void addMailingList( MailingList mailingList )
1027     {
1028         getModel().addMailingList( mailingList );
1029     }
1030 
1031     public void setDevelopers( List<Developer> developers )
1032     {
1033         getModel().setDevelopers( developers );
1034     }
1035 
1036     public List<Developer> getDevelopers()
1037     {
1038         return getModel().getDevelopers();
1039     }
1040 
1041     public void addDeveloper( Developer developer )
1042     {
1043         getModel().addDeveloper( developer );
1044     }
1045 
1046     public void setContributors( List<Contributor> contributors )
1047     {
1048         getModel().setContributors( contributors );
1049     }
1050 
1051     public List<Contributor> getContributors()
1052     {
1053         return getModel().getContributors();
1054     }
1055 
1056     public void addContributor( Contributor contributor )
1057     {
1058         getModel().addContributor( contributor );
1059     }
1060 
1061     public void setBuild( Build build )
1062     {
1063         getModel().setBuild( build );
1064     }
1065 
1066     public Build getBuild()
1067     {
1068         return getModelBuild();
1069     }
1070 
1071     public List<Resource> getResources()
1072     {
1073         return getBuild().getResources();
1074     }
1075 
1076     public List<Resource> getTestResources()
1077     {
1078         return getBuild().getTestResources();
1079     }
1080 
1081     public void addResource( Resource resource )
1082     {
1083         getBuild().addResource( resource );
1084     }
1085 
1086     public void addTestResource( Resource testResource )
1087     {
1088         getBuild().addTestResource( testResource );
1089     }
1090 
1091     @Deprecated
1092     public void setReporting( Reporting reporting )
1093     {
1094         getModel().setReporting( reporting );
1095     }
1096 
1097     @Deprecated
1098     public Reporting getReporting()
1099     {
1100         return getModel().getReporting();
1101     }
1102 
1103     public void setLicenses( List<License> licenses )
1104     {
1105         getModel().setLicenses( licenses );
1106     }
1107 
1108     public List<License> getLicenses()
1109     {
1110         return getModel().getLicenses();
1111     }
1112 
1113     public void addLicense( License license )
1114     {
1115         getModel().addLicense( license );
1116     }
1117 
1118     public void setArtifacts( Set<Artifact> artifacts )
1119     {
1120         this.artifacts = artifacts;
1121 
1122         // flush the calculated artifactMap
1123         artifactMap = null;
1124     }
1125 
1126     /**
1127      * All dependencies that this project has, including transitive ones. Contents are lazily
1128      * populated, so depending on what phases have run dependencies in some scopes won't be
1129      * included. eg. if only compile phase has run, dependencies with scope test won't be included.
1130      * 
1131      * @return {@link Set} &lt; {@link Artifact} >
1132      * @see #getDependencyArtifacts() to get only direct dependencies
1133      */
1134     public Set<Artifact> getArtifacts()
1135     {
1136         if ( artifacts == null )
1137         {
1138             if ( artifactFilter == null || resolvedArtifacts == null )
1139             {
1140                 artifacts = new LinkedHashSet<Artifact>();
1141             }
1142             else
1143             {
1144                 artifacts = new LinkedHashSet<Artifact>( resolvedArtifacts.size() * 2 );
1145                 for ( Artifact artifact : resolvedArtifacts )
1146                 {
1147                     if ( artifactFilter.include( artifact ) )
1148                     {
1149                         artifacts.add( artifact );
1150                     }
1151                 }
1152             }
1153         }
1154         return artifacts;
1155     }
1156 
1157     public Map<String, Artifact> getArtifactMap()
1158     {
1159         if ( artifactMap == null )
1160         {
1161             artifactMap = ArtifactUtils.artifactMapByVersionlessId( getArtifacts() );
1162         }
1163         return artifactMap;
1164     }
1165 
1166     public void setPluginArtifacts( Set<Artifact> pluginArtifacts )
1167     {
1168         this.pluginArtifacts = pluginArtifacts;
1169 
1170         this.pluginArtifactMap = null;
1171     }
1172 
1173     public Set<Artifact> getPluginArtifacts()
1174     {
1175         if ( pluginArtifacts != null )
1176         {
1177             return pluginArtifacts;
1178         }
1179 
1180         pluginArtifacts = new HashSet<Artifact>();
1181 
1182         if ( repositorySystem != null )
1183         {
1184             for ( Plugin p : getBuildPlugins() )
1185             {
1186                 Artifact artifact = repositorySystem.createPluginArtifact( p );
1187 
1188                 if ( artifact != null )
1189                 {
1190                     pluginArtifacts.add( artifact );
1191                 }
1192             }
1193         }
1194 
1195         pluginArtifactMap = null;
1196 
1197         return pluginArtifacts;
1198     }
1199 
1200     public Map<String, Artifact> getPluginArtifactMap()
1201     {
1202         if ( pluginArtifactMap == null )
1203         {
1204             pluginArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getPluginArtifacts() );
1205         }
1206 
1207         return pluginArtifactMap;
1208     }
1209 
1210     @Deprecated
1211     public void setReportArtifacts( Set<Artifact> reportArtifacts )
1212     {
1213         this.reportArtifacts = reportArtifacts;
1214 
1215         reportArtifactMap = null;
1216     }
1217 
1218     @Deprecated
1219     public Set<Artifact> getReportArtifacts()
1220     {
1221         if ( reportArtifacts != null )
1222         {
1223             return reportArtifacts;
1224         }
1225 
1226         reportArtifacts = new HashSet<Artifact>();
1227 
1228         if ( repositorySystem != null )
1229         {
1230             for ( ReportPlugin p : getReportPlugins() )
1231             {
1232                 Plugin pp = new Plugin();
1233                 pp.setGroupId( p.getGroupId() );
1234                 pp.setArtifactId( p.getArtifactId() );
1235                 pp.setVersion( p.getVersion() );
1236 
1237                 Artifact artifact = repositorySystem.createPluginArtifact( pp );
1238 
1239                 if ( artifact != null )
1240                 {
1241                     reportArtifacts.add( artifact );
1242                 }
1243             }
1244         }
1245 
1246         reportArtifactMap = null;
1247 
1248         return reportArtifacts;
1249     }
1250 
1251     @Deprecated
1252     public Map<String, Artifact> getReportArtifactMap()
1253     {
1254         if ( reportArtifactMap == null )
1255         {
1256             reportArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getReportArtifacts() );
1257         }
1258 
1259         return reportArtifactMap;
1260     }
1261 
1262     public void setExtensionArtifacts( Set<Artifact> extensionArtifacts )
1263     {
1264         this.extensionArtifacts = extensionArtifacts;
1265 
1266         extensionArtifactMap = null;
1267     }
1268 
1269     public Set<Artifact> getExtensionArtifacts()
1270     {
1271         if ( extensionArtifacts != null )
1272         {
1273             return extensionArtifacts;
1274         }
1275         extensionArtifacts = new HashSet<Artifact>();
1276         List<Extension> extensions = getBuildExtensions();
1277         if ( extensions != null )
1278         {
1279             for ( Extension ext : extensions )
1280             {
1281                 String version;
1282                 if ( StringUtils.isEmpty( ext.getVersion() ) )
1283                 {
1284                     version = "RELEASE";
1285                 }
1286                 else
1287                 {
1288                     version = ext.getVersion();
1289                 }
1290 
1291                 Artifact artifact =
1292                     repositorySystem.createArtifact( ext.getGroupId(), ext.getArtifactId(), version, null, "jar" );
1293 
1294                 if ( artifact != null )
1295                 {
1296                     extensionArtifacts.add( artifact );
1297                 }
1298             }
1299         }
1300         extensionArtifactMap = null;
1301         return extensionArtifacts;
1302     }
1303 
1304     public Map<String, Artifact> getExtensionArtifactMap()
1305     {
1306         if ( extensionArtifactMap == null )
1307         {
1308             extensionArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getExtensionArtifacts() );
1309         }
1310 
1311         return extensionArtifactMap;
1312     }
1313 
1314     public void setParentArtifact( Artifact parentArtifact )
1315     {
1316         this.parentArtifact = parentArtifact;
1317     }
1318 
1319     public Artifact getParentArtifact()
1320     {
1321         if ( parentArtifact == null && getParent() != null )
1322         {
1323             parentArtifact = repositorySystem.createProjectArtifact(
1324                 getParent().getGroupId(), getParent().getArtifactId(), getParent().getVersion() );
1325 
1326         }
1327         return parentArtifact;
1328     }
1329 
1330     public List<Repository> getRepositories()
1331     {
1332         return getModel().getRepositories();
1333     }
1334 
1335     // ----------------------------------------------------------------------
1336     // Plugins
1337     // ----------------------------------------------------------------------
1338 
1339     @Deprecated
1340     public List<ReportPlugin> getReportPlugins()
1341     {
1342         if ( getModel().getReporting() == null )
1343         {
1344             return Collections.emptyList();
1345         }
1346         return getModel().getReporting().getPlugins();
1347 
1348     }
1349 
1350     public List<Plugin> getBuildPlugins()
1351     {
1352         if ( getModel().getBuild() == null )
1353         {
1354             return Collections.emptyList();
1355         }
1356         return getModel().getBuild().getPlugins();
1357     }
1358 
1359     public List<String> getModules()
1360     {
1361         return getModel().getModules();
1362     }
1363 
1364     public PluginManagement getPluginManagement()
1365     {
1366         PluginManagement pluginMgmt = null;
1367 
1368         Build build = getModel().getBuild();
1369         if ( build != null )
1370         {
1371             pluginMgmt = build.getPluginManagement();
1372         }
1373 
1374         return pluginMgmt;
1375     }
1376 
1377     private Build getModelBuild()
1378     {
1379         Build build = getModel().getBuild();
1380 
1381         if ( build == null )
1382         {
1383             build = new Build();
1384 
1385             getModel().setBuild( build );
1386         }
1387 
1388         return build;
1389     }
1390 
1391     public void setRemoteArtifactRepositories( List<ArtifactRepository> remoteArtifactRepositories )
1392     {
1393         this.remoteArtifactRepositories = remoteArtifactRepositories;
1394         this.remoteProjectRepositories = RepositoryUtils.toRepos( getRemoteArtifactRepositories() );
1395     }
1396 
1397     public List<ArtifactRepository> getRemoteArtifactRepositories()
1398     {
1399         if ( remoteArtifactRepositories == null )
1400         {
1401             remoteArtifactRepositories = new ArrayList<ArtifactRepository>();
1402         }
1403 
1404         return remoteArtifactRepositories;
1405     }
1406 
1407     public void setPluginArtifactRepositories( List<ArtifactRepository> pluginArtifactRepositories )
1408     {
1409         this.pluginArtifactRepositories = pluginArtifactRepositories;
1410         this.remotePluginRepositories = RepositoryUtils.toRepos( getPluginArtifactRepositories() );
1411     }
1412 
1413     /**
1414      * @return a list of ArtifactRepository objects constructed from the Repository objects returned
1415      *         by getPluginRepositories.
1416      */
1417     public List<ArtifactRepository> getPluginArtifactRepositories()
1418     {
1419         if ( pluginArtifactRepositories == null )
1420         {
1421             pluginArtifactRepositories = new ArrayList<ArtifactRepository>();
1422         }
1423 
1424         return pluginArtifactRepositories;
1425     }
1426 
1427     public ArtifactRepository getDistributionManagementArtifactRepository()
1428     {
1429         return getArtifact().isSnapshot() && ( getSnapshotArtifactRepository() != null ) ? getSnapshotArtifactRepository() : getReleaseArtifactRepository();
1430     }
1431 
1432     public List<Repository> getPluginRepositories()
1433     {
1434         return getModel().getPluginRepositories();
1435     }
1436 
1437     public List<RemoteRepository> getRemoteProjectRepositories()
1438     {
1439         return remoteProjectRepositories;
1440     }
1441 
1442     public List<RemoteRepository> getRemotePluginRepositories()
1443     {
1444         return remotePluginRepositories;
1445     }
1446 
1447     public void setActiveProfiles( List<Profile> activeProfiles )
1448     {
1449         this.activeProfiles = activeProfiles;
1450     }
1451 
1452     public List<Profile> getActiveProfiles()
1453     {
1454         return activeProfiles;
1455     }
1456 
1457     public void setInjectedProfileIds( String source, List<String> injectedProfileIds )
1458     {
1459         if ( injectedProfileIds != null )
1460         {
1461             this.injectedProfileIds.put( source, new ArrayList<String>( injectedProfileIds ) );
1462         }
1463         else
1464         {
1465             this.injectedProfileIds.remove( source );
1466         }
1467     }
1468 
1469     /**
1470      * Gets the identifiers of all profiles that contributed to this project's effective model. This includes active
1471      * profiles from the project's POM and all its parent POMs as well as from external sources like the {@code
1472      * settings.xml}. The profile identifiers are grouped by the identifier of their source, e.g. {@code
1473      * <groupId>:<artifactId>:<version>} for a POM profile or {@code external} for profiles from the {@code
1474      * settings.xml}.
1475      * 
1476      * @return The identifiers of all injected profiles, indexed by the source from which the profiles originated, never
1477      *         {@code null}.
1478      */
1479     public Map<String, List<String>> getInjectedProfileIds()
1480     {
1481         return this.injectedProfileIds;
1482     }
1483 
1484     private String logStringForArtifactFile( Artifact a )
1485     {
1486         if ( a.getFile() != null )
1487         {
1488             return a.getFile().getAbsolutePath();
1489         }
1490         else
1491         {
1492             return "(no path)";
1493         }
1494     }
1495 
1496     /**
1497      * Add or replace an artifact.
1498      * In spite of the 'throws' declaration on this API, this method has never thrown an exception since Maven 3.0.x.
1499      * Historically, it logged and ignored a second addition of the same g/a/v/c/t. Now it replaces the file for
1500      * the artifact, so that plugins (e.g. shade) can change the pathname of the file for a particular set of
1501      * coordinates.
1502      * @param artifact the artifact to add or replace.
1503      * @throws DuplicateArtifactAttachmentException
1504      */
1505     public void addAttachedArtifact( Artifact artifact )
1506         throws DuplicateArtifactAttachmentException
1507     {
1508         List<Artifact> attachedArtifacts = getAttachedArtifacts();
1509         for ( int ax = 0; ax < attachedArtifacts.size(); ax++ )
1510         {
1511             Artifact a = attachedArtifacts.get( ax );
1512             if ( a.equals( artifact ) )
1513             {
1514                 if ( logger != null )
1515                 {
1516                     logger.debug( String.format( "Replacing attached artifact %s. Old path %s, new path %s. ",
1517                                                  a,
1518                                                  logStringForArtifactFile( a ),
1519                                                  logStringForArtifactFile( artifact ) ) );
1520                 }
1521                 attachedArtifacts.set( ax, artifact );
1522                 return;
1523             }
1524         }
1525 
1526         getAttachedArtifacts().add( artifact );
1527     }
1528 
1529     public List<Artifact> getAttachedArtifacts()
1530     {
1531         if ( attachedArtifacts == null )
1532         {
1533             attachedArtifacts = new ArrayList<Artifact>();
1534         }
1535         return attachedArtifacts;
1536     }
1537 
1538     public Xpp3Dom getGoalConfiguration( String pluginGroupId, String pluginArtifactId, String executionId,
1539                                          String goalId )
1540     {
1541         Xpp3Dom dom = null;
1542 
1543         if ( getBuildPlugins() != null )
1544         {
1545             for ( Plugin plugin : getBuildPlugins() )
1546             {
1547                 if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
1548                 {
1549                     dom = (Xpp3Dom) plugin.getConfiguration();
1550 
1551                     if ( executionId != null )
1552                     {
1553                         PluginExecution execution = plugin.getExecutionsAsMap().get( executionId );
1554                         if ( execution != null )
1555                         {
1556                             // NOTE: The PluginConfigurationExpander already merged the plugin-level config in
1557                             dom = (Xpp3Dom) execution.getConfiguration();
1558                         }
1559                     }
1560                     break;
1561                 }
1562             }
1563         }
1564 
1565         if ( dom != null )
1566         {
1567             // make a copy so the original in the POM doesn't get messed with
1568             dom = new Xpp3Dom( dom );
1569         }
1570 
1571         return dom;
1572     }
1573 
1574     @Deprecated
1575     public Xpp3Dom getReportConfiguration( String pluginGroupId, String pluginArtifactId, String reportSetId )
1576     {
1577         Xpp3Dom dom = null;
1578 
1579         // ----------------------------------------------------------------------
1580         // I would like to be able to lookup the Mojo object using a key but
1581         // we have a limitation in modello that will be remedied shortly. So
1582         // for now I have to iterate through and see what we have.
1583         // ----------------------------------------------------------------------
1584 
1585         if ( getReportPlugins() != null )
1586         {
1587             for ( ReportPlugin plugin : getReportPlugins() )
1588             {
1589                 if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
1590                 {
1591                     dom = (Xpp3Dom) plugin.getConfiguration();
1592 
1593                     if ( reportSetId != null )
1594                     {
1595                         ReportSet reportSet = plugin.getReportSetsAsMap().get( reportSetId );
1596                         if ( reportSet != null )
1597                         {
1598                             Xpp3Dom executionConfiguration = (Xpp3Dom) reportSet.getConfiguration();
1599                             if ( executionConfiguration != null )
1600                             {
1601                                 Xpp3Dom newDom = new Xpp3Dom( executionConfiguration );
1602                                 dom = Xpp3Dom.mergeXpp3Dom( newDom, dom );
1603                             }
1604                         }
1605                     }
1606                     break;
1607                 }
1608             }
1609         }
1610 
1611         if ( dom != null )
1612         {
1613             // make a copy so the original in the POM doesn't get messed with
1614             dom = new Xpp3Dom( dom );
1615         }
1616 
1617         return dom;
1618     }
1619 
1620     public MavenProject getExecutionProject()
1621     {
1622         return ( executionProject == null ? this : executionProject );
1623     }
1624 
1625     public void setExecutionProject( MavenProject executionProject )
1626     {
1627         this.executionProject = executionProject;
1628     }
1629 
1630     public List<MavenProject> getCollectedProjects()
1631     {
1632         return collectedProjects;
1633     }
1634 
1635     public void setCollectedProjects( List<MavenProject> collectedProjects )
1636     {
1637         this.collectedProjects = collectedProjects;
1638     }
1639 
1640     /**
1641      * Direct dependencies that this project has.
1642      * 
1643      * @return {@link Set} &lt; {@link Artifact} >
1644      * @see #getArtifacts() to get all transitive dependencies
1645      */
1646     public Set<Artifact> getDependencyArtifacts()
1647     {
1648         return dependencyArtifacts;
1649     }
1650 
1651     public void setDependencyArtifacts( Set<Artifact> dependencyArtifacts )
1652     {
1653         this.dependencyArtifacts = dependencyArtifacts;
1654     }
1655 
1656     public void setReleaseArtifactRepository( ArtifactRepository releaseArtifactRepository )
1657     {
1658         this.releaseArtifactRepository = releaseArtifactRepository;
1659     }
1660 
1661     public void setSnapshotArtifactRepository( ArtifactRepository snapshotArtifactRepository )
1662     {
1663         this.snapshotArtifactRepository = snapshotArtifactRepository;
1664     }
1665 
1666     public void setOriginalModel( Model originalModel )
1667     {
1668         this.originalModel = originalModel;
1669     }
1670 
1671     public Model getOriginalModel()
1672     {
1673         return originalModel;
1674     }
1675 
1676     public void setManagedVersionMap( Map<String, Artifact> map )
1677     {
1678         managedVersionMap = map;
1679     }
1680 
1681     public Map<String, Artifact> getManagedVersionMap()
1682     {
1683         if ( managedVersionMap != null )
1684         {
1685             return managedVersionMap;
1686         }
1687 
1688         Map<String, Artifact> map = null;
1689         if ( repositorySystem != null )
1690         {
1691 
1692             List<Dependency> deps;
1693             DependencyManagement dependencyManagement = getDependencyManagement();
1694             if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null ) && ( deps.size() > 0 ) )
1695             {
1696                 map = new HashMap<String, Artifact>();
1697                 for ( Dependency d : dependencyManagement.getDependencies() )
1698                 {
1699                     Artifact artifact = repositorySystem.createDependencyArtifact( d );
1700 
1701                     if ( artifact == null )
1702                     {
1703                         map = Collections.emptyMap();
1704                     }
1705 
1706                     map.put( d.getManagementKey(), artifact );
1707                 }
1708             }
1709             else
1710             {
1711                 map = Collections.emptyMap();
1712             }
1713         }
1714         managedVersionMap = map;
1715         return managedVersionMap;
1716     }
1717 
1718     @Override
1719     public boolean equals( Object other )
1720     {
1721         if ( other == this )
1722         {
1723             return true;
1724         }
1725         else if ( !( other instanceof MavenProject ) )
1726         {
1727             return false;
1728         }
1729 
1730         MavenProject that = (MavenProject) other;
1731 
1732         return eq( getArtifactId(), that.getArtifactId() )
1733             && eq( getGroupId(), that.getGroupId() )
1734             && eq( getVersion(), that.getVersion() );
1735     }
1736 
1737     private static <T> boolean eq( T s1, T s2 )
1738     {
1739         return ( s1 != null ) ? s1.equals( s2 ) : s2 == null;
1740     }
1741 
1742     @Override
1743     public int hashCode()
1744     {
1745         int hash = 17;
1746         hash = 31 * hash + getGroupId().hashCode();
1747         hash = 31 * hash + getArtifactId().hashCode();
1748         hash = 31 * hash + getVersion().hashCode();
1749         return hash;
1750     }
1751 
1752     public List<Extension> getBuildExtensions()
1753     {
1754         Build build = getBuild();
1755         if ( ( build == null ) || ( build.getExtensions() == null ) )
1756         {
1757             return Collections.emptyList();
1758         }
1759         else
1760         {
1761             return build.getExtensions();
1762         }
1763     }
1764 
1765     public void addProjectReference( MavenProject project )
1766     {
1767         projectReferences.put( getProjectReferenceId( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project );
1768     }
1769 
1770     /**
1771      * @deprecated Use MavenProjectHelper.attachArtifact(..) instead.
1772      */
1773     @Deprecated
1774     public void attachArtifact( String type, String classifier, File file )
1775     {
1776     }
1777 
1778     public Properties getProperties()
1779     {
1780         return getModel().getProperties();
1781     }
1782 
1783     public List<String> getFilters()
1784     {
1785         return getBuild().getFilters();
1786     }
1787 
1788     public Map<String, MavenProject> getProjectReferences()
1789     {
1790         return projectReferences;
1791     }
1792 
1793     public boolean isExecutionRoot()
1794     {
1795         return executionRoot;
1796     }
1797 
1798     public void setExecutionRoot( boolean executionRoot )
1799     {
1800         this.executionRoot = executionRoot;
1801     }
1802 
1803     public String getDefaultGoal()
1804     {
1805         return getBuild() != null ? getBuild().getDefaultGoal() : null;
1806     }
1807 
1808     public Plugin getPlugin( String pluginKey )
1809     {
1810         return getBuild().getPluginsAsMap().get( pluginKey );
1811     }
1812 
1813     /**
1814      * Default toString
1815      */
1816     @Override
1817     public String toString()
1818     {
1819         StringBuilder sb = new StringBuilder( 128 );
1820         sb.append( "MavenProject: " );
1821         sb.append( getGroupId() );
1822         sb.append( ":" );
1823         sb.append( getArtifactId() );
1824         sb.append( ":" );
1825         sb.append( getVersion() );
1826         sb.append( " @ " );
1827 
1828         try
1829         {
1830             sb.append( getFile().getPath() );
1831         }
1832         catch ( NullPointerException e )
1833         {
1834             //don't log it.
1835         }
1836 
1837         return sb.toString();
1838     }
1839 
1840     /**
1841      * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
1842      */
1843     @Deprecated
1844     public void writeModel( Writer writer )
1845         throws IOException
1846     {
1847         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1848         pomWriter.write( writer, getModel() );
1849     }
1850 
1851     /**
1852      * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
1853      */
1854     @Deprecated
1855     public void writeOriginalModel( Writer writer )
1856         throws IOException
1857     {
1858         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1859         pomWriter.write( writer, getOriginalModel() );
1860     }
1861 
1862     /**
1863      * @throws CloneNotSupportedException
1864      * @since 2.0.9
1865      */
1866     @Override
1867     public MavenProject clone()
1868     {
1869         MavenProject clone;
1870         try
1871         {
1872             clone = (MavenProject) super.clone();
1873         }
1874         catch ( CloneNotSupportedException e )
1875         {
1876             throw new UnsupportedOperationException( e );
1877         }
1878 
1879         clone.deepCopy( this );
1880 
1881         return clone;
1882     }
1883 
1884     protected void setModel( Model model )
1885     {
1886         this.model = model;
1887     }
1888 
1889     protected void setAttachedArtifacts( List<Artifact> attachedArtifacts )
1890     {
1891         this.attachedArtifacts = attachedArtifacts;
1892     }
1893 
1894     protected void setCompileSourceRoots( List<String> compileSourceRoots )
1895     {
1896         this.compileSourceRoots = compileSourceRoots;
1897     }
1898 
1899     protected void setTestCompileSourceRoots( List<String> testCompileSourceRoots )
1900     {
1901         this.testCompileSourceRoots = testCompileSourceRoots;
1902     }
1903 
1904     protected void setScriptSourceRoots( List<String> scriptSourceRoots )
1905     {
1906         this.scriptSourceRoots = scriptSourceRoots;
1907     }
1908 
1909     protected ArtifactRepository getReleaseArtifactRepository()
1910     {
1911         if ( releaseArtifactRepository == null && getDistributionManagement() != null
1912             && getDistributionManagement().getRepository() != null )
1913         {
1914             checkProjectBuildingRequest();
1915             try
1916             {
1917                 ArtifactRepository repo =
1918                     repositorySystem.buildArtifactRepository( getDistributionManagement().getRepository() );
1919                 repositorySystem.injectProxy( projectBuilderConfiguration.getRepositorySession(), Arrays.asList( repo ) );
1920                 repositorySystem.injectAuthentication( projectBuilderConfiguration.getRepositorySession(),
1921                                                        Arrays.asList( repo ) );
1922                 setReleaseArtifactRepository( repo );
1923             }
1924             catch ( InvalidRepositoryException e )
1925             {
1926                 throw new IllegalStateException( "Failed to create release distribution repository for " + getId(), e );
1927             }
1928         }
1929 
1930         return releaseArtifactRepository;
1931     }
1932 
1933     protected ArtifactRepository getSnapshotArtifactRepository()
1934     {
1935         if ( snapshotArtifactRepository == null && getDistributionManagement() != null
1936             && getDistributionManagement().getSnapshotRepository() != null )
1937         {
1938             checkProjectBuildingRequest();
1939             try
1940             {
1941                 ArtifactRepository repo =
1942                     repositorySystem.buildArtifactRepository( getDistributionManagement().getSnapshotRepository() );
1943                 repositorySystem.injectProxy( projectBuilderConfiguration.getRepositorySession(), Arrays.asList( repo ) );
1944                 repositorySystem.injectAuthentication( projectBuilderConfiguration.getRepositorySession(),
1945                                                        Arrays.asList( repo ) );
1946                 setSnapshotArtifactRepository( repo );
1947             }
1948             catch ( InvalidRepositoryException e )
1949             {
1950                 throw new IllegalStateException( "Failed to create snapshot distribution repository for " + getId(), e );
1951             }
1952         }
1953 
1954         return snapshotArtifactRepository;
1955     }
1956 
1957     @Deprecated
1958     public Artifact replaceWithActiveArtifact( Artifact pluginArtifact )
1959     {
1960         return pluginArtifact;
1961     }
1962 
1963     private void deepCopy( MavenProject project )
1964     {
1965         // disown the parent
1966 
1967         // copy fields
1968         setFile( project.getFile() );
1969 
1970         // don't need a deep copy, they don't get modified or added/removed to/from - but make them unmodifiable to be
1971         // sure!
1972         if ( project.getDependencyArtifacts() != null )
1973         {
1974             setDependencyArtifacts( Collections.unmodifiableSet( project.getDependencyArtifacts() ) );
1975         }
1976 
1977         if ( project.getArtifacts() != null )
1978         {
1979             setArtifacts( Collections.unmodifiableSet( project.getArtifacts() ) );
1980         }
1981 
1982         if ( project.getParentFile() != null )
1983         {
1984             parentFile = new File( project.getParentFile().getAbsolutePath() );
1985         }
1986 
1987         if ( project.getPluginArtifacts() != null )
1988         {
1989             setPluginArtifacts( Collections.unmodifiableSet( project.getPluginArtifacts() ) );
1990         }
1991 
1992         if ( project.getReportArtifacts() != null )
1993         {
1994             setReportArtifacts( Collections.unmodifiableSet( project.getReportArtifacts() ) );
1995         }
1996 
1997         if ( project.getExtensionArtifacts() != null )
1998         {
1999             setExtensionArtifacts( Collections.unmodifiableSet( project.getExtensionArtifacts() ) );
2000         }
2001 
2002         setParentArtifact( ( project.getParentArtifact() ) );
2003 
2004         if ( project.getRemoteArtifactRepositories() != null )
2005         {
2006             setRemoteArtifactRepositories( Collections.unmodifiableList( project.getRemoteArtifactRepositories() ) );
2007         }
2008 
2009         if ( project.getPluginArtifactRepositories() != null )
2010         {
2011             setPluginArtifactRepositories( ( Collections.unmodifiableList( project.getPluginArtifactRepositories() ) ) );
2012         }
2013 
2014         if ( project.getActiveProfiles() != null )
2015         {
2016             setActiveProfiles( ( Collections.unmodifiableList( project.getActiveProfiles() ) ) );
2017         }
2018 
2019         if ( project.getAttachedArtifacts() != null )
2020         {
2021             // clone properties modifyable by plugins in a forked lifecycle
2022             setAttachedArtifacts( new ArrayList<Artifact>( project.getAttachedArtifacts() ) );
2023         }
2024 
2025         if ( project.getCompileSourceRoots() != null )
2026         {
2027             // clone source roots
2028             setCompileSourceRoots( ( new ArrayList<String>( project.getCompileSourceRoots() ) ) );
2029         }
2030 
2031         if ( project.getTestCompileSourceRoots() != null )
2032         {
2033             setTestCompileSourceRoots( ( new ArrayList<String>( project.getTestCompileSourceRoots() ) ) );
2034         }
2035 
2036         if ( project.getScriptSourceRoots() != null )
2037         {
2038             setScriptSourceRoots( ( new ArrayList<String>( project.getScriptSourceRoots() ) ) );
2039         }
2040 
2041         if ( project.getModel() != null )
2042         {
2043             setModel( project.getModel().clone() );
2044         }
2045 
2046         if ( project.getOriginalModel() != null )
2047         {
2048             setOriginalModel( project.getOriginalModel() );
2049         }
2050 
2051         setExecutionRoot( project.isExecutionRoot() );
2052 
2053         if ( project.getArtifact() != null )
2054         {
2055             setArtifact( ArtifactUtils.copyArtifact( project.getArtifact() ) );
2056         }
2057 
2058         if ( project.getManagedVersionMap() != null )
2059         {
2060             setManagedVersionMap( new HashMap<String, Artifact>( project.getManagedVersionMap() ) );
2061         }
2062 
2063         lifecyclePhases.addAll( project.lifecyclePhases );
2064     }
2065 
2066     private void addArtifactPath( Artifact artifact, List<String> classpath )
2067     {
2068         File file = artifact.getFile();
2069         if ( file != null )
2070         {
2071             classpath.add( file.getPath() );
2072         }
2073     }
2074 
2075     private static String getProjectReferenceId( String groupId, String artifactId, String version )
2076     {
2077         StringBuilder buffer = new StringBuilder( 128 );
2078         buffer.append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( version );
2079         return buffer.toString();
2080     }
2081 
2082     /**
2083      * Sets the value of the context value of this project identified
2084      * by the given key. If the supplied value is <code>null</code>,
2085      * the context value is removed from this project.
2086      * 
2087      * Context values are intended to allow core extensions to associate
2088      * derived state with project instances. 
2089      */
2090     public void setContextValue( String key, Object value )
2091     {
2092         if ( context == null )
2093         {
2094             context = new HashMap<String, Object>();
2095         }
2096         if ( value != null )
2097         {
2098             context.put( key, value );
2099         }
2100         else
2101         {
2102             context.remove( key );
2103         }
2104     }
2105 
2106     /**
2107      * Returns context value of this project associated with the given key 
2108      * or null if this project has no such value. 
2109      */
2110     public Object getContextValue( String key )
2111     {
2112         if ( context == null )
2113         {
2114             return null;
2115         }
2116         return context.get( key );
2117     }
2118 
2119     /**
2120      * Sets the project's class realm. <strong>Warning:</strong> This is an internal utility method that is only public
2121      * for technical reasons, it is not part of the public API. In particular, this method can be changed or deleted
2122      * without prior notice and must not be used by plugins.
2123      * 
2124      * @param classRealm The class realm hosting the build extensions of this project, may be {@code null}.
2125      */
2126     public void setClassRealm( ClassRealm classRealm )
2127     {
2128         this.classRealm = classRealm;
2129     }
2130 
2131     /**
2132      * Gets the project's class realm. This class realm hosts the build extensions of the project.
2133      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
2134      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
2135      * used by plugins.
2136      * 
2137      * @return The project's class realm or {@code null}.
2138      */
2139     public ClassRealm getClassRealm()
2140     {
2141         return classRealm;
2142     }
2143 
2144     /**
2145      * Sets the artifact filter used to exclude shared extension artifacts from plugin realms. <strong>Warning:</strong>
2146      * This is an internal utility method that is only public for technical reasons, it is not part of the public API.
2147      * In particular, this method can be changed or deleted without prior notice and must not be used by plugins.
2148      * 
2149      * @param extensionDependencyFilter The dependency filter to apply to plugins, may be {@code null}.
2150      */
2151     public void setExtensionDependencyFilter( DependencyFilter extensionDependencyFilter )
2152     {
2153         this.extensionDependencyFilter = extensionDependencyFilter;
2154     }
2155 
2156     /**
2157      * Gets the dependency filter used to exclude shared extension artifacts from plugin realms.
2158      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
2159      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
2160      * used by plugins.
2161      * 
2162      * @return The dependency filter or {@code null}.
2163      */
2164     public DependencyFilter getExtensionDependencyFilter()
2165     {
2166         return extensionDependencyFilter;
2167     }
2168 
2169     /**
2170      * Sets the transitive dependency artifacts that have been resolved/collected for this project.
2171      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
2172      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
2173      * used by plugins.
2174      * 
2175      * @param artifacts The set of artifacts, may be {@code null}.
2176      */
2177     public void setResolvedArtifacts( Set<Artifact> artifacts )
2178     {
2179         this.resolvedArtifacts = ( artifacts != null ) ? artifacts : Collections.<Artifact> emptySet();
2180         this.artifacts = null;
2181         this.artifactMap = null;
2182     }
2183 
2184     /**
2185      * Sets the scope filter to select the artifacts being exposed to the currently executed mojo.
2186      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
2187      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
2188      * used by plugins.
2189      * 
2190      * @param artifactFilter The artifact filter, may be {@code null} to exclude all artifacts.
2191      */
2192     public void setArtifactFilter( ArtifactFilter artifactFilter )
2193     {
2194         this.artifactFilter = artifactFilter;
2195         this.artifacts = null;
2196         this.artifactMap = null;
2197     }
2198 
2199     /**
2200      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
2201      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
2202      * used by plugins.
2203      * 
2204      * @param phase The phase to check for, must not be {@code null}.
2205      * @return {@code true} if the phase has been seen.
2206      */
2207     public boolean hasLifecyclePhase( String phase )
2208     {
2209         return lifecyclePhases.contains( phase );
2210     }
2211 
2212     /**
2213      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
2214      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
2215      * used by plugins.
2216      * 
2217      * @param lifecyclePhase The lifecycle phase to add, must not be {@code null}.
2218      */
2219     public void addLifecyclePhase( String lifecyclePhase )
2220     {
2221         lifecyclePhases.add( lifecyclePhase );
2222     }
2223 
2224     /**
2225      * Gets the project building request from which this project instance was created. <strong>Warning:</strong> This is
2226      * an utility method that is meant to assist integrators of Maven, it must not be used by Maven plugins.
2227      * 
2228      * @return The project building request or {@code null}.
2229      * @since 2.1
2230      */
2231     public ProjectBuildingRequest getProjectBuildingRequest()
2232     {
2233         return projectBuilderConfiguration;
2234     }
2235 
2236     /**
2237      * Sets the project building request from which this project instance was created. <strong>Warning:</strong> This is
2238      * an utility method that is meant to assist integrators of Maven, it must not be used by Maven plugins.
2239      * 
2240      * @param projectBuildingRequest The project building request, may be {@code null}.
2241      * @since 2.1
2242      */
2243     public void setProjectBuildingRequest( ProjectBuildingRequest projectBuildingRequest )
2244     {
2245         projectBuilderConfiguration = projectBuildingRequest;
2246     }
2247 
2248     private void checkProjectBuildingRequest()
2249     {
2250         if ( projectBuilderConfiguration == null )
2251         {
2252             throw new IllegalStateException( "project building request missing" );
2253         }
2254     }
2255 
2256 }