View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model;
20  
21  import java.util.stream.Collectors;
22  
23  /**
24   * Class InputLocation.
25   *
26   * @version $Revision$ $Date$
27   */
28  @SuppressWarnings("all")
29  public final class InputLocation implements java.io.Serializable, Cloneable, InputLocationTracker {
30  
31      // --------------------------/
32      // - Class/Member Variables -/
33      // --------------------------/
34  
35      /**
36       * The one-based line number. The value will be non-positive if
37       * unknown.
38       */
39      private int lineNumber = -1;
40  
41      /**
42       * The one-based column number. The value will be non-positive
43       * if unknown.
44       */
45      private int columnNumber = -1;
46  
47      /**
48       * Field source.
49       */
50      private InputSource source;
51  
52      /**
53       * Field locations.
54       */
55      private java.util.Map<Object, InputLocation> locations;
56  
57      /**
58       * Field location.
59       */
60      private InputLocation location;
61  
62      // ----------------/
63      // - Constructors -/
64      // ----------------/
65  
66      public InputLocation(org.apache.maven.api.model.InputLocation location) {
67          this.lineNumber = location.getLineNumber();
68          this.columnNumber = location.getColumnNumber();
69          this.source = location.getSource() != null ? new InputSource(location.getSource()) : null;
70          this.locations = location.getLocations().isEmpty()
71                  ? null
72                  : location.getLocations().entrySet().stream()
73                          .collect(Collectors.toMap(
74                                  e -> e.getKey(),
75                                  e -> e.getValue() == location ? this : new InputLocation(e.getValue())));
76      }
77  
78      public InputLocation(int lineNumber, int columnNumber) {
79          this.lineNumber = lineNumber;
80          this.columnNumber = columnNumber;
81      } // -- org.apache.maven.model.InputLocation(int, int)
82  
83      public InputLocation(int lineNumber, int columnNumber, InputSource source) {
84          this.lineNumber = lineNumber;
85          this.columnNumber = columnNumber;
86          this.source = source;
87      } // -- org.apache.maven.model.InputLocation(int, int, InputSource)
88  
89      // -----------/
90      // - Methods -/
91      // -----------/
92  
93      /**
94       * Method clone.
95       *
96       * @return InputLocation
97       */
98      public InputLocation clone() {
99          try {
100             InputLocation copy = (InputLocation) super.clone();
101 
102             if (copy.locations != null) {
103                 copy.locations = new java.util.LinkedHashMap(copy.locations);
104             }
105 
106             return copy;
107         } catch (Exception ex) {
108             throw (RuntimeException)
109                     new UnsupportedOperationException(getClass().getName() + " does not support clone()").initCause(ex);
110         }
111     } // -- InputLocation clone()
112 
113     /**
114      * Get the one-based column number. The value will be
115      * non-positive if unknown.
116      *
117      * @return int
118      */
119     public int getColumnNumber() {
120         return this.columnNumber;
121     } // -- int getColumnNumber()
122 
123     /**
124      * Get the one-based line number. The value will be
125      * non-positive if unknown.
126      *
127      * @return int
128      */
129     public int getLineNumber() {
130         return this.lineNumber;
131     } // -- int getLineNumber()
132 
133     /**
134      *
135      *
136      * @param key
137      * @return InputLocation
138      */
139     public InputLocation getLocation(Object key) {
140         if (key instanceof String) {
141             switch ((String) key) {
142                 case "": {
143                     return this.location;
144                 }
145                 default: {
146                     return getOtherLocation(key);
147                 }
148             }
149         } else {
150             return getOtherLocation(key);
151         }
152     } // -- InputLocation getLocation( Object )
153 
154     /**
155      *
156      *
157      * @return Map
158      */
159     public java.util.Map<Object, InputLocation> getLocations() {
160         return locations;
161     } // -- java.util.Map<Object, InputLocation> getLocations()
162 
163     /**
164      *
165      *
166      * @param key
167      * @param location
168      */
169     public void setLocation(Object key, InputLocation location) {
170         if (key instanceof String) {
171             switch ((String) key) {
172                 case "": {
173                     this.location = location;
174                     return;
175                 }
176                 default: {
177                     setOtherLocation(key, location);
178                     return;
179                 }
180             }
181         } else {
182             setOtherLocation(key, location);
183         }
184     } // -- void setLocation( Object, InputLocation )
185 
186     /**
187      *
188      *
189      * @param key
190      * @param location
191      */
192     public void setOtherLocation(Object key, InputLocation location) {
193         if (location != null) {
194             if (this.locations == null) {
195                 this.locations = new java.util.LinkedHashMap<>();
196             }
197             this.locations.put(key, location);
198         }
199     } // -- void setOtherLocation( Object, InputLocation )
200 
201     /**
202      *
203      *
204      * @param key
205      * @return InputLocation
206      */
207     private InputLocation getOtherLocation(Object key) {
208         return (locations != null) ? locations.get(key) : null;
209     } // -- InputLocation getOtherLocation( Object )
210 
211     /**
212      * Get the source field.
213      *
214      * @return InputSource
215      */
216     public InputSource getSource() {
217         return this.source;
218     } // -- InputSource getSource()
219 
220     /**
221      * Method merge.
222      *
223      * @param target
224      * @param sourceDominant
225      * @param source
226      * @return InputLocation
227      */
228     public static InputLocation merge(InputLocation target, InputLocation source, boolean sourceDominant) {
229         if (source == null) {
230             return target;
231         } else if (target == null) {
232             return source;
233         }
234 
235         InputLocation result = new InputLocation(target.getLineNumber(), target.getColumnNumber(), target.getSource());
236 
237         java.util.Map<Object, InputLocation> locations;
238         java.util.Map<Object, InputLocation> sourceLocations = source.getLocations();
239         java.util.Map<Object, InputLocation> targetLocations = target.getLocations();
240         if (sourceLocations == null) {
241             locations = targetLocations;
242         } else if (targetLocations == null) {
243             locations = sourceLocations;
244         } else {
245             locations = new java.util.LinkedHashMap();
246             locations.putAll(sourceDominant ? targetLocations : sourceLocations);
247             locations.putAll(sourceDominant ? sourceLocations : targetLocations);
248         }
249         result.setLocations(locations);
250 
251         return result;
252     } // -- InputLocation merge( InputLocation, InputLocation, boolean )
253 
254     /**
255      * Method merge.
256      *
257      * @param target
258      * @param indices
259      * @param source
260      * @return InputLocation
261      */
262     public static InputLocation merge(
263             InputLocation target, InputLocation source, java.util.Collection<Integer> indices) {
264         if (source == null) {
265             return target;
266         } else if (target == null) {
267             return source;
268         }
269 
270         InputLocation result = new InputLocation(target.getLineNumber(), target.getColumnNumber(), target.getSource());
271 
272         java.util.Map<Object, InputLocation> locations;
273         java.util.Map<Object, InputLocation> sourceLocations = source.getLocations();
274         java.util.Map<Object, InputLocation> targetLocations = target.getLocations();
275         if (sourceLocations == null) {
276             locations = targetLocations;
277         } else if (targetLocations == null) {
278             locations = sourceLocations;
279         } else {
280             locations = new java.util.LinkedHashMap<>();
281             for (java.util.Iterator<Integer> it = indices.iterator(); it.hasNext(); ) {
282                 InputLocation location;
283                 Integer index = it.next();
284                 if (index.intValue() < 0) {
285                     location = sourceLocations.get(Integer.valueOf(~index.intValue()));
286                 } else {
287                     location = targetLocations.get(index);
288                 }
289                 locations.put(Integer.valueOf(locations.size()), location);
290             }
291         }
292         result.setLocations(locations);
293 
294         return result;
295     } // -- InputLocation merge( InputLocation, InputLocation, java.util.Collection )
296 
297     /**
298      *
299      *
300      * @param locations
301      */
302     public void setLocations(java.util.Map<Object, InputLocation> locations) {
303         this.locations = locations;
304     } // -- void setLocations( java.util.Map )
305 
306     public org.apache.maven.api.model.InputLocation toApiLocation() {
307         if (locations != null && locations.values().contains(this)) {
308             if (locations.size() == 1 && locations.values().iterator().next() == this) {
309                 return new org.apache.maven.api.model.InputLocation(
310                         lineNumber,
311                         columnNumber,
312                         source != null ? source.toApiSource() : null,
313                         locations.keySet().iterator().next());
314             } else {
315                 return new org.apache.maven.api.model.InputLocation(
316                         lineNumber, columnNumber, source != null ? source.toApiSource() : null);
317             }
318         } else {
319             return new org.apache.maven.api.model.InputLocation(
320                     lineNumber,
321                     columnNumber,
322                     source != null ? source.toApiSource() : null,
323                     locations != null
324                             ? locations.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()
325                                     .toApiLocation()))
326                             : null);
327         }
328     }
329 
330     // -----------------/
331     // - Inner Classes -/
332     // -----------------/
333 
334     /**
335      * Class StringFormatter.
336      *
337      * @version $Revision$ $Date$
338      */
339     public abstract static class StringFormatter {
340 
341         // -----------/
342         // - Methods -/
343         // -----------/
344 
345         /**
346          * Method toString.
347          *
348          * @param location
349          * @return String
350          */
351         public abstract String toString(InputLocation location);
352     }
353 
354     @Override
355     public String toString() {
356         return getLineNumber() + " : " + getColumnNumber() + ", " + getSource();
357     }
358 }