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