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