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
26
27
28
29
30 public class FullyQualifiedJavaType implements
31 Comparable<FullyQualifiedJavaType> {
32
33
34 private static final String JAVA_LANG = "java.lang";
35
36
37 private static FullyQualifiedJavaType intInstance = null;
38
39
40 private static FullyQualifiedJavaType stringInstance = null;
41
42
43 private static FullyQualifiedJavaType booleanPrimitiveInstance = null;
44
45
46 private static FullyQualifiedJavaType objectInstance = null;
47
48
49 private static FullyQualifiedJavaType dateInstance = null;
50
51
52 private static FullyQualifiedJavaType criteriaInstance = null;
53
54
55 private static FullyQualifiedJavaType generatedCriteriaInstance = null;
56
57
58 private String baseShortName;
59
60
61 private String baseQualifiedName;
62
63
64 private boolean explicitlyImported;
65
66
67 private String packageName;
68
69
70 private boolean primitive;
71
72
73 private boolean isArray;
74
75
76 private PrimitiveTypeWrapper primitiveTypeWrapper;
77
78
79 private List<FullyQualifiedJavaType> typeArguments;
80
81
82
83 private boolean wildcardType;
84
85
86 private boolean boundedWildcard;
87
88
89 private boolean extendsBoundedWildcard;
90
91
92
93
94
95
96
97 public FullyQualifiedJavaType(String fullTypeSpecification) {
98 super();
99 typeArguments = new ArrayList<FullyQualifiedJavaType>();
100 parse(fullTypeSpecification);
101 }
102
103
104
105
106
107
108 public boolean isExplicitlyImported() {
109 return explicitlyImported;
110 }
111
112
113
114
115
116
117 public String getFullyQualifiedName() {
118 StringBuilder sb = new StringBuilder();
119 if (wildcardType) {
120 sb.append('?');
121 if (boundedWildcard) {
122 if (extendsBoundedWildcard) {
123 sb.append(" extends ");
124 } else {
125 sb.append(" super ");
126 }
127
128 sb.append(baseQualifiedName);
129 }
130 } else {
131 sb.append(baseQualifiedName);
132 }
133
134 if (typeArguments.size() > 0) {
135 boolean first = true;
136 sb.append('<');
137 for (FullyQualifiedJavaType fqjt : typeArguments) {
138 if (first) {
139 first = false;
140 } else {
141 sb.append(", ");
142 }
143 sb.append(fqjt.getFullyQualifiedName());
144
145 }
146 sb.append('>');
147 }
148
149 return sb.toString();
150 }
151
152 public String getFullyQualifiedNameWithoutTypeParameters() {
153 return baseQualifiedName;
154 }
155
156
157
158
159
160
161
162 public List<String> getImportList() {
163 List<String> answer = new ArrayList<String>();
164 if (isExplicitlyImported()) {
165 int index = baseShortName.indexOf('.');
166 if (index == -1) {
167 answer.add(baseQualifiedName);
168 } else {
169
170
171 StringBuilder sb = new StringBuilder();
172 sb.append(packageName);
173 sb.append('.');
174 sb.append(baseShortName.substring(0, index));
175 answer.add(sb.toString());
176 }
177 }
178
179 for (FullyQualifiedJavaType fqjt : typeArguments) {
180 answer.addAll(fqjt.getImportList());
181 }
182
183 return answer;
184 }
185
186
187
188
189
190
191 public String getPackageName() {
192 return packageName;
193 }
194
195
196
197
198
199
200 public String getShortName() {
201 StringBuilder sb = new StringBuilder();
202 if (wildcardType) {
203 sb.append('?');
204 if (boundedWildcard) {
205 if (extendsBoundedWildcard) {
206 sb.append(" extends ");
207 } else {
208 sb.append(" super ");
209 }
210
211 sb.append(baseShortName);
212 }
213 } else {
214 sb.append(baseShortName);
215 }
216
217 if (typeArguments.size() > 0) {
218 boolean first = true;
219 sb.append('<');
220 for (FullyQualifiedJavaType fqjt : typeArguments) {
221 if (first) {
222 first = false;
223 } else {
224 sb.append(", ");
225 }
226 sb.append(fqjt.getShortName());
227
228 }
229 sb.append('>');
230 }
231
232 return sb.toString();
233 }
234
235 public String getShortNameWithoutTypeArguments() {
236 return baseShortName;
237 }
238
239
240
241
242
243
244 @Override
245 public boolean equals(Object obj) {
246 if (this == obj) {
247 return true;
248 }
249
250 if (!(obj instanceof FullyQualifiedJavaType)) {
251 return false;
252 }
253
254 FullyQualifiedJavaType other = (FullyQualifiedJavaType) obj;
255
256 return getFullyQualifiedName().equals(other.getFullyQualifiedName());
257 }
258
259
260
261
262
263
264 @Override
265 public int hashCode() {
266 return getFullyQualifiedName().hashCode();
267 }
268
269
270
271
272
273
274 @Override
275 public String toString() {
276 return getFullyQualifiedName();
277 }
278
279
280
281
282
283
284 public boolean isPrimitive() {
285 return primitive;
286 }
287
288
289
290
291
292
293 public PrimitiveTypeWrapper getPrimitiveTypeWrapper() {
294 return primitiveTypeWrapper;
295 }
296
297
298
299
300
301
302 public static final FullyQualifiedJavaType getIntInstance() {
303 if (intInstance == null) {
304 intInstance = new FullyQualifiedJavaType("int");
305 }
306
307 return intInstance;
308 }
309
310
311
312
313
314
315 public static final FullyQualifiedJavaType getNewMapInstance() {
316
317 return new FullyQualifiedJavaType("java.util.Map");
318 }
319
320
321
322
323
324
325 public static final FullyQualifiedJavaType getNewListInstance() {
326
327 return new FullyQualifiedJavaType("java.util.List");
328 }
329
330
331
332
333
334
335 public static final FullyQualifiedJavaType getNewHashMapInstance() {
336
337 return new FullyQualifiedJavaType("java.util.HashMap");
338 }
339
340
341
342
343
344
345 public static final FullyQualifiedJavaType getNewArrayListInstance() {
346
347 return new FullyQualifiedJavaType("java.util.ArrayList");
348 }
349
350
351
352
353
354
355 public static final FullyQualifiedJavaType getNewIteratorInstance() {
356
357 return new FullyQualifiedJavaType("java.util.Iterator");
358 }
359
360
361
362
363
364
365 public static final FullyQualifiedJavaType getStringInstance() {
366 if (stringInstance == null) {
367 stringInstance = new FullyQualifiedJavaType("java.lang.String");
368 }
369
370 return stringInstance;
371 }
372
373
374
375
376
377
378 public static final FullyQualifiedJavaType getBooleanPrimitiveInstance() {
379 if (booleanPrimitiveInstance == null) {
380 booleanPrimitiveInstance = new FullyQualifiedJavaType("boolean");
381 }
382
383 return booleanPrimitiveInstance;
384 }
385
386
387
388
389
390
391 public static final FullyQualifiedJavaType getObjectInstance() {
392 if (objectInstance == null) {
393 objectInstance = new FullyQualifiedJavaType("java.lang.Object");
394 }
395
396 return objectInstance;
397 }
398
399
400
401
402
403
404 public static final FullyQualifiedJavaType getDateInstance() {
405 if (dateInstance == null) {
406 dateInstance = new FullyQualifiedJavaType("java.util.Date");
407 }
408
409 return dateInstance;
410 }
411
412
413
414
415
416
417 public static final FullyQualifiedJavaType getCriteriaInstance() {
418 if (criteriaInstance == null) {
419 criteriaInstance = new FullyQualifiedJavaType("Criteria");
420 }
421
422 return criteriaInstance;
423 }
424
425
426
427
428
429
430 public static final FullyQualifiedJavaType getGeneratedCriteriaInstance() {
431 if (generatedCriteriaInstance == null) {
432 generatedCriteriaInstance = new FullyQualifiedJavaType(
433 "GeneratedCriteria");
434 }
435
436 return generatedCriteriaInstance;
437 }
438
439
440
441
442
443
444 public int compareTo(FullyQualifiedJavaType other) {
445 return getFullyQualifiedName().compareTo(other.getFullyQualifiedName());
446 }
447
448
449
450
451
452
453
454 public void addTypeArgument(FullyQualifiedJavaType type) {
455 typeArguments.add(type);
456 }
457
458
459
460
461
462
463
464 private void parse(String fullTypeSpecification) {
465 String spec = fullTypeSpecification.trim();
466
467 if (spec.startsWith("?")) {
468 wildcardType = true;
469 spec = spec.substring(1).trim();
470 if (spec.startsWith("extends ")) {
471 boundedWildcard = true;
472 extendsBoundedWildcard = true;
473 spec = spec.substring(8);
474 } else if (spec.startsWith("super ")) {
475 boundedWildcard = true;
476 extendsBoundedWildcard = false;
477 spec = spec.substring(6);
478 } else {
479 boundedWildcard = false;
480 }
481 parse(spec);
482 } else {
483 int index = fullTypeSpecification.indexOf('<');
484 if (index == -1) {
485 simpleParse(fullTypeSpecification);
486 } else {
487 simpleParse(fullTypeSpecification.substring(0, index));
488 int endIndex = fullTypeSpecification.lastIndexOf('>');
489 if (endIndex == -1) {
490 throw new RuntimeException(getString(
491 "RuntimeError.22", fullTypeSpecification));
492 }
493 genericParse(fullTypeSpecification.substring(index, endIndex + 1));
494 }
495
496
497
498
499
500 isArray = fullTypeSpecification.endsWith("]");
501 }
502 }
503
504
505
506
507
508
509
510 private void simpleParse(String typeSpecification) {
511 baseQualifiedName = typeSpecification.trim();
512 if (baseQualifiedName.contains(".")) {
513 packageName = getPackage(baseQualifiedName);
514 baseShortName = baseQualifiedName
515 .substring(packageName.length() + 1);
516 int index = baseShortName.lastIndexOf('.');
517 if (index != -1) {
518 baseShortName = baseShortName.substring(index + 1);
519 }
520
521 if (JAVA_LANG.equals(packageName)) {
522 explicitlyImported = false;
523 } else {
524 explicitlyImported = true;
525 }
526 } else {
527 baseShortName = baseQualifiedName;
528 explicitlyImported = false;
529 packageName = "";
530
531 if ("byte".equals(baseQualifiedName)) {
532 primitive = true;
533 primitiveTypeWrapper = PrimitiveTypeWrapper.getByteInstance();
534 } else if ("short".equals(baseQualifiedName)) {
535 primitive = true;
536 primitiveTypeWrapper = PrimitiveTypeWrapper.getShortInstance();
537 } else if ("int".equals(baseQualifiedName)) {
538 primitive = true;
539 primitiveTypeWrapper = PrimitiveTypeWrapper
540 .getIntegerInstance();
541 } else if ("long".equals(baseQualifiedName)) {
542 primitive = true;
543 primitiveTypeWrapper = PrimitiveTypeWrapper.getLongInstance();
544 } else if ("char".equals(baseQualifiedName)) {
545 primitive = true;
546 primitiveTypeWrapper = PrimitiveTypeWrapper
547 .getCharacterInstance();
548 } else if ("float".equals(baseQualifiedName)) {
549 primitive = true;
550 primitiveTypeWrapper = PrimitiveTypeWrapper.getFloatInstance();
551 } else if ("double".equals(baseQualifiedName)) {
552 primitive = true;
553 primitiveTypeWrapper = PrimitiveTypeWrapper.getDoubleInstance();
554 } else if ("boolean".equals(baseQualifiedName)) {
555 primitive = true;
556 primitiveTypeWrapper = PrimitiveTypeWrapper
557 .getBooleanInstance();
558 } else {
559 primitive = false;
560 primitiveTypeWrapper = null;
561 }
562 }
563 }
564
565
566
567
568
569
570
571 private void genericParse(String genericSpecification) {
572 int lastIndex = genericSpecification.lastIndexOf('>');
573 if (lastIndex == -1) {
574
575 throw new RuntimeException(getString(
576 "RuntimeError.22", genericSpecification));
577 }
578 String argumentString = genericSpecification.substring(1, lastIndex);
579
580 StringTokenizer st = new StringTokenizer(argumentString, ",<>", true);
581 int openCount = 0;
582 StringBuilder sb = new StringBuilder();
583 while (st.hasMoreTokens()) {
584 String token = st.nextToken();
585 if ("<".equals(token)) {
586 sb.append(token);
587 openCount++;
588 } else if (">".equals(token)) {
589 sb.append(token);
590 openCount--;
591 } else if (",".equals(token)) {
592 if (openCount == 0) {
593 typeArguments
594 .add(new FullyQualifiedJavaType(sb.toString()));
595 sb.setLength(0);
596 } else {
597 sb.append(token);
598 }
599 } else {
600 sb.append(token);
601 }
602 }
603
604 if (openCount != 0) {
605 throw new RuntimeException(getString(
606 "RuntimeError.22", genericSpecification));
607 }
608
609 String finalType = sb.toString();
610 if (stringHasValue(finalType)) {
611 typeArguments.add(new FullyQualifiedJavaType(finalType));
612 }
613 }
614
615
616
617
618
619
620
621
622
623
624
625
626 private static String getPackage(String baseQualifiedName) {
627 int index = baseQualifiedName.lastIndexOf('.');
628 return baseQualifiedName.substring(0, index);
629 }
630
631
632
633
634
635
636 public boolean isArray() {
637 return isArray;
638 }
639 }