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