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             String specificMethods = getRecommendedMethods(collectionName);
1220             LOGGER.warn("Plugin is modifying " + collectionName + " through " + method
1221                     + "(), which will not work in Maven 4.0.0. "
1222                     + "Use " + specificMethods + " instead. "
1223                     + "If using a plugin, please upgrade to the latest version or report the issue to the plugin maintainer. "
1224                     + "To disable these warnings, set -D" + DISABLE_WARNINGS_PROPERTY + "=true on the command line, "
1225                     + "in the .mvn/maven.config file, or in project POM properties.");
1226             // Log a stack trace to help identify the caller
1227             if (LOGGER.isDebugEnabled()) {
1228                 LOGGER.debug("Stack trace for deprecated source root modification:", new Exception("Stack trace"));
1229             }
1230         }
1231 
1232         private String getRecommendedMethods(String collectionName) {
1233             switch (collectionName) {
1234                 case "compileSourceRoots":
1235                     return "MavenProject.addCompileSourceRoot()/removeCompileSourceRoot() methods";
1236                 case "testCompileSourceRoots":
1237                     return "MavenProject.addTestCompileSourceRoot()/removeTestCompileSourceRoot() methods";
1238                 default:
1239                     return "appropriate MavenProject add/remove methods";
1240             }
1241         }
1242 
1243         @Override
1244         public E get(int index) {
1245             return delegate.get(index);
1246         }
1247 
1248         @Override
1249         public int size() {
1250             return delegate.size();
1251         }
1252 
1253         @Override
1254         public E set(int index, E element) {
1255             logWarning("set");
1256             return delegate.set(index, element);
1257         }
1258 
1259         @Override
1260         public void add(int index, E element) {
1261             logWarning("add");
1262             delegate.add(index, element);
1263         }
1264 
1265         @Override
1266         public E remove(int index) {
1267             logWarning("remove");
1268             return delegate.remove(index);
1269         }
1270 
1271         @Override
1272         public void clear() {
1273             logWarning("clear");
1274             delegate.clear();
1275         }
1276 
1277         @Override
1278         public boolean addAll(int index, Collection<? extends E> c) {
1279             logWarning("addAll");
1280             return delegate.addAll(index, c);
1281         }
1282 
1283         @Override
1284         public Iterator<E> iterator() {
1285             return new Iterator<E>() {
1286                 private final Iterator<E> it = delegate.iterator();
1287 
1288                 @Override
1289                 public boolean hasNext() {
1290                     return it.hasNext();
1291                 }
1292 
1293                 @Override
1294                 public E next() {
1295                     return it.next();
1296                 }
1297 
1298                 @Override
1299                 public void remove() {
1300                     logWarning("iterator.remove");
1301                     it.remove();
1302                 }
1303             };
1304         }
1305 
1306         @Override
1307         public ListIterator<E> listIterator() {
1308             return listIterator(0);
1309         }
1310 
1311         @Override
1312         public ListIterator<E> listIterator(int index) {
1313             return new ListIterator<E>() {
1314                 private final ListIterator<E> it = delegate.listIterator(index);
1315 
1316                 @Override
1317                 public boolean hasNext() {
1318                     return it.hasNext();
1319                 }
1320 
1321                 @Override
1322                 public E next() {
1323                     return it.next();
1324                 }
1325 
1326                 @Override
1327                 public boolean hasPrevious() {
1328                     return it.hasPrevious();
1329                 }
1330 
1331                 @Override
1332                 public E previous() {
1333                     return it.previous();
1334                 }
1335 
1336                 @Override
1337                 public int nextIndex() {
1338                     return it.nextIndex();
1339                 }
1340 
1341                 @Override
1342                 public int previousIndex() {
1343                     return it.previousIndex();
1344                 }
1345 
1346                 @Override
1347                 public void remove() {
1348                     logWarning("listIterator.remove");
1349                     it.remove();
1350                 }
1351 
1352                 @Override
1353                 public void set(E e) {
1354                     logWarning("listIterator.set");
1355                     it.set(e);
1356                 }
1357 
1358                 @Override
1359                 public void add(E e) {
1360                     logWarning("listIterator.add");
1361                     it.add(e);
1362                 }
1363             };
1364         }
1365 
1366         @Override
1367         public List<E> subList(int fromIndex, int toIndex) {
1368             return new LoggingList<>(delegate.subList(fromIndex, toIndex), collectionName);
1369         }
1370 
1371         @Override
1372         public boolean equals(Object o) {
1373             return delegate.equals(o);
1374         }
1375 
1376         @Override
1377         public int hashCode() {
1378             return delegate.hashCode();
1379         }
1380 
1381         @Override
1382         public String toString() {
1383             return delegate.toString();
1384         }
1385     }
1386 
1387     /**
1388      * Sets the value of the context value of this project identified by the given key. If the supplied value is
1389      * <code>null</code>, the context value is removed from this project. Context values are intended to allow core
1390      * extensions to associate derived state with project instances.
1391      */
1392     public void setContextValue(String key, Object value) {
1393         if (context == null) {
1394             context = new HashMap<>();
1395         }
1396         if (value != null) {
1397             context.put(key, value);
1398         } else {
1399             context.remove(key);
1400         }
1401     }
1402 
1403     /**
1404      * Returns context value of this project associated with the given key or null if this project has no such value.
1405      */
1406     public Object getContextValue(String key) {
1407         if (context == null) {
1408             return null;
1409         }
1410         return context.get(key);
1411     }
1412 
1413     /**
1414      * Sets the project's class realm. <strong>Warning:</strong> This is an internal utility method that is only public
1415      * for technical reasons, it is not part of the public API. In particular, this method can be changed or deleted
1416      * without prior notice and must not be used by plugins.
1417      *
1418      * @param classRealm The class realm hosting the build extensions of this project, may be {@code null}.
1419      */
1420     public void setClassRealm(ClassRealm classRealm) {
1421         this.classRealm = classRealm;
1422     }
1423 
1424     /**
1425      * Gets the project's class realm. This class realm hosts the build extensions of the project.
1426      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1427      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1428      * used by plugins.
1429      *
1430      * @return The project's class realm or {@code null}.
1431      */
1432     public ClassRealm getClassRealm() {
1433         return classRealm;
1434     }
1435 
1436     /**
1437      * Sets the artifact filter used to exclude shared extension artifacts from plugin realms. <strong>Warning:</strong>
1438      * This is an internal utility method that is only public for technical reasons, it is not part of the public API.
1439      * In particular, this method can be changed or deleted without prior notice and must not be used by plugins.
1440      *
1441      * @param extensionDependencyFilter The dependency filter to apply to plugins, may be {@code null}.
1442      */
1443     public void setExtensionDependencyFilter(DependencyFilter extensionDependencyFilter) {
1444         this.extensionDependencyFilter = extensionDependencyFilter;
1445     }
1446 
1447     /**
1448      * Gets the dependency filter used to exclude shared extension artifacts from plugin realms.
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      * @return The dependency filter or {@code null}.
1454      */
1455     public DependencyFilter getExtensionDependencyFilter() {
1456         return extensionDependencyFilter;
1457     }
1458 
1459     /**
1460      * Sets the transitive dependency artifacts that have been resolved/collected for this project.
1461      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1462      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1463      * used by plugins.
1464      *
1465      * @param artifacts The set of artifacts, may be {@code null}.
1466      */
1467     public void setResolvedArtifacts(Set<Artifact> artifacts) {
1468         this.resolvedArtifacts = (artifacts != null) ? artifacts : Collections.<Artifact>emptySet();
1469         this.artifacts = null;
1470         this.artifactMap = null;
1471     }
1472 
1473     /**
1474      * Sets the scope filter to select the artifacts being exposed to the currently executed mojo.
1475      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1476      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1477      * used by plugins.
1478      *
1479      * @param artifactFilter The artifact filter, may be {@code null} to exclude all artifacts.
1480      */
1481     public void setArtifactFilter(ArtifactFilter artifactFilter) {
1482         this.artifactFilter = artifactFilter;
1483         this.artifacts = null;
1484         this.artifactMap = null;
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 phase The phase to check for, must not be {@code null}.
1493      * @return {@code true} if the phase has been seen.
1494      */
1495     public boolean hasLifecyclePhase(String phase) {
1496         return lifecyclePhases.contains(phase);
1497     }
1498 
1499     /**
1500      * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
1501      * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
1502      * used by plugins.
1503      *
1504      * @param lifecyclePhase The lifecycle phase to add, must not be {@code null}.
1505      */
1506     public void addLifecyclePhase(String lifecyclePhase) {
1507         lifecyclePhases.add(lifecyclePhase);
1508     }
1509 
1510     // ----------------------------------------------------------------------------------------------------------------
1511     //
1512     //
1513     // D E P R E C A T E D
1514     //
1515     //
1516     // ----------------------------------------------------------------------------------------------------------------
1517     //
1518     // Everything below will be removed for Maven 4.0.0
1519     //
1520     // ----------------------------------------------------------------------------------------------------------------
1521 
1522     private ProjectBuildingRequest projectBuilderConfiguration;
1523 
1524     private Map<String, String> moduleAdjustments;
1525 
1526     @Deprecated // This appears only to be used in test code
1527     public String getModulePathAdjustment(MavenProject moduleProject) throws IOException {
1528         // FIXME: This is hacky. What if module directory doesn't match artifactid, and parent
1529         // is coming from the repository??
1530         String module = moduleProject.getArtifactId();
1531 
1532         File moduleFile = moduleProject.getFile();
1533 
1534         if (moduleFile != null) {
1535             File moduleDir = moduleFile.getCanonicalFile().getParentFile();
1536 
1537             module = moduleDir.getName();
1538         }
1539 
1540         if (moduleAdjustments == null) {
1541             moduleAdjustments = new HashMap<>();
1542 
1543             List<String> modules = getModules();
1544             if (modules != null) {
1545                 for (String modulePath : modules) {
1546                     String moduleName = modulePath;
1547 
1548                     if (moduleName.endsWith("/") || moduleName.endsWith("\\")) {
1549                         moduleName = moduleName.substring(0, moduleName.length() - 1);
1550                     }
1551 
1552                     int lastSlash = moduleName.lastIndexOf('/');
1553 
1554                     if (lastSlash < 0) {
1555                         lastSlash = moduleName.lastIndexOf('\\');
1556                     }
1557 
1558                     String adjustment = null;
1559 
1560                     if (lastSlash > -1) {
1561                         moduleName = moduleName.substring(lastSlash + 1);
1562                         adjustment = modulePath.substring(0, lastSlash);
1563                     }
1564 
1565                     moduleAdjustments.put(moduleName, adjustment);
1566                 }
1567             }
1568         }
1569 
1570         return moduleAdjustments.get(module);
1571     }
1572 
1573     @Deprecated
1574     public Set<Artifact> createArtifacts(ArtifactFactory artifactFactory, String inheritedScope, ArtifactFilter filter)
1575             throws InvalidDependencyVersionException {
1576         return MavenMetadataSource.createArtifacts(artifactFactory, getDependencies(), inheritedScope, filter, this);
1577     }
1578 
1579     @Deprecated
1580     protected void setScriptSourceRoots(List<String> scriptSourceRoots) {
1581         this.scriptSourceRoots = scriptSourceRoots;
1582     }
1583 
1584     @Deprecated
1585     public void addScriptSourceRoot(String path) {
1586         if (path != null) {
1587             path = path.trim();
1588             if (path.length() != 0) {
1589                 if (!getScriptSourceRoots().contains(path)) {
1590                     getScriptSourceRoots().add(path);
1591                 }
1592             }
1593         }
1594     }
1595 
1596     @Deprecated
1597     public List<String> getScriptSourceRoots() {
1598         return scriptSourceRoots;
1599     }
1600 
1601     @Deprecated
1602     public List<Artifact> getCompileArtifacts() {
1603         List<Artifact> list = new ArrayList<>(getArtifacts().size());
1604 
1605         for (Artifact a : getArtifacts()) {
1606             // TODO classpath check doesn't belong here - that's the other method
1607             if (a.getArtifactHandler().isAddedToClasspath()) {
1608                 // TODO let the scope handler deal with this
1609                 if (Artifact.SCOPE_COMPILE.equals(a.getScope())
1610                         || Artifact.SCOPE_PROVIDED.equals(a.getScope())
1611                         || Artifact.SCOPE_SYSTEM.equals(a.getScope())) {
1612                     list.add(a);
1613                 }
1614             }
1615         }
1616         return list;
1617     }
1618 
1619     @Deprecated
1620     public List<Dependency> getCompileDependencies() {
1621         Set<Artifact> artifacts = getArtifacts();
1622 
1623         if ((artifacts == null) || artifacts.isEmpty()) {
1624             return Collections.emptyList();
1625         }
1626 
1627         List<Dependency> list = new ArrayList<>(artifacts.size());
1628 
1629         for (Artifact a : getArtifacts()) {
1630             // TODO let the scope handler deal with this
1631             if (Artifact.SCOPE_COMPILE.equals(a.getScope())
1632                     || Artifact.SCOPE_PROVIDED.equals(a.getScope())
1633                     || Artifact.SCOPE_SYSTEM.equals(a.getScope())) {
1634                 Dependency dependency = new Dependency();
1635 
1636                 dependency.setArtifactId(a.getArtifactId());
1637                 dependency.setGroupId(a.getGroupId());
1638                 dependency.setVersion(a.getVersion());
1639                 dependency.setScope(a.getScope());
1640                 dependency.setType(a.getType());
1641                 dependency.setClassifier(a.getClassifier());
1642 
1643                 list.add(dependency);
1644             }
1645         }
1646         return Collections.unmodifiableList(list);
1647     }
1648 
1649     @Deprecated
1650     public List<Artifact> getTestArtifacts() {
1651         List<Artifact> list = new ArrayList<>(getArtifacts().size());
1652 
1653         for (Artifact a : getArtifacts()) {
1654             // TODO classpath check doesn't belong here - that's the other method
1655             if (a.getArtifactHandler().isAddedToClasspath()) {
1656                 list.add(a);
1657             }
1658         }
1659         return list;
1660     }
1661 
1662     @Deprecated
1663     public List<Dependency> getTestDependencies() {
1664         Set<Artifact> artifacts = getArtifacts();
1665 
1666         if ((artifacts == null) || artifacts.isEmpty()) {
1667             return Collections.emptyList();
1668         }
1669 
1670         List<Dependency> list = new ArrayList<>(artifacts.size());
1671 
1672         for (Artifact a : getArtifacts()) {
1673             Dependency dependency = new Dependency();
1674 
1675             dependency.setArtifactId(a.getArtifactId());
1676             dependency.setGroupId(a.getGroupId());
1677             dependency.setVersion(a.getVersion());
1678             dependency.setScope(a.getScope());
1679             dependency.setType(a.getType());
1680             dependency.setClassifier(a.getClassifier());
1681 
1682             list.add(dependency);
1683         }
1684         return Collections.unmodifiableList(list);
1685     }
1686 
1687     @Deprecated // used by the Maven ITs
1688     public List<Dependency> getRuntimeDependencies() {
1689         Set<Artifact> artifacts = getArtifacts();
1690 
1691         if ((artifacts == null) || artifacts.isEmpty()) {
1692             return Collections.emptyList();
1693         }
1694 
1695         List<Dependency> list = new ArrayList<>(artifacts.size());
1696 
1697         for (Artifact a : getArtifacts()) {
1698             // TODO let the scope handler deal with this
1699             if (Artifact.SCOPE_COMPILE.equals(a.getScope()) || Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
1700                 Dependency dependency = new Dependency();
1701 
1702                 dependency.setArtifactId(a.getArtifactId());
1703                 dependency.setGroupId(a.getGroupId());
1704                 dependency.setVersion(a.getVersion());
1705                 dependency.setScope(a.getScope());
1706                 dependency.setType(a.getType());
1707                 dependency.setClassifier(a.getClassifier());
1708 
1709                 list.add(dependency);
1710             }
1711         }
1712         return Collections.unmodifiableList(list);
1713     }
1714 
1715     @Deprecated
1716     public List<Artifact> getRuntimeArtifacts() {
1717         List<Artifact> list = new ArrayList<>(getArtifacts().size());
1718 
1719         for (Artifact a : getArtifacts()) {
1720             // TODO classpath check doesn't belong here - that's the other method
1721             if (a.getArtifactHandler().isAddedToClasspath()
1722                     // TODO let the scope handler deal with this
1723                     && (Artifact.SCOPE_COMPILE.equals(a.getScope()) || Artifact.SCOPE_RUNTIME.equals(a.getScope()))) {
1724                 list.add(a);
1725             }
1726         }
1727         return list;
1728     }
1729 
1730     @Deprecated
1731     public List<String> getSystemClasspathElements() throws DependencyResolutionRequiredException {
1732         List<String> list = new ArrayList<>(getArtifacts().size());
1733 
1734         String d = getBuild().getOutputDirectory();
1735         if (d != null) {
1736             list.add(d);
1737         }
1738 
1739         for (Artifact a : getArtifacts()) {
1740             if (a.getArtifactHandler().isAddedToClasspath()) {
1741                 // TODO let the scope handler deal with this
1742                 if (Artifact.SCOPE_SYSTEM.equals(a.getScope())) {
1743                     addArtifactPath(a, list);
1744                 }
1745             }
1746         }
1747         return list;
1748     }
1749 
1750     @Deprecated
1751     public List<Artifact> getSystemArtifacts() {
1752         List<Artifact> list = new ArrayList<>(getArtifacts().size());
1753 
1754         for (Artifact a : getArtifacts()) {
1755             // TODO classpath check doesn't belong here - that's the other method
1756             if (a.getArtifactHandler().isAddedToClasspath()) {
1757                 // TODO let the scope handler deal with this
1758                 if (Artifact.SCOPE_SYSTEM.equals(a.getScope())) {
1759                     list.add(a);
1760                 }
1761             }
1762         }
1763         return list;
1764     }
1765 
1766     @Deprecated
1767     public List<Dependency> getSystemDependencies() {
1768         Set<Artifact> artifacts = getArtifacts();
1769 
1770         if ((artifacts == null) || artifacts.isEmpty()) {
1771             return Collections.emptyList();
1772         }
1773 
1774         List<Dependency> list = new ArrayList<>(artifacts.size());
1775 
1776         for (Artifact a : getArtifacts()) {
1777             // TODO let the scope handler deal with this
1778             if (Artifact.SCOPE_SYSTEM.equals(a.getScope())) {
1779                 Dependency dependency = new Dependency();
1780 
1781                 dependency.setArtifactId(a.getArtifactId());
1782                 dependency.setGroupId(a.getGroupId());
1783                 dependency.setVersion(a.getVersion());
1784                 dependency.setScope(a.getScope());
1785                 dependency.setType(a.getType());
1786                 dependency.setClassifier(a.getClassifier());
1787 
1788                 list.add(dependency);
1789             }
1790         }
1791         return Collections.unmodifiableList(list);
1792     }
1793 
1794     @Deprecated
1795     public void setReporting(Reporting reporting) {
1796         getModel().setReporting(reporting);
1797     }
1798 
1799     @Deprecated
1800     public Reporting getReporting() {
1801         return getModel().getReporting();
1802     }
1803 
1804     @Deprecated
1805     public void setReportArtifacts(Set<Artifact> reportArtifacts) {
1806         this.reportArtifacts = reportArtifacts;
1807 
1808         reportArtifactMap = null;
1809     }
1810 
1811     @Deprecated
1812     public Set<Artifact> getReportArtifacts() {
1813         return reportArtifacts;
1814     }
1815 
1816     @Deprecated
1817     public Map<String, Artifact> getReportArtifactMap() {
1818         if (reportArtifactMap == null) {
1819             reportArtifactMap = ArtifactUtils.artifactMapByVersionlessId(getReportArtifacts());
1820         }
1821 
1822         return reportArtifactMap;
1823     }
1824 
1825     @Deprecated
1826     public void setExtensionArtifacts(Set<Artifact> extensionArtifacts) {
1827         this.extensionArtifacts = extensionArtifacts;
1828 
1829         extensionArtifactMap = null;
1830     }
1831 
1832     @Deprecated
1833     public Set<Artifact> getExtensionArtifacts() {
1834         return extensionArtifacts;
1835     }
1836 
1837     @Deprecated
1838     public Map<String, Artifact> getExtensionArtifactMap() {
1839         if (extensionArtifactMap == null) {
1840             extensionArtifactMap = ArtifactUtils.artifactMapByVersionlessId(getExtensionArtifacts());
1841         }
1842 
1843         return extensionArtifactMap;
1844     }
1845 
1846     @Deprecated
1847     public List<ReportPlugin> getReportPlugins() {
1848         if (getModel().getReporting() == null) {
1849             return Collections.emptyList();
1850         }
1851         return Collections.unmodifiableList(getModel().getReporting().getPlugins());
1852     }
1853 
1854     @Deprecated
1855     public Xpp3Dom getReportConfiguration(String pluginGroupId, String pluginArtifactId, String reportSetId) {
1856         Xpp3Dom dom = null;
1857 
1858         // ----------------------------------------------------------------------
1859         // I would like to be able to lookup the Mojo object using a key but
1860         // we have a limitation in modello that will be remedied shortly. So
1861         // for now I have to iterate through and see what we have.
1862         // ----------------------------------------------------------------------
1863 
1864         if (getReportPlugins() != null) {
1865             for (ReportPlugin plugin : getReportPlugins()) {
1866                 if (pluginGroupId.equals(plugin.getGroupId()) && pluginArtifactId.equals(plugin.getArtifactId())) {
1867                     dom = (Xpp3Dom) plugin.getConfiguration();
1868 
1869                     if (reportSetId != null) {
1870                         ReportSet reportSet = plugin.getReportSetsAsMap().get(reportSetId);
1871                         if (reportSet != null) {
1872                             Xpp3Dom executionConfiguration = (Xpp3Dom) reportSet.getConfiguration();
1873                             if (executionConfiguration != null) {
1874                                 Xpp3Dom newDom = new Xpp3Dom(executionConfiguration);
1875                                 dom = Xpp3Dom.mergeXpp3Dom(newDom, dom);
1876                             }
1877                         }
1878                     }
1879                     break;
1880                 }
1881             }
1882         }
1883 
1884         if (dom != null) {
1885             // make a copy so the original in the POM doesn't get messed with
1886             dom = new Xpp3Dom(dom);
1887         }
1888 
1889         return dom;
1890     }
1891 
1892     /**
1893      * @deprecated Use MavenProjectHelper.attachArtifact(..) instead.
1894      */
1895     @Deprecated
1896     public void attachArtifact(String type, String classifier, File file) {}
1897 
1898     /**
1899      * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
1900      */
1901     @Deprecated
1902     public void writeModel(Writer writer) throws IOException {
1903         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1904         pomWriter.write(writer, getModel());
1905     }
1906 
1907     /**
1908      * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
1909      */
1910     @Deprecated
1911     public void writeOriginalModel(Writer writer) throws IOException {
1912         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
1913         pomWriter.write(writer, getOriginalModel());
1914     }
1915 
1916     @Deprecated
1917     public Artifact replaceWithActiveArtifact(Artifact pluginArtifact) {
1918         return pluginArtifact;
1919     }
1920 
1921     /**
1922      * Gets 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      * @return The project building request or {@code null}.
1926      * @since 2.1
1927      */
1928     @Deprecated
1929     public ProjectBuildingRequest getProjectBuildingRequest() {
1930         return projectBuilderConfiguration;
1931     }
1932 
1933     /**
1934      * Sets the project building request from which this project instance was created. <strong>Warning:</strong> This is
1935      * an utility method that is meant to assist integrators of Maven, it must not be used by Maven plugins.
1936      *
1937      * @param projectBuildingRequest The project building request, may be {@code null}.
1938      * @since 2.1
1939      */
1940     // used by maven-dependency-tree
1941     @Deprecated
1942     public void setProjectBuildingRequest(ProjectBuildingRequest projectBuildingRequest) {
1943         this.projectBuilderConfiguration = projectBuildingRequest;
1944     }
1945 }