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