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 * This is the file specification used to activate the profile. The {@code missing} value
25 * is the location of a file that needs to exist, and if it doesn't, the profile will be
26 * activated. On the other hand, {@code exists} will test for the existence of the file and if it is
27 * there, the profile will be activated.
28 * <p>Variable interpolation for these file specifications is limited to {@code ${project.basedir}},
29 * system properties and user properties.</p>
30 */
31 @Experimental
32 @Generated @ThreadSafe @Immutable
33 public class ActivationFile
34 implements Serializable, InputLocationTracker
35 {
36 /**
37 * The name of the file that must be missing to activate the profile. Please note, that missing and exists
38 * fields cannot be used together. Only one of them should be used at any one time.
39 */
40 final String missing;
41 /**
42 * The name of the file that must exist to activate the profile. Please note, that missing and exists
43 * fields cannot be used together. Only one of them should be used at any one time.
44 */
45 final String exists;
46 /** Locations */
47 final Map<Object, InputLocation> locations;
48 /** Location tracking */
49 final InputLocation importedFrom;
50
51 /**
52 * Constructor for this class, to be called from its subclasses and {@link Builder}.
53 * @see Builder#build()
54 */
55 protected ActivationFile(Builder builder) {
56 this.missing = builder.missing != null ? builder.missing : (builder.base != null ? builder.base.missing : null);
57 this.exists = builder.exists != null ? builder.exists : (builder.base != null ? builder.base.exists : null);
58 this.locations = builder.computeLocations();
59 this.importedFrom = builder.importedFrom;
60 }
61
62 /**
63 * The name of the file that must be missing to activate the profile. Please note, that missing and exists
64 * fields cannot be used together. Only one of them should be used at any one time.
65 *
66 * @return a {@code String}
67 */
68 public String getMissing() {
69 return this.missing;
70 }
71
72 /**
73 * The name of the file that must exist to activate the profile. Please note, that missing and exists
74 * fields cannot be used together. Only one of them should be used at any one time.
75 *
76 * @return a {@code String}
77 */
78 public String getExists() {
79 return this.exists;
80 }
81
82 /**
83 * Gets the location of the specified field in the input source.
84 *
85 * @param key the key of the field, must not be {@code null}
86 * @return the location of the field in the input source or {@code null} if unknown
87 * @throws NullPointerException if {@code key} is {@code null}
88 */
89 public InputLocation getLocation(Object key) {
90 Objects.requireNonNull(key, "key");
91 return locations.get(key);
92 }
93
94 /**
95 * Gets the keys of the locations of the input source.
96 */
97 public Set<Object> getLocationKeys() {
98 return locations.keySet();
99 }
100
101 protected Stream<Object> getLocationKeyStream() {
102 return locations.keySet().stream();
103 }
104
105 /**
106 * Gets the input location that caused this model to be read.
107 */
108 public InputLocation getImportedFrom() {
109 return importedFrom;
110 }
111
112 /**
113 * Creates a new builder with this object as the basis.
114 *
115 * @return a {@code Builder}
116 */
117 @Nonnull
118 public Builder with() {
119 return newBuilder(this);
120 }
121 /**
122 * Creates a new {@code ActivationFile} instance using the specified missing.
123 *
124 * @param missing the new {@code String} to use
125 * @return a {@code ActivationFile} with the specified missing
126 */
127 @Nonnull
128 public ActivationFile withMissing(String missing) {
129 return newBuilder(this, true).missing(missing).build();
130 }
131 /**
132 * Creates a new {@code ActivationFile} instance using the specified exists.
133 *
134 * @param exists the new {@code String} to use
135 * @return a {@code ActivationFile} with the specified exists
136 */
137 @Nonnull
138 public ActivationFile withExists(String exists) {
139 return newBuilder(this, true).exists(exists).build();
140 }
141
142 /**
143 * Creates a new {@code ActivationFile} instance.
144 * Equivalent to {@code newInstance(true)}.
145 * @see #newInstance(boolean)
146 *
147 * @return a new {@code ActivationFile}
148 */
149 @Nonnull
150 public static ActivationFile newInstance() {
151 return newInstance(true);
152 }
153
154 /**
155 * Creates a new {@code ActivationFile} instance using default values or not.
156 * Equivalent to {@code newBuilder(withDefaults).build()}.
157 *
158 * @param withDefaults the boolean indicating whether default values should be used
159 * @return a new {@code ActivationFile}
160 */
161 @Nonnull
162 public static ActivationFile newInstance(boolean withDefaults) {
163 return newBuilder(withDefaults).build();
164 }
165
166 /**
167 * Creates a new {@code ActivationFile} builder instance.
168 * Equivalent to {@code newBuilder(true)}.
169 * @see #newBuilder(boolean)
170 *
171 * @return a new {@code Builder}
172 */
173 @Nonnull
174 public static Builder newBuilder() {
175 return newBuilder(true);
176 }
177
178 /**
179 * Creates a new {@code ActivationFile} builder instance using default values or not.
180 *
181 * @param withDefaults the boolean indicating whether default values should be used
182 * @return a new {@code Builder}
183 */
184 @Nonnull
185 public static Builder newBuilder(boolean withDefaults) {
186 return new Builder(withDefaults);
187 }
188
189 /**
190 * Creates a new {@code ActivationFile} builder instance using the specified object as a basis.
191 * Equivalent to {@code newBuilder(from, false)}.
192 *
193 * @param from the {@code ActivationFile} instance to use as a basis
194 * @return a new {@code Builder}
195 */
196 @Nonnull
197 public static Builder newBuilder(ActivationFile from) {
198 return newBuilder(from, false);
199 }
200
201 /**
202 * Creates a new {@code ActivationFile} builder instance using the specified object as a basis.
203 *
204 * @param from the {@code ActivationFile} instance to use as a basis
205 * @param forceCopy the boolean indicating if a copy should be forced
206 * @return a new {@code Builder}
207 */
208 @Nonnull
209 public static Builder newBuilder(ActivationFile from, boolean forceCopy) {
210 return new Builder(from, forceCopy);
211 }
212
213 /**
214 * Builder class used to create ActivationFile instances.
215 * @see #with()
216 * @see #newBuilder()
217 */
218 @NotThreadSafe
219 public static class Builder
220 {
221 ActivationFile base;
222 String missing;
223 String exists;
224 Map<Object, InputLocation> locations;
225 InputLocation importedFrom;
226
227 protected Builder(boolean withDefaults) {
228 if (withDefaults) {
229 }
230 }
231
232 protected Builder(ActivationFile base, boolean forceCopy) {
233 if (forceCopy) {
234 this.missing = base.missing;
235 this.exists = base.exists;
236 this.locations = base.locations;
237 this.importedFrom = base.importedFrom;
238 } else {
239 this.base = base;
240 }
241 }
242
243 @Nonnull
244 public Builder missing(String missing) {
245 this.missing = missing;
246 return this;
247 }
248
249 @Nonnull
250 public Builder exists(String exists) {
251 this.exists = exists;
252 return this;
253 }
254
255
256 @Nonnull
257 public Builder location(Object key, InputLocation location) {
258 if (location != null) {
259 if (!(this.locations instanceof HashMap)) {
260 this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
261 }
262 this.locations.put(key, location);
263 }
264 return this;
265 }
266
267 @Nonnull
268 public Builder importedFrom(InputLocation importedFrom) {
269 this.importedFrom = importedFrom;
270 return this;
271 }
272
273 @Nonnull
274 public ActivationFile build() {
275 // this method should not contain any logic other than creating (or reusing) an object in order to ease subclassing
276 if (base != null
277 && (missing == null || missing == base.missing)
278 && (exists == null || exists == base.exists)
279 ) {
280 return base;
281 }
282 return new ActivationFile(this);
283 }
284
285 Map<Object, InputLocation> computeLocations() {
286 Map<Object, InputLocation> newlocs = locations != null ? locations : Map.of();
287 Map<Object, InputLocation> oldlocs = base != null ? base.locations : Map.of();
288 if (newlocs.isEmpty()) {
289 return Map.copyOf(oldlocs);
290 }
291 if (oldlocs.isEmpty()) {
292 return Map.copyOf(newlocs);
293 }
294 return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream())
295 // Keep value from newlocs in case of duplicates
296 .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
297 }
298 }
299
300 }