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.settings;
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   * Common base class that contains code to track the source for this instance.
25   */
26  @Experimental
27  @Generated @ThreadSafe @Immutable
28  public class TrackableBase
29      implements Serializable, InputLocationTracker
30  {
31      /** Locations */
32      final Map<Object, InputLocation> locations;
33      /** Location tracking */
34      final InputLocation importedFrom;
35  
36      /**
37        * Constructor for this class, to be called from its subclasses and {@link Builder}.
38        * @see Builder#build()
39        */
40      protected TrackableBase(Builder builder) {
41          this.locations = builder.computeLocations();
42          this.importedFrom = builder.importedFrom;
43      }
44  
45      /**
46       * Gets the location of the specified field in the input source.
47       *
48       * @param key the key of the field, must not be {@code null}
49       * @return the location of the field in the input source or {@code null} if unknown
50       * @throws NullPointerException if {@code key} is {@code null}
51       */
52      public InputLocation getLocation(Object key) {
53          Objects.requireNonNull(key, "key");
54          return locations.get(key);
55      }
56  
57      /**
58       * Gets the keys of the locations of the input source.
59       */
60      public Set<Object> getLocationKeys() {
61          return locations.keySet();
62      }
63  
64      protected Stream<Object> getLocationKeyStream() {
65          return locations.keySet().stream();
66      }
67  
68      /**
69       * Gets the input location that caused this model to be read.
70       */
71      public InputLocation getImportedFrom() {
72          return importedFrom;
73      }
74  
75      /**
76       * Creates a new builder with this object as the basis.
77       *
78       * @return a {@code Builder}
79       */
80      @Nonnull
81      public Builder with() {
82          return newBuilder(this);
83      }
84  
85      /**
86       * Creates a new {@code TrackableBase} instance.
87       * Equivalent to {@code newInstance(true)}.
88       * @see #newInstance(boolean)
89       *
90       * @return a new {@code TrackableBase}
91       */
92      @Nonnull
93      public static TrackableBase newInstance() {
94          return newInstance(true);
95      }
96  
97      /**
98       * Creates a new {@code TrackableBase} instance using default values or not.
99       * Equivalent to {@code newBuilder(withDefaults).build()}.
100      *
101      * @param withDefaults the boolean indicating whether default values should be used
102      * @return a new {@code TrackableBase}
103      */
104     @Nonnull
105     public static TrackableBase newInstance(boolean withDefaults) {
106         return newBuilder(withDefaults).build();
107     }
108 
109     /**
110      * Creates a new {@code TrackableBase} builder instance.
111      * Equivalent to {@code newBuilder(true)}.
112      * @see #newBuilder(boolean)
113      *
114      * @return a new {@code Builder}
115      */
116     @Nonnull
117     public static Builder newBuilder() {
118         return newBuilder(true);
119     }
120 
121     /**
122      * Creates a new {@code TrackableBase} builder instance using default values or not.
123      *
124      * @param withDefaults the boolean indicating whether default values should be used
125      * @return a new {@code Builder}
126      */
127     @Nonnull
128     public static Builder newBuilder(boolean withDefaults) {
129         return new Builder(withDefaults);
130     }
131 
132     /**
133      * Creates a new {@code TrackableBase} builder instance using the specified object as a basis.
134      * Equivalent to {@code newBuilder(from, false)}.
135      *
136      * @param from the {@code TrackableBase} instance to use as a basis
137      * @return a new {@code Builder}
138      */
139     @Nonnull
140     public static Builder newBuilder(TrackableBase from) {
141         return newBuilder(from, false);
142     }
143 
144     /**
145      * Creates a new {@code TrackableBase} builder instance using the specified object as a basis.
146      *
147      * @param from the {@code TrackableBase} instance to use as a basis
148      * @param forceCopy the boolean indicating if a copy should be forced
149      * @return a new {@code Builder}
150      */
151     @Nonnull
152     public static Builder newBuilder(TrackableBase from, boolean forceCopy) {
153         return new Builder(from, forceCopy);
154     }
155 
156     /**
157      * Builder class used to create TrackableBase instances.
158      * @see #with()
159      * @see #newBuilder()
160      */
161     @NotThreadSafe
162     public static class Builder
163     {
164         TrackableBase base;
165         Map<Object, InputLocation> locations;
166         InputLocation importedFrom;
167 
168         protected Builder(boolean withDefaults) {
169             if (withDefaults) {
170             }
171         }
172 
173         protected Builder(TrackableBase base, boolean forceCopy) {
174             if (forceCopy) {
175                 this.locations = base.locations;
176                 this.importedFrom = base.importedFrom;
177             } else {
178                 this.base = base;
179             }
180         }
181 
182 
183         @Nonnull
184         public Builder location(Object key, InputLocation location) {
185             if (location != null) {
186                 if (!(this.locations instanceof HashMap)) {
187                     this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
188                 }
189                 this.locations.put(key, location);
190             }
191             return this;
192         }
193 
194         @Nonnull
195         public Builder importedFrom(InputLocation importedFrom) {
196             this.importedFrom = importedFrom;
197             return this;
198         }
199 
200         @Nonnull
201         public TrackableBase build() {
202             // this method should not contain any logic other than creating (or reusing) an object in order to ease subclassing
203             if (base != null
204             ) {
205                 return base;
206             }
207             return new TrackableBase(this);
208         }
209 
210         Map<Object, InputLocation> computeLocations() {
211             Map<Object, InputLocation> newlocs = locations != null ? locations : Map.of();
212             Map<Object, InputLocation> oldlocs = base != null ? base.locations : Map.of();
213             if (newlocs.isEmpty()) {
214                 return Map.copyOf(oldlocs);
215             }
216             if (oldlocs.isEmpty()) {
217                 return Map.copyOf(newlocs);
218             }
219             return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream())
220                     // Keep value from newlocs in case of duplicates
221                     .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
222         }
223     }
224 
225 }