1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.generator.api.dom.java;
17
18 import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
19 import static org.mybatis.generator.internal.util.messages.Messages.getString;
20
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.StringTokenizer;
24
25 public class FullyQualifiedJavaType implements Comparable<FullyQualifiedJavaType> {
26
27 private static final String JAVA_LANG = "java.lang";
28
29 private static FullyQualifiedJavaType intInstance = null;
30
31 private static FullyQualifiedJavaType stringInstance = null;
32
33 private static FullyQualifiedJavaType booleanPrimitiveInstance = null;
34
35 private static FullyQualifiedJavaType objectInstance = null;
36
37 private static FullyQualifiedJavaType dateInstance = null;
38
39 private static FullyQualifiedJavaType criteriaInstance = null;
40
41 private static FullyQualifiedJavaType generatedCriteriaInstance = null;
42
43
44 private String baseShortName;
45
46
47 private String baseQualifiedName;
48
49 private boolean explicitlyImported;
50
51 private String packageName;
52
53 private boolean primitive;
54
55 private boolean isArray;
56
57 private PrimitiveTypeWrapper primitiveTypeWrapper;
58
59 private final List<FullyQualifiedJavaType> typeArguments;
60
61
62 private boolean wildcardType;
63
64 private boolean boundedWildcard;
65
66 private boolean extendsBoundedWildcard;
67
68
69
70
71
72
73
74 public FullyQualifiedJavaType(String fullTypeSpecification) {
75 super();
76 typeArguments = new ArrayList<>();
77 parse(fullTypeSpecification);
78 }
79
80 public boolean isExplicitlyImported() {
81 return explicitlyImported;
82 }
83
84
85
86
87
88
89 public String getFullyQualifiedName() {
90 StringBuilder sb = new StringBuilder();
91 if (wildcardType) {
92 sb.append('?');
93 if (boundedWildcard) {
94 if (extendsBoundedWildcard) {
95 sb.append(" extends ");
96 } else {
97 sb.append(" super ");
98 }
99
100 sb.append(baseQualifiedName);
101 }
102 } else {
103 sb.append(baseQualifiedName);
104 }
105
106 if (!typeArguments.isEmpty()) {
107 boolean first = true;
108 sb.append('<');
109 for (FullyQualifiedJavaType fqjt : typeArguments) {
110 if (first) {
111 first = false;
112 } else {
113 sb.append(", ");
114 }
115 sb.append(fqjt.getFullyQualifiedName());
116
117 }
118 sb.append('>');
119 }
120
121 return sb.toString();
122 }
123
124 public String getFullyQualifiedNameWithoutTypeParameters() {
125 return baseQualifiedName;
126 }
127
128
129
130
131
132
133
134 public List<String> getImportList() {
135 List<String> answer = new ArrayList<>();
136 if (isExplicitlyImported()) {
137 int index = baseShortName.indexOf('.');
138 if (index == -1) {
139 answer.add(calculateActualImport(baseQualifiedName));
140 } else {
141
142
143 String sb = packageName + '.' + calculateActualImport(baseShortName.substring(0, index));
144 answer.add(sb);
145 }
146 }
147
148 for (FullyQualifiedJavaType fqjt : typeArguments) {
149 answer.addAll(fqjt.getImportList());
150 }
151
152 return answer;
153 }
154
155 private String calculateActualImport(String name) {
156 String answer = name;
157 if (this.isArray()) {
158 int index = name.indexOf('[');
159 if (index != -1) {
160 answer = name.substring(0, index);
161 }
162 }
163 return answer;
164 }
165
166 public String getPackageName() {
167 return packageName;
168 }
169
170 public String getShortName() {
171 StringBuilder sb = new StringBuilder();
172 if (wildcardType) {
173 sb.append('?');
174 if (boundedWildcard) {
175 if (extendsBoundedWildcard) {
176 sb.append(" extends ");
177 } else {
178 sb.append(" super ");
179 }
180
181 sb.append(baseShortName);
182 }
183 } else {
184 sb.append(baseShortName);
185 }
186
187 if (!typeArguments.isEmpty()) {
188 boolean first = true;
189 sb.append('<');
190 for (FullyQualifiedJavaType fqjt : typeArguments) {
191 if (first) {
192 first = false;
193 } else {
194 sb.append(", ");
195 }
196 sb.append(fqjt.getShortName());
197
198 }
199 sb.append('>');
200 }
201
202 return sb.toString();
203 }
204
205 public String getShortNameWithoutTypeArguments() {
206 return baseShortName;
207 }
208
209 @Override
210 public boolean equals(Object obj) {
211 if (this == obj) {
212 return true;
213 }
214
215 if (!(obj instanceof FullyQualifiedJavaType)) {
216 return false;
217 }
218
219 FullyQualifiedJavaType other = (FullyQualifiedJavaType) obj;
220
221 return getFullyQualifiedName().equals(other.getFullyQualifiedName());
222 }
223
224 @Override
225 public int hashCode() {
226 return getFullyQualifiedName().hashCode();
227 }
228
229 @Override
230 public String toString() {
231 return getFullyQualifiedName();
232 }
233
234 public boolean isPrimitive() {
235 return primitive;
236 }
237
238 public PrimitiveTypeWrapper getPrimitiveTypeWrapper() {
239 return primitiveTypeWrapper;
240 }
241
242 public static FullyQualifiedJavaType getIntInstance() {
243 if (intInstance == null) {
244 intInstance = new FullyQualifiedJavaType("int");
245 }
246
247 return intInstance;
248 }
249
250 public static FullyQualifiedJavaType getNewListInstance() {
251
252 return new FullyQualifiedJavaType("java.util.List");
253 }
254
255 public static FullyQualifiedJavaType getNewHashMapInstance() {
256
257 return new FullyQualifiedJavaType("java.util.HashMap");
258 }
259
260 public static FullyQualifiedJavaType getNewArrayListInstance() {
261
262 return new FullyQualifiedJavaType("java.util.ArrayList");
263 }
264
265 public static FullyQualifiedJavaType getNewIteratorInstance() {
266
267 return new FullyQualifiedJavaType("java.util.Iterator");
268 }
269
270 public static FullyQualifiedJavaType getStringInstance() {
271 if (stringInstance == null) {
272 stringInstance = new FullyQualifiedJavaType("java.lang.String");
273 }
274
275 return stringInstance;
276 }
277
278 public static FullyQualifiedJavaType getBooleanPrimitiveInstance() {
279 if (booleanPrimitiveInstance == null) {
280 booleanPrimitiveInstance = new FullyQualifiedJavaType("boolean");
281 }
282
283 return booleanPrimitiveInstance;
284 }
285
286 public static FullyQualifiedJavaType getObjectInstance() {
287 if (objectInstance == null) {
288 objectInstance = new FullyQualifiedJavaType("java.lang.Object");
289 }
290
291 return objectInstance;
292 }
293
294 public static FullyQualifiedJavaType getDateInstance() {
295 if (dateInstance == null) {
296 dateInstance = new FullyQualifiedJavaType("java.util.Date");
297 }
298
299 return dateInstance;
300 }
301
302 public static FullyQualifiedJavaType getCriteriaInstance() {
303 if (criteriaInstance == null) {
304 criteriaInstance = new FullyQualifiedJavaType("Criteria");
305 }
306
307 return criteriaInstance;
308 }
309
310 public static FullyQualifiedJavaType getGeneratedCriteriaInstance() {
311 if (generatedCriteriaInstance == null) {
312 generatedCriteriaInstance = new FullyQualifiedJavaType(
313 "GeneratedCriteria");
314 }
315
316 return generatedCriteriaInstance;
317 }
318
319 @Override
320 public int compareTo(FullyQualifiedJavaType other) {
321 return getFullyQualifiedName().compareTo(other.getFullyQualifiedName());
322 }
323
324 public void addTypeArgument(FullyQualifiedJavaType type) {
325 typeArguments.add(type);
326 }
327
328 private void parse(String fullTypeSpecification) {
329 String spec = fullTypeSpecification.trim();
330
331 if (spec.startsWith("?")) {
332 wildcardType = true;
333 spec = spec.substring(1).trim();
334 if (spec.startsWith("extends ")) {
335 boundedWildcard = true;
336 extendsBoundedWildcard = true;
337 spec = spec.substring(8);
338 } else if (spec.startsWith("super ")) {
339 boundedWildcard = true;
340 extendsBoundedWildcard = false;
341 spec = spec.substring(6);
342 } else {
343 boundedWildcard = false;
344 }
345 parse(spec);
346 } else {
347 int index = fullTypeSpecification.indexOf('<');
348 if (index == -1) {
349 simpleParse(fullTypeSpecification);
350 } else {
351 simpleParse(fullTypeSpecification.substring(0, index));
352 int endIndex = fullTypeSpecification.lastIndexOf('>');
353 if (endIndex == -1) {
354 throw new RuntimeException(getString(
355 "RuntimeError.22", fullTypeSpecification));
356 }
357 genericParse(fullTypeSpecification.substring(index, endIndex + 1));
358 }
359
360
361
362
363
364 isArray = fullTypeSpecification.endsWith("]");
365 }
366 }
367
368 private void simpleParse(String typeSpecification) {
369 baseQualifiedName = typeSpecification.trim();
370 if (baseQualifiedName.contains(".")) {
371 packageName = getPackage(baseQualifiedName);
372 baseShortName = baseQualifiedName
373 .substring(packageName.length() + 1);
374 int index = baseShortName.lastIndexOf('.');
375 if (index != -1) {
376 baseShortName = baseShortName.substring(index + 1);
377 }
378
379
380 explicitlyImported = !JAVA_LANG.equals(packageName);
381 } else {
382 baseShortName = baseQualifiedName;
383 explicitlyImported = false;
384 packageName = "";
385
386 switch (baseQualifiedName) {
387 case "byte":
388 primitive = true;
389 primitiveTypeWrapper = PrimitiveTypeWrapper.getByteInstance();
390 break;
391 case "short":
392 primitive = true;
393 primitiveTypeWrapper = PrimitiveTypeWrapper.getShortInstance();
394 break;
395 case "int":
396 primitive = true;
397 primitiveTypeWrapper = PrimitiveTypeWrapper.getIntegerInstance();
398 break;
399 case "long":
400 primitive = true;
401 primitiveTypeWrapper = PrimitiveTypeWrapper.getLongInstance();
402 break;
403 case "char":
404 primitive = true;
405 primitiveTypeWrapper = PrimitiveTypeWrapper.getCharacterInstance();
406 break;
407 case "float":
408 primitive = true;
409 primitiveTypeWrapper = PrimitiveTypeWrapper.getFloatInstance();
410 break;
411 case "double":
412 primitive = true;
413 primitiveTypeWrapper = PrimitiveTypeWrapper.getDoubleInstance();
414 break;
415 case "boolean":
416 primitive = true;
417 primitiveTypeWrapper = PrimitiveTypeWrapper.getBooleanInstance();
418 break;
419 default:
420 primitive = false;
421 primitiveTypeWrapper = null;
422 break;
423 }
424 }
425 }
426
427 private void genericParse(String genericSpecification) {
428 int lastIndex = genericSpecification.lastIndexOf('>');
429 if (lastIndex == -1) {
430
431 throw new RuntimeException(getString(
432 "RuntimeError.22", genericSpecification));
433 }
434 String argumentString = genericSpecification.substring(1, lastIndex);
435
436 StringTokenizer st = new StringTokenizer(argumentString, ",<>", true);
437 int openCount = 0;
438 StringBuilder sb = new StringBuilder();
439 while (st.hasMoreTokens()) {
440 String token = st.nextToken();
441 if ("<".equals(token)) {
442 sb.append(token);
443 openCount++;
444 } else if (">".equals(token)) {
445 sb.append(token);
446 openCount--;
447 } else if (",".equals(token)) {
448 if (openCount == 0) {
449 typeArguments
450 .add(new FullyQualifiedJavaType(sb.toString()));
451 sb.setLength(0);
452 } else {
453 sb.append(token);
454 }
455 } else {
456 sb.append(token);
457 }
458 }
459
460 if (openCount != 0) {
461 throw new RuntimeException(getString(
462 "RuntimeError.22", genericSpecification));
463 }
464
465 String finalType = sb.toString();
466 if (stringHasValue(finalType)) {
467 typeArguments.add(new FullyQualifiedJavaType(finalType));
468 }
469 }
470
471
472
473
474
475
476
477
478
479
480
481
482
483 private static String getPackage(String baseQualifiedName) {
484 int index = baseQualifiedName.lastIndexOf('.');
485 return baseQualifiedName.substring(0, index);
486 }
487
488 public boolean isArray() {
489 return isArray;
490 }
491
492 public List<FullyQualifiedJavaType> getTypeArguments() {
493 return typeArguments;
494 }
495 }