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