1 // =================== DO NOT EDIT THIS FILE ====================
2 // Generated by Modello Velocity from model.vm
3 // template, any modifications will be overwritten.
4 // ==============================================================
5 package org.apache.maven.api.model;
6
7 import java.io.Serializable;
8 import java.util.Collections;
9 import java.util.HashMap;
10 import java.util.Map;
11 import java.util.Objects;
12 import java.util.Optional;
13 import java.util.Set;
14 import java.util.stream.Collectors;
15 import java.util.stream.Stream;
16 import org.apache.maven.api.annotations.Experimental;
17 import org.apache.maven.api.annotations.Generated;
18 import org.apache.maven.api.annotations.Immutable;
19 import org.apache.maven.api.annotations.Nonnull;
20 import org.apache.maven.api.annotations.NotThreadSafe;
21 import org.apache.maven.api.annotations.ThreadSafe;
22
23 /**
24 * The {@code <parent>} element contains information required to locate the parent project from which
25 * this project will inherit from.
26 * <p><strong>Note:</strong> The children of this element are not interpolated and must be given as literal values.</p>
27 */
28 @Experimental
29 @Generated @ThreadSafe @Immutable
30 public class Parent
31 implements Serializable, InputLocationTracker
32 {
33 /**
34 * The group id of the parent project to inherit from.
35 */
36 final String groupId;
37 /**
38 * The artifact id of the parent project to inherit from.
39 */
40 final String artifactId;
41 /**
42 * The version of the parent project to inherit.
43 */
44 final String version;
45 /**
46 * The relative path of the parent subproject POM file or directory within the checkout.
47 * If not specified, it defaults to {@code ..}, i.e. the parent directory.
48 * Maven looks for the parent POM first in this location on
49 * the filesystem if explicitly provided, then in the reactor if groupId and artifactId are provided,
50 * then in the default parent directory, then the local repository, and lastly in the remote repo.
51 * However, if the both relative path and the group ID / artifact ID are provided,
52 * they must match the file in the location given.
53 * Specify either the {@code relativePath} or the {@code groupId}/{@code artifactId}, not both.
54 */
55 final String relativePath;
56 /** Locations */
57 final Map<Object, InputLocation> locations;
58 /** Location tracking */
59 final InputLocation importedFrom;
60
61 /**
62 * Constructor for this class, to be called from its subclasses and {@link Builder}.
63 * @see Builder#build()
64 */
65 protected Parent(Builder builder) {
66 this.groupId = builder.groupId != null ? builder.groupId : (builder.base != null ? builder.base.groupId : null);
67 this.artifactId = builder.artifactId != null ? builder.artifactId : (builder.base != null ? builder.base.artifactId : null);
68 this.version = builder.version != null ? builder.version : (builder.base != null ? builder.base.version : null);
69 this.relativePath = builder.relativePath != null ? builder.relativePath : (builder.base != null ? builder.base.relativePath : null);
70 this.locations = builder.computeLocations();
71 this.importedFrom = builder.importedFrom;
72 }
73
74 /**
75 * The group id of the parent project to inherit from.
76 *
77 * @return a {@code String}
78 */
79 public String getGroupId() {
80 return this.groupId;
81 }
82
83 /**
84 * The artifact id of the parent project to inherit from.
85 *
86 * @return a {@code String}
87 */
88 public String getArtifactId() {
89 return this.artifactId;
90 }
91
92 /**
93 * The version of the parent project to inherit.
94 *
95 * @return a {@code String}
96 */
97 public String getVersion() {
98 return this.version;
99 }
100
101 /**
102 * The relative path of the parent subproject POM file or directory within the checkout.
103 * If not specified, it defaults to {@code ..}, i.e. the parent directory.
104 * Maven looks for the parent POM first in this location on
105 * the filesystem if explicitly provided, then in the reactor if groupId and artifactId are provided,
106 * then in the default parent directory, then the local repository, and lastly in the remote repo.
107 * However, if the both relative path and the group ID / artifact ID are provided,
108 * they must match the file in the location given.
109 * Specify either the {@code relativePath} or the {@code groupId}/{@code artifactId}, not both.
110 *
111 * @return a {@code String}
112 */
113 public String getRelativePath() {
114 return this.relativePath;
115 }
116
117 /**
118 * Gets the location of the specified field in the input source.
119 */
120 public InputLocation getLocation(Object key) {
121 return locations.get(key);
122 }
123
124 /**
125 * Gets the keys of the locations of the input source.
126 */
127 public Set<Object> getLocationKeys() {
128 return locations.keySet();
129 }
130
131 protected Stream<Object> getLocationKeyStream() {
132 return locations.keySet().stream();
133 }
134
135 /**
136 * Gets the input location that caused this model to be read.
137 */
138 public InputLocation getImportedFrom() {
139 return importedFrom;
140 }
141
142 /**
143 * Creates a new builder with this object as the basis.
144 *
145 * @return a {@code Builder}
146 */
147 @Nonnull
148 public Builder with() {
149 return newBuilder(this);
150 }
151 /**
152 * Creates a new {@code Parent} instance using the specified groupId.
153 *
154 * @param groupId the new {@code String} to use
155 * @return a {@code Parent} with the specified groupId
156 */
157 @Nonnull
158 public Parent withGroupId(String groupId) {
159 return newBuilder(this, true).groupId(groupId).build();
160 }
161 /**
162 * Creates a new {@code Parent} instance using the specified artifactId.
163 *
164 * @param artifactId the new {@code String} to use
165 * @return a {@code Parent} with the specified artifactId
166 */
167 @Nonnull
168 public Parent withArtifactId(String artifactId) {
169 return newBuilder(this, true).artifactId(artifactId).build();
170 }
171 /**
172 * Creates a new {@code Parent} instance using the specified version.
173 *
174 * @param version the new {@code String} to use
175 * @return a {@code Parent} with the specified version
176 */
177 @Nonnull
178 public Parent withVersion(String version) {
179 return newBuilder(this, true).version(version).build();
180 }
181 /**
182 * Creates a new {@code Parent} instance using the specified relativePath.
183 *
184 * @param relativePath the new {@code String} to use
185 * @return a {@code Parent} with the specified relativePath
186 */
187 @Nonnull
188 public Parent withRelativePath(String relativePath) {
189 return newBuilder(this, true).relativePath(relativePath).build();
190 }
191
192 /**
193 * Creates a new {@code Parent} instance.
194 * Equivalent to {@code newInstance(true)}.
195 * @see #newInstance(boolean)
196 *
197 * @return a new {@code Parent}
198 */
199 @Nonnull
200 public static Parent newInstance() {
201 return newInstance(true);
202 }
203
204 /**
205 * Creates a new {@code Parent} instance using default values or not.
206 * Equivalent to {@code newBuilder(withDefaults).build()}.
207 *
208 * @param withDefaults the boolean indicating whether default values should be used
209 * @return a new {@code Parent}
210 */
211 @Nonnull
212 public static Parent newInstance(boolean withDefaults) {
213 return newBuilder(withDefaults).build();
214 }
215
216 /**
217 * Creates a new {@code Parent} builder instance.
218 * Equivalent to {@code newBuilder(true)}.
219 * @see #newBuilder(boolean)
220 *
221 * @return a new {@code Builder}
222 */
223 @Nonnull
224 public static Builder newBuilder() {
225 return newBuilder(true);
226 }
227
228 /**
229 * Creates a new {@code Parent} builder instance using default values or not.
230 *
231 * @param withDefaults the boolean indicating whether default values should be used
232 * @return a new {@code Builder}
233 */
234 @Nonnull
235 public static Builder newBuilder(boolean withDefaults) {
236 return new Builder(withDefaults);
237 }
238
239 /**
240 * Creates a new {@code Parent} builder instance using the specified object as a basis.
241 * Equivalent to {@code newBuilder(from, false)}.
242 *
243 * @param from the {@code Parent} instance to use as a basis
244 * @return a new {@code Builder}
245 */
246 @Nonnull
247 public static Builder newBuilder(Parent from) {
248 return newBuilder(from, false);
249 }
250
251 /**
252 * Creates a new {@code Parent} builder instance using the specified object as a basis.
253 *
254 * @param from the {@code Parent} instance to use as a basis
255 * @param forceCopy the boolean indicating if a copy should be forced
256 * @return a new {@code Builder}
257 */
258 @Nonnull
259 public static Builder newBuilder(Parent from, boolean forceCopy) {
260 return new Builder(from, forceCopy);
261 }
262
263 /**
264 * Builder class used to create Parent instances.
265 * @see #with()
266 * @see #newBuilder()
267 */
268 @NotThreadSafe
269 public static class Builder
270 {
271 Parent base;
272 String groupId;
273 String artifactId;
274 String version;
275 String relativePath;
276 Map<Object, InputLocation> locations;
277 InputLocation importedFrom;
278
279 protected Builder(boolean withDefaults) {
280 if (withDefaults) {
281 }
282 }
283
284 protected Builder(Parent base, boolean forceCopy) {
285 if (forceCopy) {
286 this.groupId = base.groupId;
287 this.artifactId = base.artifactId;
288 this.version = base.version;
289 this.relativePath = base.relativePath;
290 this.locations = base.locations;
291 this.importedFrom = base.importedFrom;
292 } else {
293 this.base = base;
294 }
295 }
296
297 @Nonnull
298 public Builder groupId(String groupId) {
299 this.groupId = groupId;
300 return this;
301 }
302
303 @Nonnull
304 public Builder artifactId(String artifactId) {
305 this.artifactId = artifactId;
306 return this;
307 }
308
309 @Nonnull
310 public Builder version(String version) {
311 this.version = version;
312 return this;
313 }
314
315 @Nonnull
316 public Builder relativePath(String relativePath) {
317 this.relativePath = relativePath;
318 return this;
319 }
320
321
322 @Nonnull
323 public Builder location(Object key, InputLocation location) {
324 if (location != null) {
325 if (!(this.locations instanceof HashMap)) {
326 this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
327 }
328 this.locations.put(key, location);
329 }
330 return this;
331 }
332
333 @Nonnull
334 public Builder importedFrom(InputLocation importedFrom) {
335 this.importedFrom = importedFrom;
336 return this;
337 }
338
339 @Nonnull
340 public Parent build() {
341 // this method should not contain any logic other than creating (or reusing) an object in order to ease subclassing
342 if (base != null
343 && (groupId == null || groupId == base.groupId)
344 && (artifactId == null || artifactId == base.artifactId)
345 && (version == null || version == base.version)
346 && (relativePath == null || relativePath == base.relativePath)
347 ) {
348 return base;
349 }
350 return new Parent(this);
351 }
352
353 Map<Object, InputLocation> computeLocations() {
354 Map<Object, InputLocation> newlocs = locations != null ? locations : Map.of();
355 Map<Object, InputLocation> oldlocs = base != null ? base.locations : Map.of();
356 if (newlocs.isEmpty()) {
357 return Map.copyOf(oldlocs);
358 }
359 if (oldlocs.isEmpty()) {
360 return Map.copyOf(newlocs);
361 }
362 return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream())
363 // Keep value from newlocs in case of duplicates
364 .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
365 }
366 }
367
368
369
370 /**
371 * @return the id as {@code groupId:artifactId:version}
372 */
373 public String getId() {
374 return getGroupId() + ":" + getArtifactId() + ":pom:" + getVersion();
375 }
376
377 @Override
378 public String toString() {
379 return getId();
380 }
381
382
383 }