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  import org.slf4j.Logger;
76  import org.slf4j.LoggerFactory;
77  
78  /**
79   * The concern of the project is provide runtime values based on the model.
80   * <p>
81   * The values in the model remain untouched but during the process of building a project notions like inheritance and
82   * interpolation can be added. This allows to have an entity which is useful in a runtime while preserving the model so
83   * that it can be marshalled and unmarshalled without being tainted by runtime requirements.
84   * </p>
85   * <p>
86   * With changes during 3.2.2 release MavenProject is closer to being immutable after construction with the removal of
87   * all components from this class, and the upfront construction taken care of entirely by the {@link ProjectBuilder}.
88   * There is still the issue of having to run the lifecycle in order to find all the compile source roots and resource
89   * directories but I hope to take care of this during the Maven 4.0 release (jvz).
90   * </p>
91   */
92  public class MavenProject
93      implements Cloneable
94  {
95      private static final Logger LOGGER = LoggerFactory.getLogger( MavenProject.class );
96      public static final String EMPTY_PROJECT_GROUP_ID = "unknown";
97      public static final String EMPTY_PROJECT_ARTIFACT_ID = "empty-project";
98      public static final String EMPTY_PROJECT_VERSION = "0";
99  
100     private Model model;
101 
102     private MavenProject parent;
103 
104     private File file;
105 
106     private File basedir;
107 
108     private Set<Artifact> resolvedArtifacts;
109 
110     private Artifact parentArtifact;
111 
112     private Set<Artifact> pluginArtifacts;
113 
114     private List<ArtifactRepository> remoteArtifactRepositories;
115 
116     private List<ArtifactRepository> pluginArtifactRepositories;
117 
118     private List<RemoteRepository> remoteProjectRepositories;
119 
120     private List<RemoteRepository> remotePluginRepositories;
121 
122     private List<Artifact> attachedArtifacts = new ArrayList<>();
123 
124     private MavenProject executionProject;
125 
126     private List<MavenProject> collectedProjects;
127 
128     private List<String> compileSourceRoots = new ArrayList<>();
129 
130     private List<String> testCompileSourceRoots = new ArrayList<>();
131 
132     private List<String> scriptSourceRoots = new ArrayList<>();
133 
134     private ArtifactRepository releaseArtifactRepository;
135 
136     private ArtifactRepository snapshotArtifactRepository;
137 
138     private List<Profile> activeProfiles = new ArrayList<>();
139 
140     private Map<String, List<String>> injectedProfileIds = new LinkedHashMap<>();
141 
142     private Set<Artifact> dependencyArtifacts;
143 
144     private Artifact artifact;
145 
146     private final ThreadLocal<ArtifactsHolder> threadLocalArtifactsHolder = new ThreadLocal()
147     {
148         protected ArtifactsHolder initialValue()
149         {
150             return new ArtifactsHolder();
151         }
152     };
153 
154     private Model originalModel;
155 
156     private Map<String, Artifact> pluginArtifactMap;
157 
158     private Set<Artifact> reportArtifacts;
159 
160     private Map<String, Artifact> reportArtifactMap;
161 
162     private Set<Artifact> extensionArtifacts;
163 
164     private Map<String, Artifact> extensionArtifactMap;
165 
166     private Map<String, Artifact> managedVersionMap;
167 
168     private Map<String, MavenProject> projectReferences = new HashMap<>();
169 
170     private boolean executionRoot;
171 
172     private File parentFile;
173 
174     private Map<String, Object> context;
175 
176     private ClassRealm classRealm;
177 
178     private DependencyFilter extensionDependencyFilter;
179 
180     private final Set<String> lifecyclePhases = Collections.synchronizedSet( new LinkedHashSet<String>() );
181 
182     public MavenProject()
183     {
184         Model model = new Model();
185         model.setGroupId( EMPTY_PROJECT_GROUP_ID );
186         model.setArtifactId( EMPTY_PROJECT_ARTIFACT_ID );
187         model.setVersion( EMPTY_PROJECT_VERSION );
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         ArtifactsHolder artifactsHolder = threadLocalArtifactsHolder.get();
694         artifactsHolder.artifacts = artifacts;
695 
696         // flush the calculated artifactMap
697         artifactsHolder.artifactMap = null;
698     }
699 
700     /**
701      * All dependencies that this project has, including transitive ones. Contents are lazily populated, so depending on
702      * what phases have run dependencies in some scopes won't be included. eg. if only compile phase has run,
703      * dependencies with scope test won't be included.
704      *
705      * @return {@link Set} &lt; {@link Artifact} &gt;
706      * @see #getDependencyArtifacts() to get only direct dependencies
707      */
708     public Set<Artifact> getArtifacts()
709     {
710         ArtifactsHolder artifactsHolder = threadLocalArtifactsHolder.get();
711         if ( artifactsHolder.artifacts == null )
712         {
713             if ( artifactsHolder.artifactFilter == null || resolvedArtifacts == null )
714             {
715                 artifactsHolder.artifacts = new LinkedHashSet<>();
716             }
717             else
718             {
719                 artifactsHolder.artifacts = new LinkedHashSet<>( resolvedArtifacts.size() * 2 );
720                 for ( Artifact artifact : resolvedArtifacts )
721                 {
722                     if ( artifactsHolder.artifactFilter.include( artifact ) )
723                     {
724                         artifactsHolder.artifacts.add( artifact );
725                     }
726                 }
727             }
728         }
729         return artifactsHolder.artifacts;
730     }
731 
732     public Map<String, Artifact> getArtifactMap()
733     {
734         ArtifactsHolder artifactsHolder = threadLocalArtifactsHolder.get();
735         if ( artifactsHolder.artifactMap == null )
736         {
737             artifactsHolder.artifactMap = ArtifactUtils.artifactMapByVersionlessId( getArtifacts() );
738         }
739         return artifactsHolder.artifactMap;
740     }
741 
742     public void setPluginArtifacts( Set<Artifact> pluginArtifacts )
743     {
744         this.pluginArtifacts = pluginArtifacts;
745 
746         this.pluginArtifactMap = null;
747     }
748 
749     public Set<Artifact> getPluginArtifacts()
750     {
751         return pluginArtifacts;
752     }
753 
754     public Map<String, Artifact> getPluginArtifactMap()
755     {
756         if ( pluginArtifactMap == null )
757         {
758             pluginArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getPluginArtifacts() );
759         }
760 
761         return pluginArtifactMap;
762     }
763 
764     public void setParentArtifact( Artifact parentArtifact )
765     {
766         this.parentArtifact = parentArtifact;
767     }
768 
769     public Artifact getParentArtifact()
770     {
771         return parentArtifact;
772     }
773 
774     public List<Repository> getRepositories()
775     {
776         return getModel().getRepositories();
777     }
778 
779     // ----------------------------------------------------------------------
780     // Plugins
781     // ----------------------------------------------------------------------
782 
783     public List<Plugin> getBuildPlugins()
784     {
785         if ( getModel().getBuild() == null )
786         {
787             return Collections.emptyList();
788         }
789         return Collections.unmodifiableList( getModel().getBuild().getPlugins() );
790     }
791 
792     public List<String> getModules()
793     {
794         return getModel().getModules();
795     }
796 
797     public PluginManagement getPluginManagement()
798     {
799         PluginManagement pluginMgmt = null;
800 
801         Build build = getModel().getBuild();
802         if ( build != null )
803         {
804             pluginMgmt = build.getPluginManagement();
805         }
806 
807         return pluginMgmt;
808     }
809 
810     private Build getModelBuild()
811     {
812         Build build = getModel().getBuild();
813 
814         if ( build == null )
815         {
816             build = new Build();
817 
818             getModel().setBuild( build );
819         }
820 
821         return build;
822     }
823 
824     public void setRemoteArtifactRepositories( List<ArtifactRepository> remoteArtifactRepositories )
825     {
826         this.remoteArtifactRepositories = remoteArtifactRepositories;
827         this.remoteProjectRepositories = RepositoryUtils.toRepos( getRemoteArtifactRepositories() );
828     }
829 
830     public List<ArtifactRepository> getRemoteArtifactRepositories()
831     {
832         if ( remoteArtifactRepositories == null )
833         {
834             remoteArtifactRepositories = new ArrayList<>();
835         }
836 
837         return remoteArtifactRepositories;
838     }
839 
840     public void setPluginArtifactRepositories( List<ArtifactRepository> pluginArtifactRepositories )
841     {
842         this.pluginArtifactRepositories = pluginArtifactRepositories;
843         this.remotePluginRepositories = RepositoryUtils.toRepos( getPluginArtifactRepositories() );
844     }
845 
846     /**
847      * @return a list of ArtifactRepository objects constructed from the Repository objects returned by
848      *         getPluginRepositories.
849      */
850     public List<ArtifactRepository> getPluginArtifactRepositories()
851     {
852         if ( pluginArtifactRepositories == null )
853         {
854             pluginArtifactRepositories = new ArrayList<>();
855         }
856 
857         return pluginArtifactRepositories;
858     }
859 
860     public ArtifactRepository getDistributionManagementArtifactRepository()
861     {
862         return getArtifact().isSnapshot() && ( getSnapshotArtifactRepository() != null )
863                         ? getSnapshotArtifactRepository()
864                         : getReleaseArtifactRepository();
865     }
866 
867     public List<Repository> getPluginRepositories()
868     {
869         return getModel().getPluginRepositories();
870     }
871 
872     public List<RemoteRepository> getRemoteProjectRepositories()
873     {
874         return remoteProjectRepositories;
875     }
876 
877     public List<RemoteRepository> getRemotePluginRepositories()
878     {
879         return remotePluginRepositories;
880     }
881 
882     public void setActiveProfiles( List<Profile> activeProfiles )
883     {
884         this.activeProfiles = activeProfiles;
885     }
886 
887     public List<Profile> getActiveProfiles()
888     {
889         return activeProfiles;
890     }
891 
892     public void setInjectedProfileIds( String source, List<String> injectedProfileIds )
893     {
894         if ( injectedProfileIds != null )
895         {
896             this.injectedProfileIds.put( source, new ArrayList<>( injectedProfileIds ) );
897         }
898         else
899         {
900             this.injectedProfileIds.remove( source );
901         }
902     }
903 
904     /**
905      * Gets the identifiers of all profiles that contributed to this project's effective model. This includes active
906      * profiles from the project's POM and all its parent POMs as well as from external sources like the
907      * {@code settings.xml}. The profile identifiers are grouped by the identifier of their source, e.g.
908      * {@code <groupId>:<artifactId>:<version>} for a POM profile or {@code external} for profiles from the
909      * {@code settings.xml}.
910      *
911      * @return The identifiers of all injected profiles, indexed by the source from which the profiles originated, never
912      *         {@code null}.
913      */
914     public Map<String, List<String>> getInjectedProfileIds()
915     {
916         return this.injectedProfileIds;
917     }
918 
919     /**
920      * Add or replace an artifact. This method is now deprecated. Use the @{MavenProjectHelper} to attach artifacts to a
921      * project. In spite of the 'throws' declaration on this API, this method has never thrown an exception since Maven
922      * 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
923      * the artifact, so that plugins (e.g. shade) can change the pathname of the file for a particular set of
924      * coordinates.
925      *
926      * @param artifact the artifact to add or replace.
927      * @deprecated Please use {@link MavenProjectHelper}
928      * @throws DuplicateArtifactAttachmentException will never happen but leave it for backward compatibility
929      */
930     public void addAttachedArtifact( Artifact artifact )
931         throws DuplicateArtifactAttachmentException
932     {
933         // if already there we remove it and add again
934         int index = attachedArtifacts.indexOf( artifact );
935         if ( index >= 0 )
936         {
937             LOGGER.warn( "artifact {} already attached, replace previous instance", artifact );
938             attachedArtifacts.set( index, artifact );
939         }
940         else
941         {
942             attachedArtifacts.add( artifact );
943         }
944     }
945 
946     public List<Artifact> getAttachedArtifacts()
947     {
948         if ( attachedArtifacts == null )
949         {
950             attachedArtifacts = new ArrayList<>();
951         }
952         return Collections.unmodifiableList( attachedArtifacts );
953     }
954 
955     public Xpp3Dom getGoalConfiguration( String pluginGroupId, String pluginArtifactId, String executionId,
956                                          String goalId )
957     {
958         Xpp3Dom dom = null;
959 
960         if ( getBuildPlugins() != null )
961         {
962             for ( Plugin plugin : getBuildPlugins() )
963             {
964                 if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
965                 {
966                     dom = (Xpp3Dom) plugin.getConfiguration();
967 
968                     if ( executionId != null )
969                     {
970                         PluginExecution execution = plugin.getExecutionsAsMap().get( executionId );
971                         if ( execution != null )
972                         {
973                             // NOTE: The PluginConfigurationExpander already merged the plugin-level config in
974                             dom = (Xpp3Dom) execution.getConfiguration();
975                         }
976                     }
977                     break;
978                 }
979             }
980         }
981 
982         if ( dom != null )
983         {
984             // make a copy so the original in the POM doesn't get messed with
985             dom = new Xpp3Dom( dom );
986         }
987 
988         return dom;
989     }
990 
991     public MavenProject getExecutionProject()
992     {
993         return ( executionProject == null ? this : executionProject );
994     }
995 
996     public void setExecutionProject( MavenProject executionProject )
997     {
998         this.executionProject = executionProject;
999     }
1000 
1001     public List<MavenProject> getCollectedProjects()
1002     {
1003         return collectedProjects;
1004     }
1005 
1006     public void setCollectedProjects( List<MavenProject> collectedProjects )
1007     {
1008         this.collectedProjects = collectedProjects;
1009     }
1010 
1011     /**
1012      * Direct dependencies that this project has.
1013      *
1014      * @return {@link Set} &lt; {@link Artifact} &gt;
1015      * @see #getArtifacts() to get all transitive dependencies
1016      */
1017     @Deprecated
1018     public Set<Artifact> getDependencyArtifacts()
1019     {
1020         return dependencyArtifacts;
1021     }
1022 
1023     @Deprecated
1024     public void setDependencyArtifacts( Set<Artifact> dependencyArtifacts )
1025     {
1026         this.dependencyArtifacts = dependencyArtifacts;
1027     }
1028 
1029     public void setReleaseArtifactRepository( ArtifactRepository releaseArtifactRepository )
1030     {
1031         this.releaseArtifactRepository = releaseArtifactRepository;
1032     }
1033 
1034     public void setSnapshotArtifactRepository( ArtifactRepository snapshotArtifactRepository )
1035     {
1036         this.snapshotArtifactRepository = snapshotArtifactRepository;
1037     }
1038 
1039     public void setOriginalModel( Model originalModel )
1040     {
1041         this.originalModel = originalModel;
1042     }
1043 
1044     public Model getOriginalModel()
1045     {
1046         return originalModel;
1047     }
1048 
1049     public void setManagedVersionMap( Map<String, Artifact> map )
1050     {
1051         managedVersionMap = map;
1052     }
1053 
1054     public Map<String, Artifact> getManagedVersionMap()
1055     {
1056         return managedVersionMap;
1057     }
1058 
1059     @Override
1060     public boolean equals( Object other )
1061     {
1062         if ( other == this )
1063         {
1064             return true;
1065         }
1066         else if ( !( other instanceof MavenProject ) )
1067         {
1068             return false;
1069         }
1070 
1071         MavenProject that = (MavenProject) other;
1072 
1073         return Objects.equals( getArtifactId(), that.getArtifactId() )
1074             && Objects.equals( getGroupId(), that.getGroupId() ) 
1075             && Objects.equals( getVersion(), that.getVersion() );
1076     }
1077 
1078     @Override
1079     public int hashCode()
1080     {
1081         int hash = 17;
1082         hash = 31 * hash + getGroupId().hashCode();
1083         hash = 31 * hash + getArtifactId().hashCode();
1084         hash = 31 * hash + getVersion().hashCode();
1085         return hash;
1086     }
1087 
1088     public List<Extension> getBuildExtensions()
1089     {
1090         Build build = getBuild();
1091         if ( ( build == null ) || ( build.getExtensions() == null ) )
1092         {
1093             return Collections.emptyList();
1094         }
1095         else
1096         {
1097             return Collections.unmodifiableList( build.getExtensions() );
1098         }
1099     }
1100 
1101     public void addProjectReference( MavenProject project )
1102     {
1103         projectReferences.put( getProjectReferenceId( project.getGroupId(), project.getArtifactId(),
1104                                                       project.getVersion() ), project );
1105     }
1106 
1107     public Properties getProperties()
1108     {
1109         return getModel().getProperties();
1110     }
1111 
1112     public List<String> getFilters()
1113     {
1114         return getBuild().getFilters();
1115     }
1116 
1117     public Map<String, MavenProject> getProjectReferences()
1118     {
1119         return projectReferences;
1120     }
1121 
1122     public boolean isExecutionRoot()
1123     {
1124         return executionRoot;
1125     }
1126 
1127     public void setExecutionRoot( boolean executionRoot )
1128     {
1129         this.executionRoot = executionRoot;
1130     }
1131 
1132     public String getDefaultGoal()
1133     {
1134         return getBuild() != null ? getBuild().getDefaultGoal() : null;
1135     }
1136 
1137     public Plugin getPlugin( String pluginKey )
1138     {
1139         return getBuild().getPluginsAsMap().get( pluginKey );
1140     }
1141 
1142     /**
1143      * Default toString
1144      */
1145     @Override
1146     public String toString()
1147     {
1148         StringBuilder sb = new StringBuilder( 128 );
1149         sb.append( "MavenProject: " );
1150         sb.append( getGroupId() );
1151         sb.append( ':' );
1152         sb.append( getArtifactId() );
1153         sb.append( ':' );
1154         sb.append( getVersion() );
1155         sb.append( " @ " );
1156 
1157         try
1158         {
1159             sb.append( getFile().getPath() );
1160         }
1161         catch ( NullPointerException e )
1162         {
1163             // don't log it.
1164         }
1165 
1166         return sb.toString();
1167     }
1168 
1169     /**
1170      * @since 2.0.9
1171      */
1172     @Override
1173     public MavenProject clone()
1174     {
1175         MavenProject clone;
1176         try
1177         {
1178             clone = (MavenProject) super.clone();
1179         }
1180         catch ( CloneNotSupportedException e )
1181         {
1182             throw new UnsupportedOperationException( e );
1183         }
1184 
1185         clone.deepCopy( this );
1186 
1187         return clone;
1188     }
1189 
1190     public void setModel( Model model )
1191     {
1192         this.model = model;
1193     }
1194 
1195     protected void setAttachedArtifacts( List<Artifact> attachedArtifacts )
1196     {
1197         this.attachedArtifacts = attachedArtifacts;
1198     }
1199 
1200     protected void setCompileSourceRoots( List<String> compileSourceRoots )
1201     {
1202         this.compileSourceRoots = compileSourceRoots;
1203     }
1204 
1205     protected void setTestCompileSourceRoots( List<String> testCompileSourceRoots )
1206     {
1207         this.testCompileSourceRoots = testCompileSourceRoots;
1208     }
1209 
1210     protected ArtifactRepository getReleaseArtifactRepository()
1211     {
1212         return releaseArtifactRepository;
1213     }
1214 
1215     protected ArtifactRepository getSnapshotArtifactRepository()
1216     {
1217         return snapshotArtifactRepository;
1218     }
1219 
1220     private void deepCopy( MavenProject project )
1221     {
1222         // disown the parent
1223 
1224         // copy fields
1225         file = project.file;
1226         basedir = project.basedir;
1227 
1228         // don't need a deep copy, they don't get modified or added/removed to/from - but make them unmodifiable to be
1229         // sure!
1230         if ( project.getDependencyArtifacts() != null )
1231         {
1232             setDependencyArtifacts( Collections.unmodifiableSet( project.getDependencyArtifacts() ) );
1233         }
1234 
1235         if ( project.getArtifacts() != null )
1236         {
1237             setArtifacts( Collections.unmodifiableSet( project.getArtifacts() ) );
1238         }
1239 
1240         if ( project.getParentFile() != null )
1241         {
1242             parentFile = new File( project.getParentFile().getAbsolutePath() );
1243         }
1244 
1245         if ( project.getPluginArtifacts() != null )
1246         {
1247             setPluginArtifacts( Collections.unmodifiableSet( project.getPluginArtifacts() ) );
1248         }
1249 
1250         if ( project.getReportArtifacts() != null )
1251         {
1252             setReportArtifacts( Collections.unmodifiableSet( project.getReportArtifacts() ) );
1253         }
1254 
1255         if ( project.getExtensionArtifacts() != null )
1256         {
1257             setExtensionArtifacts( Collections.unmodifiableSet( project.getExtensionArtifacts() ) );
1258         }
1259 
1260         setParentArtifact( ( project.getParentArtifact() ) );
1261 
1262         if ( project.getRemoteArtifactRepositories() != null )
1263         {
1264             setRemoteArtifactRepositories( Collections.unmodifiableList( project.getRemoteArtifactRepositories() ) );
1265         }
1266 
1267         if ( project.getPluginArtifactRepositories() != null )
1268         {
1269             setPluginArtifactRepositories( Collections.unmodifiableList( project.getPluginArtifactRepositories() ) );
1270         }
1271 
1272         if ( project.getActiveProfiles() != null )
1273         {
1274             setActiveProfiles( ( Collections.unmodifiableList( project.getActiveProfiles() ) ) );
1275         }
1276 
1277         if ( project.getAttachedArtifacts() != null )
1278         {
1279             // clone properties modifyable by plugins in a forked lifecycle
1280             setAttachedArtifacts( new ArrayList<>( project.getAttachedArtifacts() ) );
1281         }
1282 
1283         if ( project.getCompileSourceRoots() != null )
1284         {
1285             // clone source roots
1286             setCompileSourceRoots( ( new ArrayList<>( project.getCompileSourceRoots() ) ) );
1287         }
1288 
1289         if ( project.getTestCompileSourceRoots() != null )
1290         {
1291             setTestCompileSourceRoots( ( new ArrayList<>( project.getTestCompileSourceRoots() ) ) );
1292         }
1293 
1294         if ( project.getScriptSourceRoots() != null )
1295         {
1296             setScriptSourceRoots( ( new ArrayList<>( project.getScriptSourceRoots() ) ) );
1297         }
1298 
1299         if ( project.getModel() != null )
1300         {
1301             setModel( project.getModel().clone() );
1302         }
1303 
1304         if ( project.getOriginalModel() != null )
1305         {
1306             setOriginalModel( project.getOriginalModel() );
1307         }
1308 
1309         setExecutionRoot( project.isExecutionRoot() );
1310 
1311         if ( project.getArtifact() != null )
1312         {
1313             setArtifact( ArtifactUtils.copyArtifact( project.getArtifact() ) );
1314         }
1315 
1316         if ( project.getManagedVersionMap() != null )
1317         {
1318             setManagedVersionMap( project.getManagedVersionMap() );
1319         }
1320 
1321         lifecyclePhases.addAll( project.lifecyclePhases );
1322     }
1323 
1324     private void addArtifactPath( Artifact artifact, List<String> classpath )
1325     {
1326         File file = artifact.getFile();
1327         if ( file != null )
1328         {
1329             classpath.add( file.getPath() );
1330         }
1331     }
1332 
1333     private static String getProjectReferenceId( String groupId, String artifactId, String version )
1334     {
1335         StringBuilder buffer = new StringBuilder( 128 );
1336         buffer.append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( version );
1337         return buffer.toString();
1338     }
1339 
1340     /**
1341      * Sets the value of the context value of this project identified by the given key. If the supplied value is
1342      * <code>null</code>, the context value is removed from this project. Context values are intended to allow core
1343      * extensions to associate derived state with project instances.
1344      */
1345     public void setContextValue( String key, Object value )
1346     {
1347         if ( context == null )
1348         {
1349             context = new HashMap<>();
1350         }
1351         if ( value != null )
1352         {
1353             context.put( key, value );
1354         }
1355         else
1356         {
1357             context.remove( key );
1358         }
1359     }
1360 
1361     /**
1362      * Returns context value of this project associated with the given key or null if this project has no such value.
1363      */
1364     public Object getContextValue( String key )
1365     {
1366         if ( context == null )
1367         {
1368             return null;
1369         }
1370         return context.get( key );
1371     }
1372 
1373     /**
1374      * Sets the project's class realm. <strong>Warning:</strong> This is an internal utility method that is only public
1375      * for technical reasons, it is not part of the public API. In particular, this method can be changed or deleted
1376      * without prior notice and must not be used by plugins.
1377      *
1378      * @param classRealm The class realm hosting the build extensions of this project, may be {@code null}.
1379      */
1380     public void setClassRealm( ClassRealm classRealm )
1381     {
1382         this.classRealm = classRealm;
1383     }
1384 
1385     /**
1386      * Gets the project's class realm. This class realm hosts the build extensions of the project.
1387      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1388      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1389      * used by plugins.
1390      *
1391      * @return The project's class realm or {@code null}.
1392      */
1393     public ClassRealm getClassRealm()
1394     {
1395         return classRealm;
1396     }
1397 
1398     /**
1399      * Sets the artifact filter used to exclude shared extension artifacts from plugin realms. <strong>Warning:</strong>
1400      * This is an internal utility method that is only public for technical reasons, it is not part of the public API.
1401      * In particular, this method can be changed or deleted without prior notice and must not be used by plugins.
1402      *
1403      * @param extensionDependencyFilter The dependency filter to apply to plugins, may be {@code null}.
1404      */
1405     public void setExtensionDependencyFilter( DependencyFilter extensionDependencyFilter )
1406     {
1407         this.extensionDependencyFilter = extensionDependencyFilter;
1408     }
1409 
1410     /**
1411      * Gets the dependency filter used to exclude shared extension artifacts from plugin realms.
1412      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1413      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1414      * used by plugins.
1415      *
1416      * @return The dependency filter or {@code null}.
1417      */
1418     public DependencyFilter getExtensionDependencyFilter()
1419     {
1420         return extensionDependencyFilter;
1421     }
1422 
1423     /**
1424      * Sets the transitive dependency artifacts that have been resolved/collected for this project.
1425      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1426      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1427      * used by plugins.
1428      *
1429      * @param artifacts The set of artifacts, may be {@code null}.
1430      */
1431     public void setResolvedArtifacts( Set<Artifact> artifacts )
1432     {
1433         this.resolvedArtifacts = ( artifacts != null ) ? artifacts : Collections.<Artifact>emptySet();
1434         ArtifactsHolder artifactsHolder = threadLocalArtifactsHolder.get();
1435         artifactsHolder.artifacts = null;
1436         artifactsHolder.artifactMap = null;
1437     }
1438 
1439     /**
1440      * Sets the scope filter to select the artifacts being exposed to the currently executed mojo.
1441      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1442      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1443      * used by plugins.
1444      *
1445      * @param artifactFilter The artifact filter, may be {@code null} to exclude all artifacts.
1446      */
1447     public void setArtifactFilter( ArtifactFilter artifactFilter )
1448     {
1449         ArtifactsHolder artifactsHolder = threadLocalArtifactsHolder.get();
1450         artifactsHolder.artifactFilter = artifactFilter;
1451         artifactsHolder.artifacts = null;
1452         artifactsHolder.artifactMap = null;
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 phase The phase to check for, must not be {@code null}.
1461      * @return {@code true} if the phase has been seen.
1462      */
1463     public boolean hasLifecyclePhase( String phase )
1464     {
1465         return lifecyclePhases.contains( phase );
1466     }
1467 
1468     /**
1469      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1470      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1471      * used by plugins.
1472      *
1473      * @param lifecyclePhase The lifecycle phase to add, must not be {@code null}.
1474      */
1475     public void addLifecyclePhase( String lifecyclePhase )
1476     {
1477         lifecyclePhases.add( lifecyclePhase );
1478     }
1479 
1480     // ----------------------------------------------------------------------------------------------------------------
1481     //
1482     //
1483     // D E P R E C A T E D
1484     //
1485     //
1486     // ----------------------------------------------------------------------------------------------------------------
1487     //
1488     // Everything below will be removed for Maven 4.0.0
1489     //
1490     // ----------------------------------------------------------------------------------------------------------------
1491 
1492     private ProjectBuildingRequest projectBuilderConfiguration;
1493 
1494     private Map<String, String> moduleAdjustments;
1495 
1496     @Deprecated // This appears only to be used in test code
1497     public String getModulePathAdjustment( MavenProject moduleProject )
1498         throws IOException
1499     {
1500         // FIXME: This is hacky. What if module directory doesn't match artifactid, and parent
1501         // is coming from the repository??
1502         String module = moduleProject.getArtifactId();
1503 
1504         File moduleFile = moduleProject.getFile();
1505 
1506         if ( moduleFile != null )
1507         {
1508             File moduleDir = moduleFile.getCanonicalFile().getParentFile();
1509 
1510             module = moduleDir.getName();
1511         }
1512 
1513         if ( moduleAdjustments == null )
1514         {
1515             moduleAdjustments = new HashMap<>();
1516 
1517             List<String> modules = getModules();
1518             if ( modules != null )
1519             {
1520                 for ( String modulePath : modules )
1521                 {
1522                     String moduleName = modulePath;
1523 
1524                     if ( moduleName.endsWith( "/" ) || moduleName.endsWith( "\\" ) )
1525                     {
1526                         moduleName = moduleName.substring( 0, moduleName.length() - 1 );
1527                     }
1528 
1529                     int lastSlash = moduleName.lastIndexOf( '/' );
1530 
1531                     if ( lastSlash < 0 )
1532                     {
1533                         lastSlash = moduleName.lastIndexOf( '\\' );
1534                     }
1535 
1536                     String adjustment = null;
1537 
1538                     if ( lastSlash > -1 )
1539                     {
1540                         moduleName = moduleName.substring( lastSlash + 1 );
1541                         adjustment = modulePath.substring( 0, lastSlash );
1542                     }
1543 
1544                     moduleAdjustments.put( moduleName, adjustment );
1545                 }
1546             }
1547         }
1548 
1549         return moduleAdjustments.get( module );
1550     }
1551 
1552     @Deprecated
1553     public Set<Artifact> createArtifacts( ArtifactFactory artifactFactory, String inheritedScope,
1554                                           ArtifactFilter filter )
1555         throws InvalidDependencyVersionException
1556     {
1557         return MavenMetadataSource.createArtifacts( artifactFactory, getDependencies(), inheritedScope, filter, this );
1558     }
1559 
1560     @Deprecated
1561     protected void setScriptSourceRoots( List<String> scriptSourceRoots )
1562     {
1563         this.scriptSourceRoots = scriptSourceRoots;
1564     }
1565 
1566     @Deprecated
1567     public void addScriptSourceRoot( String path )
1568     {
1569         if ( path != null )
1570         {
1571             path = path.trim();
1572             if ( path.length() != 0 )
1573             {
1574                 if ( !getScriptSourceRoots().contains( path ) )
1575                 {
1576                     getScriptSourceRoots().add( path );
1577                 }
1578             }
1579         }
1580     }
1581 
1582     @Deprecated
1583     public List<String> getScriptSourceRoots()
1584     {
1585         return scriptSourceRoots;
1586     }
1587 
1588     @Deprecated
1589     public List<Artifact> getCompileArtifacts()
1590     {
1591         List<Artifact> list = new ArrayList<>( getArtifacts().size() );
1592 
1593         for ( Artifact a : getArtifacts() )
1594         {
1595             // TODO classpath check doesn't belong here - that's the other method
1596             if ( a.getArtifactHandler().isAddedToClasspath() )
1597             {
1598                 // TODO let the scope handler deal with this
1599                 if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
1600                     || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
1601                 {
1602                     list.add( a );
1603                 }
1604             }
1605         }
1606         return list;
1607     }
1608 
1609     @Deprecated
1610     public List<Dependency> getCompileDependencies()
1611     {
1612         Set<Artifact> artifacts = getArtifacts();
1613 
1614         if ( ( artifacts == null ) || artifacts.isEmpty() )
1615         {
1616             return Collections.emptyList();
1617         }
1618 
1619         List<Dependency> list = new ArrayList<>( artifacts.size() );
1620 
1621         for ( Artifact a : getArtifacts() )
1622         {
1623             // TODO let the scope handler deal with this
1624             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
1625                      || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
1626             {
1627                 Dependency dependency = new Dependency();
1628 
1629                 dependency.setArtifactId( a.getArtifactId() );
1630                 dependency.setGroupId( a.getGroupId() );
1631                 dependency.setVersion( a.getVersion() );
1632                 dependency.setScope( a.getScope() );
1633                 dependency.setType( a.getType() );
1634                 dependency.setClassifier( a.getClassifier() );
1635 
1636                 list.add( dependency );
1637             }
1638         }
1639         return Collections.unmodifiableList( list );
1640     }
1641 
1642     @Deprecated
1643     public List<Artifact> getTestArtifacts()
1644     {
1645         List<Artifact> list = new ArrayList<>( getArtifacts().size() );
1646 
1647         for ( Artifact a : getArtifacts() )
1648         {
1649             // TODO classpath check doesn't belong here - that's the other method
1650             if ( a.getArtifactHandler().isAddedToClasspath() )
1651             {
1652                 list.add( a );
1653             }
1654         }
1655         return list;
1656     }
1657 
1658     @Deprecated
1659     public List<Dependency> getTestDependencies()
1660     {
1661         Set<Artifact> artifacts = getArtifacts();
1662 
1663         if ( ( artifacts == null ) || artifacts.isEmpty() )
1664         {
1665             return Collections.emptyList();
1666         }
1667 
1668         List<Dependency> list = new ArrayList<>( artifacts.size() );
1669 
1670         for ( Artifact a : getArtifacts() )
1671         {
1672             Dependency dependency = new Dependency();
1673 
1674             dependency.setArtifactId( a.getArtifactId() );
1675             dependency.setGroupId( a.getGroupId() );
1676             dependency.setVersion( a.getVersion() );
1677             dependency.setScope( a.getScope() );
1678             dependency.setType( a.getType() );
1679             dependency.setClassifier( a.getClassifier() );
1680 
1681             list.add( dependency );
1682         }
1683         return Collections.unmodifiableList( list );
1684     }
1685 
1686     @Deprecated // used by the Maven ITs
1687     public List<Dependency> getRuntimeDependencies()
1688     {
1689         Set<Artifact> artifacts = getArtifacts();
1690 
1691         if ( ( artifacts == null ) || artifacts.isEmpty() )
1692         {
1693             return Collections.emptyList();
1694         }
1695 
1696         List<Dependency> list = new ArrayList<>( artifacts.size() );
1697 
1698         for ( Artifact a : getArtifacts() )
1699         {
1700             // TODO let the scope handler deal with this
1701             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
1702             {
1703                 Dependency dependency = new Dependency();
1704 
1705                 dependency.setArtifactId( a.getArtifactId() );
1706                 dependency.setGroupId( a.getGroupId() );
1707                 dependency.setVersion( a.getVersion() );
1708                 dependency.setScope( a.getScope() );
1709                 dependency.setType( a.getType() );
1710                 dependency.setClassifier( a.getClassifier() );
1711 
1712                 list.add( dependency );
1713             }
1714         }
1715         return Collections.unmodifiableList( list );
1716     }
1717 
1718     @Deprecated
1719     public List<Artifact> getRuntimeArtifacts()
1720     {
1721         List<Artifact> list = new ArrayList<>( getArtifacts().size() );
1722 
1723         for ( Artifact a : getArtifacts()  )
1724         {
1725             // TODO classpath check doesn't belong here - that's the other method
1726             if ( a.getArtifactHandler().isAddedToClasspath()
1727             // TODO let the scope handler deal with this
1728                 && ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) ) )
1729             {
1730                 list.add( a );
1731             }
1732         }
1733         return list;
1734     }
1735 
1736     @Deprecated
1737     public List<String> getSystemClasspathElements()
1738         throws DependencyResolutionRequiredException
1739     {
1740         List<String> list = new ArrayList<>( getArtifacts().size() );
1741 
1742         String d = getBuild().getOutputDirectory();
1743         if ( d != null )
1744         {
1745             list.add( d );
1746         }
1747 
1748         for ( Artifact a : getArtifacts() )
1749         {
1750             if ( a.getArtifactHandler().isAddedToClasspath() )
1751             {
1752                 // TODO let the scope handler deal with this
1753                 if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
1754                 {
1755                     addArtifactPath( a, list );
1756                 }
1757             }
1758         }
1759         return list;
1760     }
1761 
1762     @Deprecated
1763     public List<Artifact> getSystemArtifacts()
1764     {
1765         List<Artifact> list = new ArrayList<>( getArtifacts().size() );
1766 
1767         for ( Artifact a : getArtifacts() )
1768         {
1769             // TODO classpath check doesn't belong here - that's the other method
1770             if ( a.getArtifactHandler().isAddedToClasspath() )
1771             {
1772                 // TODO let the scope handler deal with this
1773                 if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
1774                 {
1775                     list.add( a );
1776                 }
1777             }
1778         }
1779         return list;
1780     }
1781 
1782     @Deprecated
1783     public List<Dependency> getSystemDependencies()
1784     {
1785         Set<Artifact> artifacts = getArtifacts();
1786 
1787         if ( ( artifacts == null ) || artifacts.isEmpty() )
1788         {
1789             return Collections.emptyList();
1790         }
1791 
1792         List<Dependency> list = new ArrayList<>( artifacts.size() );
1793 
1794         for ( Artifact a : getArtifacts() )
1795         {
1796             // TODO let the scope handler deal with this
1797             if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
1798             {
1799                 Dependency dependency = new Dependency();
1800 
1801                 dependency.setArtifactId( a.getArtifactId() );
1802                 dependency.setGroupId( a.getGroupId() );
1803                 dependency.setVersion( a.getVersion() );
1804                 dependency.setScope( a.getScope() );
1805                 dependency.setType( a.getType() );
1806                 dependency.setClassifier( a.getClassifier() );
1807 
1808                 list.add( dependency );
1809             }
1810         }
1811         return Collections.unmodifiableList( list );
1812     }
1813 
1814     @Deprecated
1815     public void setReporting( Reporting reporting )
1816     {
1817         getModel().setReporting( reporting );
1818     }
1819 
1820     @Deprecated
1821     public Reporting getReporting()
1822     {
1823         return getModel().getReporting();
1824     }
1825 
1826     @Deprecated
1827     public void setReportArtifacts( Set<Artifact> reportArtifacts )
1828     {
1829         this.reportArtifacts = reportArtifacts;
1830 
1831         reportArtifactMap = null;
1832     }
1833 
1834     @Deprecated
1835     public Set<Artifact> getReportArtifacts()
1836     {
1837         return reportArtifacts;
1838     }
1839 
1840     @Deprecated
1841     public Map<String, Artifact> getReportArtifactMap()
1842     {
1843         if ( reportArtifactMap == null )
1844         {
1845             reportArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getReportArtifacts() );
1846         }
1847         return reportArtifactMap;
1848     }
1849 
1850     @Deprecated
1851     public void setExtensionArtifacts( Set<Artifact> extensionArtifacts )
1852     {
1853         this.extensionArtifacts = extensionArtifacts;
1854 
1855         extensionArtifactMap = null;
1856     }
1857 
1858     @Deprecated
1859     public Set<Artifact> getExtensionArtifacts()
1860     {
1861         return extensionArtifacts;
1862     }
1863 
1864     @Deprecated
1865     public Map<String, Artifact> getExtensionArtifactMap()
1866     {
1867         if ( extensionArtifactMap == null )
1868         {
1869             extensionArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getExtensionArtifacts() );
1870         }
1871         return extensionArtifactMap;
1872     }
1873 
1874     @Deprecated
1875     public List<ReportPlugin> getReportPlugins()
1876     {
1877         if ( getModel().getReporting() == null )
1878         {
1879             return Collections.emptyList();
1880         }
1881         return Collections.unmodifiableList( getModel().getReporting().getPlugins() );
1882     }
1883 
1884     @Deprecated
1885     public Xpp3Dom getReportConfiguration( String pluginGroupId, String pluginArtifactId, String reportSetId )
1886     {
1887         Xpp3Dom dom = null;
1888 
1889         // ----------------------------------------------------------------------
1890         // I would like to be able to lookup the Mojo object using a key but
1891         // we have a limitation in modello that will be remedied shortly. So
1892         // for now I have to iterate through and see what we have.
1893         // ----------------------------------------------------------------------
1894 
1895         if ( getReportPlugins() != null )
1896         {
1897             for ( ReportPlugin plugin : getReportPlugins() )
1898             {
1899                 if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
1900                 {
1901                     dom = (Xpp3Dom) plugin.getConfiguration();
1902 
1903                     if ( reportSetId != null )
1904                     {
1905                         ReportSet reportSet = plugin.getReportSetsAsMap().get( reportSetId );
1906                         if ( reportSet != null )
1907                         {
1908                             Xpp3Dom executionConfiguration = (Xpp3Dom) reportSet.getConfiguration();
1909                             if ( executionConfiguration != null )
1910                             {
1911                                 Xpp3Dom newDom = new Xpp3Dom( executionConfiguration );
1912                                 dom = Xpp3Dom.mergeXpp3Dom( newDom, dom );
1913                             }
1914                         }
1915                     }
1916                     break;
1917                 }
1918             }
1919         }
1920 
1921         if ( dom != null )
1922         {
1923             // make a copy so the original in the POM doesn't get messed with
1924             dom = new Xpp3Dom( dom );
1925         }
1926 
1927         return dom;
1928     }
1929 
1930     /**
1931      * @deprecated Use MavenProjectHelper.attachArtifact(..) instead.
1932      */
1933     @Deprecated
1934     public void attachArtifact( String type, String classifier, File file )
1935     {
1936     }
1937 
1938     /**
1939      * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
1940      */
1941     @Deprecated
1942     public void writeModel( Writer writer )
1943         throws IOException
1944     {
1945         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1946         pomWriter.write( writer, getModel() );
1947     }
1948 
1949     /**
1950      * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
1951      */
1952     @Deprecated
1953     public void writeOriginalModel( Writer writer )
1954         throws IOException
1955     {
1956         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1957         pomWriter.write( writer, getOriginalModel() );
1958     }
1959 
1960     @Deprecated
1961     public Artifact replaceWithActiveArtifact( Artifact pluginArtifact )
1962     {
1963         return pluginArtifact;
1964     }
1965 
1966     /**
1967      * Gets the project building request from which this project instance was created. <strong>Warning:</strong> This is
1968      * an utility method that is meant to assist integrators of Maven, it must not be used by Maven plugins.
1969      *
1970      * @return The project building request or {@code null}.
1971      * @since 2.1
1972      */
1973     @Deprecated
1974     public ProjectBuildingRequest getProjectBuildingRequest()
1975     {
1976         return projectBuilderConfiguration;
1977     }
1978 
1979     /**
1980      * Sets the project building request from which this project instance was created. <strong>Warning:</strong> This is
1981      * an utility method that is meant to assist integrators of Maven, it must not be used by Maven plugins.
1982      *
1983      * @param projectBuildingRequest The project building request, may be {@code null}.
1984      * @since 2.1
1985      */
1986     // used by maven-dependency-tree
1987     @Deprecated
1988     public void setProjectBuildingRequest( ProjectBuildingRequest projectBuildingRequest )
1989     {
1990         this.projectBuilderConfiguration = projectBuildingRequest;
1991     }
1992 
1993     private static class ArtifactsHolder
1994     {
1995         private ArtifactFilter artifactFilter;
1996         private Set<Artifact> artifacts;
1997         private Map<String, Artifact> artifactMap;
1998     }
1999 }