View Javadoc
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 }