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