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 public InputLocation getLocation(Object key) {
86 return locations.get(key);
87 }
88
89 /**
90 * Gets the keys of the locations of the input source.
91 */
92 public Set<Object> getLocationKeys() {
93 return locations.keySet();
94 }
95
96 protected Stream<Object> getLocationKeyStream() {
97 return locations.keySet().stream();
98 }
99
100 /**
101 * Gets the input location that caused this model to be read.
102 */
103 public InputLocation getImportedFrom()
104 {
105 return importedFrom;
106 }
107
108 /**
109 * Creates a new builder with this object as the basis.
110 *
111 * @return a {@code Builder}
112 */
113 @Nonnull
114 public Builder with() {
115 return newBuilder(this);
116 }
117 /**
118 * Creates a new {@code ActivationFile} instance using the specified missing.
119 *
120 * @param missing the new {@code String} to use
121 * @return a {@code ActivationFile} with the specified missing
122 */
123 @Nonnull
124 public ActivationFile withMissing(String missing) {
125 return newBuilder(this, true).missing(missing).build();
126 }
127 /**
128 * Creates a new {@code ActivationFile} instance using the specified exists.
129 *
130 * @param exists the new {@code String} to use
131 * @return a {@code ActivationFile} with the specified exists
132 */
133 @Nonnull
134 public ActivationFile withExists(String exists) {
135 return newBuilder(this, true).exists(exists).build();
136 }
137
138 /**
139 * Creates a new {@code ActivationFile} instance.
140 * Equivalent to {@code newInstance(true)}.
141 * @see #newInstance(boolean)
142 *
143 * @return a new {@code ActivationFile}
144 */
145 @Nonnull
146 public static ActivationFile newInstance() {
147 return newInstance(true);
148 }
149
150 /**
151 * Creates a new {@code ActivationFile} instance using default values or not.
152 * Equivalent to {@code newBuilder(withDefaults).build()}.
153 *
154 * @param withDefaults the boolean indicating whether default values should be used
155 * @return a new {@code ActivationFile}
156 */
157 @Nonnull
158 public static ActivationFile newInstance(boolean withDefaults) {
159 return newBuilder(withDefaults).build();
160 }
161
162 /**
163 * Creates a new {@code ActivationFile} builder instance.
164 * Equivalent to {@code newBuilder(true)}.
165 * @see #newBuilder(boolean)
166 *
167 * @return a new {@code Builder}
168 */
169 @Nonnull
170 public static Builder newBuilder() {
171 return newBuilder(true);
172 }
173
174 /**
175 * Creates a new {@code ActivationFile} builder instance using default values or not.
176 *
177 * @param withDefaults the boolean indicating whether default values should be used
178 * @return a new {@code Builder}
179 */
180 @Nonnull
181 public static Builder newBuilder(boolean withDefaults) {
182 return new Builder(withDefaults);
183 }
184
185 /**
186 * Creates a new {@code ActivationFile} builder instance using the specified object as a basis.
187 * Equivalent to {@code newBuilder(from, false)}.
188 *
189 * @param from the {@code ActivationFile} instance to use as a basis
190 * @return a new {@code Builder}
191 */
192 @Nonnull
193 public static Builder newBuilder(ActivationFile from) {
194 return newBuilder(from, false);
195 }
196
197 /**
198 * Creates a new {@code ActivationFile} builder instance using the specified object as a basis.
199 *
200 * @param from the {@code ActivationFile} instance to use as a basis
201 * @param forceCopy the boolean indicating if a copy should be forced
202 * @return a new {@code Builder}
203 */
204 @Nonnull
205 public static Builder newBuilder(ActivationFile from, boolean forceCopy) {
206 return new Builder(from, forceCopy);
207 }
208
209 /**
210 * Builder class used to create ActivationFile instances.
211 * @see #with()
212 * @see #newBuilder()
213 */
214 @NotThreadSafe
215 public static class Builder
216 {
217 ActivationFile base;
218 String missing;
219 String exists;
220 Map<Object, InputLocation> locations;
221 InputLocation importedFrom;
222
223 protected Builder(boolean withDefaults) {
224 if (withDefaults) {
225 }
226 }
227
228 protected Builder(ActivationFile base, boolean forceCopy) {
229 if (forceCopy) {
230 this.missing = base.missing;
231 this.exists = base.exists;
232 this.locations = base.locations;
233 this.importedFrom = base.importedFrom;
234 } else {
235 this.base = base;
236 }
237 }
238
239 @Nonnull
240 public Builder missing(String missing) {
241 this.missing = missing;
242 return this;
243 }
244
245 @Nonnull
246 public Builder exists(String exists) {
247 this.exists = exists;
248 return this;
249 }
250
251
252 @Nonnull
253 public Builder location(Object key, InputLocation location) {
254 if (location != null) {
255 if (!(this.locations instanceof HashMap)) {
256 this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
257 }
258 this.locations.put(key, location);
259 }
260 return this;
261 }
262
263 @Nonnull
264 public Builder importedFrom(InputLocation importedFrom) {
265 this.importedFrom = importedFrom;
266 return this;
267 }
268
269 @Nonnull
270 public ActivationFile build() {
271 // this method should not contain any logic other than creating (or reusing) an object in order to ease subclassing
272 if (base != null
273 && (missing == null || missing == base.missing)
274 && (exists == null || exists == base.exists)
275 ) {
276 return base;
277 }
278 return new ActivationFile(this);
279 }
280
281 Map<Object, InputLocation> computeLocations() {
282 Map<Object, InputLocation> newlocs = locations != null ? locations : Map.of();
283 Map<Object, InputLocation> oldlocs = base != null ? base.locations : Map.of();
284 if (newlocs.isEmpty()) {
285 return Map.copyOf(oldlocs);
286 }
287 if (oldlocs.isEmpty()) {
288 return Map.copyOf(newlocs);
289 }
290 return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream())
291 // Keep value from newlocs in case of duplicates
292 .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
293 }
294 }
295
296 }