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 * A repository contains the information needed for establishing connections with
25 * remote repository.
26 */
27 @Experimental
28 @Generated @ThreadSafe @Immutable
29 public class RepositoryBase
30 implements Serializable, InputLocationTracker
31 {
32 /**
33 * A unique identifier for a repository. This is used to match the repository
34 * to configuration in the {@code settings.xml} file, for example. Furthermore, the identifier is
35 * used during POM inheritance and profile injection to detect repositories that should be merged.
36 */
37 final String id;
38 /**
39 * Human readable name of the repository.
40 */
41 final String name;
42 /**
43 * The url of the repository, in the form {@code protocol://hostname/path}.
44 */
45 final String url;
46 /**
47 * The type of layout this repository uses for locating and storing artifacts -
48 * can be {@code legacy} or {@code default}.
49 */
50 final String layout;
51 /** Locations */
52 final Map<Object, InputLocation> locations;
53 /** Location tracking */
54 final InputLocation importedFrom;
55
56 /**
57 * Constructor for this class, to be called from its subclasses and {@link Builder}.
58 * @see Builder#build()
59 */
60 protected RepositoryBase(Builder builder) {
61 this.id = builder.id != null ? builder.id : (builder.base != null ? builder.base.id : null);
62 this.name = builder.name != null ? builder.name : (builder.base != null ? builder.base.name : null);
63 this.url = builder.url != null ? builder.url : (builder.base != null ? builder.base.url : null);
64 this.layout = builder.layout != null ? builder.layout : (builder.base != null ? builder.base.layout : null);
65 this.locations = builder.computeLocations();
66 this.importedFrom = builder.importedFrom;
67 }
68
69 @Override
70 public boolean equals(Object o) {
71 if (this == o) {
72 return true;
73 }
74 if (o == null || !(o instanceof RepositoryBase)) {
75 return false;
76 }
77 RepositoryBase that = (RepositoryBase) o;
78 return Objects.equals( this.id, that.id );
79 }
80
81 @Override
82 public int hashCode() {
83 return Objects.hash(id);
84 }
85
86 /**
87 * A unique identifier for a repository. This is used to match the repository
88 * to configuration in the {@code settings.xml} file, for example. Furthermore, the identifier is
89 * used during POM inheritance and profile injection to detect repositories that should be merged.
90 *
91 * @return a {@code String}
92 */
93 public String getId() {
94 return this.id;
95 }
96
97 /**
98 * Human readable name of the repository.
99 *
100 * @return a {@code String}
101 */
102 public String getName() {
103 return this.name;
104 }
105
106 /**
107 * The url of the repository, in the form {@code protocol://hostname/path}.
108 *
109 * @return a {@code String}
110 */
111 public String getUrl() {
112 return this.url;
113 }
114
115 /**
116 * The type of layout this repository uses for locating and storing artifacts -
117 * can be {@code legacy} or {@code default}.
118 *
119 * @return a {@code String}
120 */
121 public String getLayout() {
122 return this.layout;
123 }
124
125 /**
126 * Gets the location of the specified field in the input source.
127 *
128 * @param key the key of the field, must not be {@code null}
129 * @return the location of the field in the input source or {@code null} if unknown
130 * @throws NullPointerException if {@code key} is {@code null}
131 */
132 public InputLocation getLocation(Object key) {
133 Objects.requireNonNull(key, "key");
134 return locations.get(key);
135 }
136
137 /**
138 * Gets the keys of the locations of the input source.
139 */
140 public Set<Object> getLocationKeys() {
141 return locations.keySet();
142 }
143
144 protected Stream<Object> getLocationKeyStream() {
145 return locations.keySet().stream();
146 }
147
148 /**
149 * Gets the input location that caused this model to be read.
150 */
151 public InputLocation getImportedFrom() {
152 return importedFrom;
153 }
154
155 /**
156 * Creates a new builder with this object as the basis.
157 *
158 * @return a {@code Builder}
159 */
160 @Nonnull
161 public Builder with() {
162 return newBuilder(this);
163 }
164 /**
165 * Creates a new {@code RepositoryBase} instance using the specified id.
166 *
167 * @param id the new {@code String} to use
168 * @return a {@code RepositoryBase} with the specified id
169 */
170 @Nonnull
171 public RepositoryBase withId(String id) {
172 return newBuilder(this, true).id(id).build();
173 }
174 /**
175 * Creates a new {@code RepositoryBase} instance using the specified name.
176 *
177 * @param name the new {@code String} to use
178 * @return a {@code RepositoryBase} with the specified name
179 */
180 @Nonnull
181 public RepositoryBase withName(String name) {
182 return newBuilder(this, true).name(name).build();
183 }
184 /**
185 * Creates a new {@code RepositoryBase} instance using the specified url.
186 *
187 * @param url the new {@code String} to use
188 * @return a {@code RepositoryBase} with the specified url
189 */
190 @Nonnull
191 public RepositoryBase withUrl(String url) {
192 return newBuilder(this, true).url(url).build();
193 }
194 /**
195 * Creates a new {@code RepositoryBase} instance using the specified layout.
196 *
197 * @param layout the new {@code String} to use
198 * @return a {@code RepositoryBase} with the specified layout
199 */
200 @Nonnull
201 public RepositoryBase withLayout(String layout) {
202 return newBuilder(this, true).layout(layout).build();
203 }
204
205 /**
206 * Creates a new {@code RepositoryBase} instance.
207 * Equivalent to {@code newInstance(true)}.
208 * @see #newInstance(boolean)
209 *
210 * @return a new {@code RepositoryBase}
211 */
212 @Nonnull
213 public static RepositoryBase newInstance() {
214 return newInstance(true);
215 }
216
217 /**
218 * Creates a new {@code RepositoryBase} instance using default values or not.
219 * Equivalent to {@code newBuilder(withDefaults).build()}.
220 *
221 * @param withDefaults the boolean indicating whether default values should be used
222 * @return a new {@code RepositoryBase}
223 */
224 @Nonnull
225 public static RepositoryBase newInstance(boolean withDefaults) {
226 return newBuilder(withDefaults).build();
227 }
228
229 /**
230 * Creates a new {@code RepositoryBase} builder instance.
231 * Equivalent to {@code newBuilder(true)}.
232 * @see #newBuilder(boolean)
233 *
234 * @return a new {@code Builder}
235 */
236 @Nonnull
237 public static Builder newBuilder() {
238 return newBuilder(true);
239 }
240
241 /**
242 * Creates a new {@code RepositoryBase} builder instance using default values or not.
243 *
244 * @param withDefaults the boolean indicating whether default values should be used
245 * @return a new {@code Builder}
246 */
247 @Nonnull
248 public static Builder newBuilder(boolean withDefaults) {
249 return new Builder(withDefaults);
250 }
251
252 /**
253 * Creates a new {@code RepositoryBase} builder instance using the specified object as a basis.
254 * Equivalent to {@code newBuilder(from, false)}.
255 *
256 * @param from the {@code RepositoryBase} instance to use as a basis
257 * @return a new {@code Builder}
258 */
259 @Nonnull
260 public static Builder newBuilder(RepositoryBase from) {
261 return newBuilder(from, false);
262 }
263
264 /**
265 * Creates a new {@code RepositoryBase} builder instance using the specified object as a basis.
266 *
267 * @param from the {@code RepositoryBase} instance to use as a basis
268 * @param forceCopy the boolean indicating if a copy should be forced
269 * @return a new {@code Builder}
270 */
271 @Nonnull
272 public static Builder newBuilder(RepositoryBase from, boolean forceCopy) {
273 return new Builder(from, forceCopy);
274 }
275
276 /**
277 * Builder class used to create RepositoryBase instances.
278 * @see #with()
279 * @see #newBuilder()
280 */
281 @NotThreadSafe
282 public static class Builder
283 {
284 RepositoryBase base;
285 String id;
286 String name;
287 String url;
288 String layout;
289 Map<Object, InputLocation> locations;
290 InputLocation importedFrom;
291
292 protected Builder(boolean withDefaults) {
293 if (withDefaults) {
294 this.layout = "default";
295 }
296 }
297
298 protected Builder(RepositoryBase base, boolean forceCopy) {
299 if (forceCopy) {
300 this.id = base.id;
301 this.name = base.name;
302 this.url = base.url;
303 this.layout = base.layout;
304 this.locations = base.locations;
305 this.importedFrom = base.importedFrom;
306 } else {
307 this.base = base;
308 }
309 }
310
311 @Nonnull
312 public Builder id(String id) {
313 this.id = id;
314 return this;
315 }
316
317 @Nonnull
318 public Builder name(String name) {
319 this.name = name;
320 return this;
321 }
322
323 @Nonnull
324 public Builder url(String url) {
325 this.url = url;
326 return this;
327 }
328
329 @Nonnull
330 public Builder layout(String layout) {
331 this.layout = layout;
332 return this;
333 }
334
335
336 @Nonnull
337 public Builder location(Object key, InputLocation location) {
338 if (location != null) {
339 if (!(this.locations instanceof HashMap)) {
340 this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
341 }
342 this.locations.put(key, location);
343 }
344 return this;
345 }
346
347 @Nonnull
348 public Builder importedFrom(InputLocation importedFrom) {
349 this.importedFrom = importedFrom;
350 return this;
351 }
352
353 @Nonnull
354 public RepositoryBase build() {
355 // this method should not contain any logic other than creating (or reusing) an object in order to ease subclassing
356 if (base != null
357 && (id == null || id == base.id)
358 && (name == null || name == base.name)
359 && (url == null || url == base.url)
360 && (layout == null || layout == base.layout)
361 ) {
362 return base;
363 }
364 return new RepositoryBase(this);
365 }
366
367 Map<Object, InputLocation> computeLocations() {
368 Map<Object, InputLocation> newlocs = locations != null ? locations : Map.of();
369 Map<Object, InputLocation> oldlocs = base != null ? base.locations : Map.of();
370 if (newlocs.isEmpty()) {
371 return Map.copyOf(oldlocs);
372 }
373 if (oldlocs.isEmpty()) {
374 return Map.copyOf(newlocs);
375 }
376 return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream())
377 // Keep value from newlocs in case of duplicates
378 .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
379 }
380 }
381
382 }