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.services;
20
21 import java.nio.file.Path;
22 import java.util.List;
23 import java.util.Objects;
24 import java.util.Optional;
25
26 import org.apache.maven.api.RemoteRepository;
27 import org.apache.maven.api.Session;
28 import org.apache.maven.api.annotations.Experimental;
29 import org.apache.maven.api.annotations.Immutable;
30 import org.apache.maven.api.annotations.Nonnull;
31 import org.apache.maven.api.annotations.NotThreadSafe;
32 import org.apache.maven.api.annotations.Nullable;
33
34 import static java.util.Objects.requireNonNull;
35
36 /**
37 * Request used to build a {@link org.apache.maven.api.Project} using
38 * the {@link ProjectBuilder} service.
39 *
40 * TODO: add validationLevel, activeProfileIds, inactiveProfileIds, resolveDependencies
41 *
42 * @since 4.0.0
43 */
44 @Experimental
45 @Immutable
46 public interface ProjectBuilderRequest extends RepositoryAwareRequest {
47
48 /**
49 * Gets the path to the project to build.
50 * This is typically the path to a pom.xml file or a directory containing a pom.xml file.
51 *
52 * @return an optional containing the path to the project, or empty if not specified
53 */
54 @Nonnull
55 Optional<Path> getPath();
56
57 /**
58 * Gets the source of the project to build.
59 * This is an alternative to specifying a path, allowing the project to be built from
60 * a model source such as a string or input stream.
61 *
62 * @return an optional containing the source of the project, or empty if not specified
63 */
64 @Nonnull
65 Optional<Source> getSource();
66
67 /**
68 * Determines whether a stub model should be allowed when the POM is missing or unreadable.
69 * A stub model contains only minimal information derived from the project's coordinates.
70 *
71 * @return true if a stub model should be allowed, false otherwise
72 */
73 boolean isAllowStubModel();
74
75 /**
76 * Determines whether the project builder should recursively build parent/child projects.
77 * When true, the builder will process parent POMs and child modules as needed.
78 *
79 * @return true if the build should be recursive, false otherwise
80 */
81 boolean isRecursive();
82
83 /**
84 * Determines whether plugins should be processed during project building.
85 * When true, the builder will process plugin information which may include
86 * resolving plugin dependencies and executing plugin goals that participate in project building.
87 *
88 * @return true if plugins should be processed, false otherwise
89 */
90 boolean isProcessPlugins();
91
92 /**
93 * Gets the list of remote repositories to use for resolving dependencies during project building.
94 * These repositories will be used in addition to any repositories defined in the project itself.
95 *
96 * @return the list of remote repositories, or null if not specified
97 */
98 @Nullable
99 List<RemoteRepository> getRepositories();
100
101 /**
102 * Creates a new ProjectBuilderRequest with the specified session and source.
103 *
104 * @param session the Maven session
105 * @param source the source of the project to build
106 * @return a new ProjectBuilderRequest
107 * @throws NullPointerException if session or source is null
108 */
109 @Nonnull
110 static ProjectBuilderRequest build(@Nonnull Session session, @Nonnull Source source) {
111 return builder()
112 .session(requireNonNull(session, "session cannot be null"))
113 .source(requireNonNull(source, "source cannot be null"))
114 .build();
115 }
116
117 /**
118 * Creates a new ProjectBuilderRequest with the specified session and path.
119 *
120 * @param session the Maven session
121 * @param path the path to the project to build
122 * @return a new ProjectBuilderRequest
123 * @throws NullPointerException if session or path is null
124 */
125 @Nonnull
126 static ProjectBuilderRequest build(@Nonnull Session session, @Nonnull Path path) {
127 return builder()
128 .session(requireNonNull(session, "session cannot be null"))
129 .path(requireNonNull(path, "path cannot be null"))
130 .build();
131 }
132
133 /**
134 * Creates a new builder for constructing a ProjectBuilderRequest.
135 *
136 * @return a new ProjectBuilderRequestBuilder
137 */
138 @Nonnull
139 static ProjectBuilderRequestBuilder builder() {
140 return new ProjectBuilderRequestBuilder();
141 }
142
143 /**
144 * Builder for creating ProjectBuilderRequest instances.
145 * This builder provides a fluent API for setting the various properties of a request.
146 */
147 @NotThreadSafe
148 class ProjectBuilderRequestBuilder {
149 Session session;
150 RequestTrace trace;
151 Path path;
152 Source source;
153 boolean allowStubModel;
154 boolean recursive;
155 boolean processPlugins = true;
156 List<RemoteRepository> repositories;
157
158 ProjectBuilderRequestBuilder() {}
159
160 /**
161 * Sets the Maven session for this request.
162 *
163 * @param session the Maven session
164 * @return this builder instance
165 */
166 public ProjectBuilderRequestBuilder session(Session session) {
167 this.session = session;
168 return this;
169 }
170
171 /**
172 * Sets the request trace for this request.
173 * The trace is used for debugging and monitoring purposes.
174 *
175 * @param trace the request trace
176 * @return this builder instance
177 */
178 public ProjectBuilderRequestBuilder trace(RequestTrace trace) {
179 this.trace = trace;
180 return this;
181 }
182
183 /**
184 * Sets the path to the project to build.
185 * This is typically the path to a pom.xml file or a directory containing a pom.xml file.
186 *
187 * @param path the path to the project
188 * @return this builder instance
189 */
190 public ProjectBuilderRequestBuilder path(Path path) {
191 this.path = path;
192 return this;
193 }
194
195 /**
196 * Sets the source of the project to build.
197 * This is an alternative to specifying a path, allowing the project to be built from
198 * a model source such as a string or input stream.
199 *
200 * @param source the source of the project
201 * @return this builder instance
202 */
203 public ProjectBuilderRequestBuilder source(Source source) {
204 this.source = source;
205 return this;
206 }
207
208 /**
209 * Sets whether plugins should be processed during project building.
210 * When true, the builder will process plugin information which may include
211 * resolving plugin dependencies and executing plugin goals that participate in project building.
212 *
213 * @param processPlugins true if plugins should be processed, false otherwise
214 * @return this builder instance
215 */
216 public ProjectBuilderRequestBuilder processPlugins(boolean processPlugins) {
217 this.processPlugins = processPlugins;
218 return this;
219 }
220
221 /**
222 * Sets the list of remote repositories to use for resolving dependencies during project building.
223 * These repositories will be used in addition to any repositories defined in the project itself.
224 *
225 * @param repositories the list of remote repositories
226 * @return this builder instance
227 */
228 public ProjectBuilderRequestBuilder repositories(List<RemoteRepository> repositories) {
229 this.repositories = repositories;
230 return this;
231 }
232
233 /**
234 * Builds a new ProjectBuilderRequest with the current builder settings.
235 *
236 * @return a new ProjectBuilderRequest instance
237 */
238 public ProjectBuilderRequest build() {
239 return new DefaultProjectBuilderRequest(
240 session, trace, path, source, allowStubModel, recursive, processPlugins, repositories);
241 }
242
243 private static class DefaultProjectBuilderRequest extends BaseRequest<Session>
244 implements ProjectBuilderRequest {
245 private final Path path;
246 private final Source source;
247 private final boolean allowStubModel;
248 private final boolean recursive;
249 private final boolean processPlugins;
250 private final List<RemoteRepository> repositories;
251
252 @SuppressWarnings("checkstyle:ParameterNumber")
253 DefaultProjectBuilderRequest(
254 @Nonnull Session session,
255 @Nullable RequestTrace trace,
256 @Nullable Path path,
257 @Nullable Source source,
258 boolean allowStubModel,
259 boolean recursive,
260 boolean processPlugins,
261 @Nullable List<RemoteRepository> repositories) {
262 super(session, trace);
263 this.path = path;
264 this.source = source;
265 this.allowStubModel = allowStubModel;
266 this.recursive = recursive;
267 this.processPlugins = processPlugins;
268 this.repositories = validate(repositories);
269 }
270
271 @Nonnull
272 @Override
273 public Optional<Path> getPath() {
274 return Optional.ofNullable(path);
275 }
276
277 @Nonnull
278 @Override
279 public Optional<Source> getSource() {
280 return Optional.ofNullable(source);
281 }
282
283 @Override
284 public boolean isAllowStubModel() {
285 return allowStubModel;
286 }
287
288 @Override
289 public boolean isRecursive() {
290 return recursive;
291 }
292
293 @Override
294 public boolean isProcessPlugins() {
295 return processPlugins;
296 }
297
298 @Override
299 public List<RemoteRepository> getRepositories() {
300 return repositories;
301 }
302
303 @Override
304 public boolean equals(Object o) {
305 return o instanceof DefaultProjectBuilderRequest that
306 && allowStubModel == that.allowStubModel
307 && recursive == that.recursive
308 && processPlugins == that.processPlugins
309 && Objects.equals(path, that.path)
310 && Objects.equals(source, that.source)
311 && Objects.equals(repositories, that.repositories);
312 }
313
314 @Override
315 public int hashCode() {
316 return Objects.hash(path, source, allowStubModel, recursive, processPlugins, repositories);
317 }
318
319 @Override
320 public String toString() {
321 return "ProjectBuilderRequest[" + "path="
322 + path + ", source="
323 + source + ", allowStubModel="
324 + allowStubModel + ", recursive="
325 + recursive + ", processPlugins="
326 + processPlugins + ", repositories="
327 + repositories + ']';
328 }
329 }
330 }
331 }