1
2
3
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 import org.apache.maven.api.xml.XmlNode;
23
24
25
26
27 @Experimental
28 @Generated @ThreadSafe @Immutable
29 public class ConfigurationContainer
30 implements Serializable, InputLocationTracker
31 {
32
33
34
35
36
37 final String inherited;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 final XmlNode configuration;
53
54 final Map<Object, InputLocation> locations;
55
56 final InputLocation importedFrom;
57
58
59
60
61
62 protected ConfigurationContainer(Builder builder) {
63 this.inherited = builder.inherited != null ? builder.inherited : (builder.base != null ? builder.base.inherited : null);
64 this.configuration = builder.configuration != null ? builder.configuration : (builder.base != null ? builder.base.configuration : null);
65 this.locations = builder.computeLocations();
66 this.importedFrom = builder.importedFrom;
67 }
68
69
70
71
72
73
74
75
76 public String getInherited() {
77 return this.inherited;
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public XmlNode getConfiguration() {
97 return this.configuration;
98 }
99
100
101
102
103 public InputLocation getLocation(Object key) {
104 return locations.get(key);
105 }
106
107
108
109
110 public Set<Object> getLocationKeys() {
111 return locations.keySet();
112 }
113
114 protected Stream<Object> getLocationKeyStream() {
115 return locations.keySet().stream();
116 }
117
118
119
120
121 public InputLocation getImportedFrom()
122 {
123 return importedFrom;
124 }
125
126
127
128
129
130
131 @Nonnull
132 public Builder with() {
133 return newBuilder(this);
134 }
135
136
137
138
139
140
141 @Nonnull
142 public ConfigurationContainer withInherited(String inherited) {
143 return newBuilder(this, true).inherited(inherited).build();
144 }
145
146
147
148
149
150
151 @Nonnull
152 public ConfigurationContainer withConfiguration(XmlNode configuration) {
153 return newBuilder(this, true).configuration(configuration).build();
154 }
155
156
157
158
159
160
161
162
163 @Nonnull
164 public static ConfigurationContainer newInstance() {
165 return newInstance(true);
166 }
167
168
169
170
171
172
173
174
175 @Nonnull
176 public static ConfigurationContainer newInstance(boolean withDefaults) {
177 return newBuilder(withDefaults).build();
178 }
179
180
181
182
183
184
185
186
187 @Nonnull
188 public static Builder newBuilder() {
189 return newBuilder(true);
190 }
191
192
193
194
195
196
197
198 @Nonnull
199 public static Builder newBuilder(boolean withDefaults) {
200 return new Builder(withDefaults);
201 }
202
203
204
205
206
207
208
209
210 @Nonnull
211 public static Builder newBuilder(ConfigurationContainer from) {
212 return newBuilder(from, false);
213 }
214
215
216
217
218
219
220
221
222 @Nonnull
223 public static Builder newBuilder(ConfigurationContainer from, boolean forceCopy) {
224 return new Builder(from, forceCopy);
225 }
226
227
228
229
230
231
232 @NotThreadSafe
233 public static class Builder
234 {
235 ConfigurationContainer base;
236 String inherited;
237 XmlNode configuration;
238 Map<Object, InputLocation> locations;
239 InputLocation importedFrom;
240
241 protected Builder(boolean withDefaults) {
242 if (withDefaults) {
243 }
244 }
245
246 protected Builder(ConfigurationContainer base, boolean forceCopy) {
247 if (forceCopy) {
248 this.inherited = base.inherited;
249 this.configuration = base.configuration;
250 this.locations = base.locations;
251 this.importedFrom = base.importedFrom;
252 } else {
253 this.base = base;
254 }
255 }
256
257 @Nonnull
258 public Builder inherited(String inherited) {
259 this.inherited = inherited;
260 return this;
261 }
262
263 @Nonnull
264 public Builder configuration(XmlNode configuration) {
265 this.configuration = configuration;
266 return this;
267 }
268
269
270 @Nonnull
271 public Builder location(Object key, InputLocation location) {
272 if (location != null) {
273 if (!(this.locations instanceof HashMap)) {
274 this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
275 }
276 this.locations.put(key, location);
277 }
278 return this;
279 }
280
281 @Nonnull
282 public Builder importedFrom(InputLocation importedFrom) {
283 this.importedFrom = importedFrom;
284 return this;
285 }
286
287 @Nonnull
288 public ConfigurationContainer build() {
289
290 if (base != null
291 && (inherited == null || inherited == base.inherited)
292 && (configuration == null || configuration == base.configuration)
293 ) {
294 return base;
295 }
296 return new ConfigurationContainer(this);
297 }
298
299 Map<Object, InputLocation> computeLocations() {
300 Map<Object, InputLocation> newlocs = locations != null ? locations : Map.of();
301 Map<Object, InputLocation> oldlocs = base != null ? base.locations : Map.of();
302 if (newlocs.isEmpty()) {
303 return Map.copyOf(oldlocs);
304 }
305 if (oldlocs.isEmpty()) {
306 return Map.copyOf(newlocs);
307 }
308 return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream())
309
310 .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
311 }
312 }
313
314
315
316 public boolean isInherited() {
317 return ( getInherited() != null ) ? Boolean.parseBoolean( getInherited() ) : true;
318 }
319
320
321
322 }