1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.api.model;
20
21 import java.io.Serializable;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.LinkedHashMap;
25 import java.util.Map;
26
27
28
29
30 public class InputLocation implements Serializable, InputLocationTracker {
31 private final int lineNumber;
32 private final int columnNumber;
33 private final InputSource source;
34 private final Map<Object, InputLocation> locations;
35 private final InputLocation importedFrom;
36
37 public InputLocation(InputSource source) {
38 this.lineNumber = -1;
39 this.columnNumber = -1;
40 this.source = source;
41 this.locations = Collections.singletonMap(0, this);
42 this.importedFrom = null;
43 }
44
45 public InputLocation(int lineNumber, int columnNumber) {
46 this(lineNumber, columnNumber, null, null);
47 }
48
49 public InputLocation(int lineNumber, int columnNumber, InputSource source) {
50 this(lineNumber, columnNumber, source, null);
51 }
52
53 public InputLocation(int lineNumber, int columnNumber, InputSource source, Object selfLocationKey) {
54 this.lineNumber = lineNumber;
55 this.columnNumber = columnNumber;
56 this.source = source;
57 this.locations =
58 selfLocationKey != null ? Collections.singletonMap(selfLocationKey, this) : Collections.emptyMap();
59 this.importedFrom = null;
60 }
61
62 public InputLocation(int lineNumber, int columnNumber, InputSource source, Map<Object, InputLocation> locations) {
63 this.lineNumber = lineNumber;
64 this.columnNumber = columnNumber;
65 this.source = source;
66 this.locations = ImmutableCollections.copy(locations);
67 this.importedFrom = null;
68 }
69
70 public InputLocation(InputLocation original) {
71 this.lineNumber = original.lineNumber;
72 this.columnNumber = original.columnNumber;
73 this.source = original.source;
74 this.locations = original.locations;
75 this.importedFrom = original.importedFrom;
76 }
77
78 public int getLineNumber() {
79 return lineNumber;
80 }
81
82 public int getColumnNumber() {
83 return columnNumber;
84 }
85
86 public InputSource getSource() {
87 return source;
88 }
89
90 public InputLocation getLocation(Object key) {
91 return locations != null ? locations.get(key) : null;
92 }
93
94 public Map<Object, InputLocation> getLocations() {
95 return locations;
96 }
97
98
99
100
101
102
103
104
105 public InputLocation getImportedFrom() {
106 return importedFrom;
107 }
108
109
110
111
112
113
114
115
116
117 public static InputLocation merge(InputLocation target, InputLocation source, boolean sourceDominant) {
118 if (source == null) {
119 return target;
120 } else if (target == null) {
121 return source;
122 }
123
124 Map<Object, InputLocation> locations;
125 Map<Object, InputLocation> sourceLocations = source.locations;
126 Map<Object, InputLocation> targetLocations = target.locations;
127 if (sourceLocations == null) {
128 locations = targetLocations;
129 } else if (targetLocations == null) {
130 locations = sourceLocations;
131 } else {
132 locations = new LinkedHashMap<>();
133 locations.putAll(sourceDominant ? targetLocations : sourceLocations);
134 locations.putAll(sourceDominant ? sourceLocations : targetLocations);
135 }
136
137 return new InputLocation(-1, -1, InputSource.merge(source.getSource(), target.getSource()), locations);
138 }
139
140
141
142
143
144
145
146
147
148
149 public static InputLocation merge(InputLocation target, InputLocation source, Collection<Integer> indices) {
150 if (source == null) {
151 return target;
152 } else if (target == null) {
153 return source;
154 }
155
156 Map<Object, InputLocation> locations;
157 Map<Object, InputLocation> sourceLocations = source.locations;
158 Map<Object, InputLocation> targetLocations = target.locations;
159 if (sourceLocations == null) {
160 locations = targetLocations;
161 } else if (targetLocations == null) {
162 locations = sourceLocations;
163 } else {
164 locations = new LinkedHashMap<>();
165 for (int index : indices) {
166 InputLocation location;
167 if (index < 0) {
168 location = sourceLocations.get(~index);
169 } else {
170 location = targetLocations.get(index);
171 }
172 locations.put(locations.size(), location);
173 }
174 }
175
176 return new InputLocation(-1, -1, InputSource.merge(source.getSource(), target.getSource()), locations);
177 }
178
179
180
181
182
183
184 public interface StringFormatter {
185
186
187
188
189
190
191
192
193 String toString(InputLocation location);
194 }
195
196 @Override
197 public String toString() {
198 return String.format("%s @ %d:%d", source.getLocation(), lineNumber, columnNumber);
199 }
200 }