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