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.api;
20
21 import java.nio.file.Path;
22 import java.util.List;
23 import java.util.Optional;
24
25 import org.apache.maven.api.annotations.Experimental;
26 import org.apache.maven.api.annotations.Nonnull;
27 import org.apache.maven.api.model.Build;
28 import org.apache.maven.api.model.Model;
29 import org.apache.maven.api.model.Profile;
30
31 /**
32 * Interface representing a Maven project which can be created using the
33 * {@link org.apache.maven.api.services.ProjectBuilder ProjectBuilder} service.
34 * Such objects are immutable and plugin that wish to modify such objects
35 * need to do so using the {@link org.apache.maven.api.services.ProjectManager
36 * ProjectManager} service.
37 * <p>
38 * Projects are created using the {@code ProjectBuilder} from a POM file
39 * (usually named {@code pom.xml}) on the file system.
40 * The {@link #getPomPath()} will point to the POM file and the
41 * {@link #getBasedir()} to the directory parent containing the
42 * POM file.
43 * </p>
44 *
45 * @since 4.0.0
46 * @see org.apache.maven.api.services.ProjectManager
47 * @see org.apache.maven.api.services.ProjectBuilder
48 */
49 @Experimental
50 public interface Project {
51
52 /**
53 * {@return the project groupId}.
54 */
55 @Nonnull
56 String getGroupId();
57
58 /**
59 * {@return the project artifactId}.
60 */
61 @Nonnull
62 String getArtifactId();
63
64 /**
65 * {@return the project version}.
66 */
67 @Nonnull
68 String getVersion();
69
70 /**
71 * {@return the project packaging}.
72 * <p>
73 * Note: unlike in legacy code, logical checks against string representing packaging (returned by this method)
74 * are NOT recommended (code like {@code "pom".equals(project.getPackaging)} must be avoided). Use method
75 * {@link #getArtifacts()} to gain access to POM or build artifact.
76 *
77 * @see #getArtifacts()
78 */
79 @Nonnull
80 Packaging getPackaging();
81
82 /**
83 * {@return the project language}. It is by default determined by {@link #getPackaging()}.
84 *
85 * @see #getPackaging()
86 */
87 @Nonnull
88 default Language getLanguage() {
89 return getPackaging().language();
90 }
91
92 /**
93 * {@return the project POM artifact}, which is the artifact of the POM of this project. Every project have a POM
94 * artifact, even if the existence of backing POM file is NOT a requirement (i.e. for some transient projects).
95 *
96 * @see org.apache.maven.api.services.ArtifactManager#getPath(Artifact)
97 */
98 @Nonnull
99 default ProducedArtifact getPomArtifact() {
100 return getArtifacts().get(0);
101 }
102
103 /**
104 * {@return the project main artifact}, which is the artifact produced by this project build, if applicable.
105 * This artifact MAY be absent if the project is actually not producing any main artifact (i.e. "pom" packaging).
106 *
107 * @see #getPackaging()
108 * @see org.apache.maven.api.services.ArtifactManager#getPath(Artifact)
109 */
110 @Nonnull
111 default Optional<ProducedArtifact> getMainArtifact() {
112 List<ProducedArtifact> artifacts = getArtifacts();
113 return artifacts.size() == 2 ? Optional.of(artifacts.get(1)) : Optional.empty();
114 }
115
116 /**
117 * {@return the project artifacts as immutable list}. Elements are the project POM artifact and the artifact
118 * produced by this project build, if applicable. Hence, the returned list may have one or two elements
119 * (never less than 1, never more than 2), depending on project packaging.
120 * <p>
121 * The list's first element is ALWAYS the project POM artifact. Presence of second element in the list depends
122 * solely on the project packaging.
123 *
124 * @see #getPackaging()
125 * @see #getPomArtifact()
126 * @see #getMainArtifact()
127 * @see org.apache.maven.api.services.ArtifactManager#getPath(Artifact)
128 */
129 @Nonnull
130 List<ProducedArtifact> getArtifacts();
131
132 /**
133 * {@return the project model}.
134 */
135 @Nonnull
136 Model getModel();
137
138 /**
139 * Shorthand method.
140 *
141 * @return the build element of the project model
142 */
143 @Nonnull
144 default Build getBuild() {
145 Build build = getModel().getBuild();
146 return build != null ? build : Build.newInstance();
147 }
148
149 /**
150 * Returns the path to the pom file for this project.
151 * A project is usually read from a file named {@code pom.xml},
152 * which contains the {@linkplain #getModel() model} in an XML form.
153 * When a custom {@code org.apache.maven.api.spi.ModelParser} is used,
154 * the path may point to a non XML file.
155 * <p>
156 * The POM path is also used to define the {@linkplain #getBasedir() base directory}
157 * of the project.
158 *
159 * @return the path of the pom
160 * @see #getBasedir()
161 */
162 @Nonnull
163 Path getPomPath();
164
165 /**
166 * Returns the project base directory, i.e. the directory containing the project.
167 * A project is usually read from the file system and this will point to
168 * the directory containing the POM file.
169 *
170 * @return the path of the directory containing the project
171 */
172 @Nonnull
173 Path getBasedir();
174
175 /**
176 * {@return the project direct dependencies (directly specified or inherited)}.
177 */
178 @Nonnull
179 List<DependencyCoordinates> getDependencies();
180
181 /**
182 * {@return the project managed dependencies (directly specified or inherited)}.
183 */
184 @Nonnull
185 List<DependencyCoordinates> getManagedDependencies();
186
187 /**
188 * {@return the project ID, usable as key}.
189 */
190 @Nonnull
191 default String getId() {
192 return getModel().getId();
193 }
194
195 /**
196 * Returns a boolean indicating if the project is the top level project for
197 * this reactor build. The top level project may be different from the
198 * {@code rootDirectory}, especially if a subtree of the project is being
199 * built, either because Maven has been launched in a subdirectory or using
200 * a {@code -f} option.
201 *
202 * @return {@code true} if the project is the top level project for this build
203 */
204 boolean isTopProject();
205
206 /**
207 * Returns a boolean indicating if the project is a root project,
208 * meaning that the {@link #getRootDirectory()} and {@link #getBasedir()}
209 * points to the same directory, and that either {@link Model#isRoot()}
210 * is {@code true} or that {@code basedir} contains a {@code .mvn} child
211 * directory.
212 *
213 * @return {@code true} if the project is the root project
214 * @see Model#isRoot()
215 */
216 boolean isRootProject();
217
218 /**
219 * Gets the root directory of the project, which is the parent directory
220 * containing the {@code .mvn} directory or flagged with {@code root="true"}.
221 *
222 * @return the root directory of the project
223 * @throws IllegalStateException if the root directory could not be found
224 * @see Session#getRootDirectory()
225 */
226 @Nonnull
227 Path getRootDirectory();
228
229 /**
230 * Returns project parent project, if any.
231 * <p>
232 * Note that the model may have a parent defined, but an empty parent
233 * project may be returned if the parent comes from a remote repository,
234 * as a {@code Project} must refer to a buildable project.
235 *
236 * @return an optional containing the parent project
237 * @see Model#getParent()
238 */
239 @Nonnull
240 Optional<Project> getParent();
241
242 /**
243 * Returns all profiles defined in this project.
244 * <p>
245 * This method returns only the profiles defined directly in the current project's POM
246 * and does not include profiles from parent projects.
247 *
248 * @return a non-null, possibly empty list of profiles defined in this project
249 * @see Profile
250 * @see #getEffectiveProfiles()
251 */
252 @Nonnull
253 List<Profile> getDeclaredProfiles();
254
255 /**
256 * Returns all profiles defined in this project and all of its parent projects.
257 * <p>
258 * This method traverses the parent hierarchy and includes profiles defined in parent POMs.
259 * The returned list contains profiles from the current project and all of its ancestors in
260 * the project inheritance chain.
261 *
262 * @return a non-null, possibly empty list of all profiles from this project and its parents
263 * @see Profile
264 * @see #getDeclaredProfiles()
265 */
266 @Nonnull
267 List<Profile> getEffectiveProfiles();
268
269 /**
270 * Returns all active profiles for the current project build.
271 * <p>
272 * Active profiles are those that have been explicitly activated through one of the following means:
273 * <ul>
274 * <li>Command line activation using the -P flag</li>
275 * <li>Maven settings activation in settings.xml via <activeProfiles></li>
276 * <li>Automatic activation via <activation> conditions</li>
277 * <li>The default active profile (marked with <activeByDefault>true</activeByDefault>)</li>
278 * </ul>
279 * <p>
280 * The active profiles control various aspects of the build configuration including but not
281 * limited to dependencies, plugins, properties, and build resources.
282 *
283 * @return a non-null, possibly empty list of active profiles for this project
284 * @see Profile
285 * @see #getEffectiveActiveProfiles()
286 */
287 @Nonnull
288 List<Profile> getDeclaredActiveProfiles();
289
290 /**
291 * Returns all active profiles for this project and all of its parent projects.
292 * <p>
293 * This method traverses the parent hierarchy and collects all active profiles from
294 * the current project and its ancestors. Active profiles are those that meet the
295 * activation criteria through explicit activation or automatic conditions.
296 * <p>
297 * The combined set of active profiles from the entire project hierarchy affects
298 * the effective build configuration.
299 *
300 * @return a non-null, possibly empty list of all active profiles from this project and its parents
301 * @see Profile
302 * @see #getDeclaredActiveProfiles()
303 */
304 @Nonnull
305 List<Profile> getEffectiveActiveProfiles();
306 }