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