1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.castor.xml;
47
48 import java.io.File;
49 import java.lang.reflect.Field;
50 import java.lang.reflect.Method;
51 import java.util.Hashtable;
52
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
55 import org.springframework.stereotype.Component;
56
57
58
59
60
61
62
63
64
65
66 @Component("javaNamingNG")
67 public class JavaNamingNGImpl implements JavaNaming {
68
69
70 private static final Log LOG = LogFactory.getLog(JavaNamingNGImpl.class);
71
72
73
74
75
76 public static final String UPPER_CASE_AFTER_UNDERSCORE_PROPERTY
77 = "org.exolab.castor.xml.JavaNaming.upperCaseAfterUnderscore";
78
79
80
81
82
83 public static boolean _upperCaseAfterUnderscore = false;
84
85
86 private static final Hashtable<String, String> SUBST = keywordMap();
87
88 private InternalContext context;
89
90
91 private static final String[] KEYWORDS = {"abstract", "boolean", "break", "byte", "case",
92 "catch", "char", "class", "const", "continue", "default", "do", "double", "else",
93 "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements",
94 "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package",
95 "private", "protected", "public", "return", "short", "static", "super", "switch",
96 "synchronized", "this", "throw", "throws", "transient", "true", "try", "void",
97 "volatile", "while"};
98
99
100
101
102 public JavaNamingNGImpl() {
103 super();
104 }
105
106 public JavaNamingNGImpl(InternalContext context) {
107 super();
108 this.context = context;
109 }
110
111
112
113
114
115
116
117
118 public final boolean isKeyword(final String name) {
119 if (name == null) {
120 return false;
121 }
122 for (int i = 0; i < KEYWORDS.length; i++) {
123 if (KEYWORDS[i].equals(name)) {
124 return true;
125 }
126 }
127 return false;
128 }
129
130
131
132
133
134
135
136
137
138
139
140 public final boolean isValidJavaIdentifier(final String string) {
141 if ((string == null) || (string.length() == 0)) {
142 return false;
143 }
144
145 for (int i = 0; i < string.length(); i++) {
146 char ch = string.charAt(i);
147
148
149 if (ch == '_') {
150 continue;
151 }
152 if (ch == '$') {
153 continue;
154 }
155
156 if ((ch >= 'A') && (ch <= 'Z')) {
157 continue;
158 }
159 if ((ch >= 'a') && (ch <= 'z')) {
160 continue;
161 }
162 if ((ch >= '0') && (ch <= '9')) {
163 if (i == 0) {
164 return false;
165 }
166 continue;
167 }
168
169 return false;
170 }
171 if (isKeyword(string)) {
172 return false;
173 }
174 return true;
175 }
176
177
178
179
180
181
182
183 public final String toJavaClassName(final String name) {
184
185 if ((name == null) || (name.length() <= 0)) {
186
187 return name;
188 }
189
190
191 int colon = name.indexOf(':');
192 if (colon != -1) {
193 return toJavaName(name.substring(colon + 1), true);
194 }
195 return toJavaName(name, true);
196
197 }
198
199
200
201
202
203
204
205 public final String toJavaMemberName(final String name) {
206 return toJavaMemberName(name, true);
207 }
208
209
210
211
212
213
214
215
216 public final String toJavaMemberName(final String name, final boolean useKeywordSubstitutions) {
217
218 if (name == null) {
219 return null;
220 }
221
222 String memberName = toJavaName(name, false);
223
224 if (isKeyword(memberName) && useKeywordSubstitutions) {
225 String mappedName = (String) SUBST.get(memberName);
226 if (mappedName != null) {
227 memberName = mappedName;
228 }
229 }
230 return memberName;
231 }
232
233
234
235
236
237
238
239
240
241
242 public final boolean isValidPackageName(final String packageName) {
243 if ((packageName == null) || (packageName.length() < 1)) {
244 return true;
245 }
246 if (".".equals(packageName)) {
247 return false;
248 }
249 if (packageName.startsWith(".") || (packageName.endsWith("."))) {
250 return false;
251 }
252 boolean valid = true;
253 String[] packageNameParts = packageName.split("\\.");
254 for (int i = 0; i < packageNameParts.length; i++) {
255 String packageNamePart = packageNameParts[i];
256 valid &= isValidJavaIdentifier(packageNamePart);
257 }
258 return valid;
259 }
260
261
262
263
264
265
266
267
268 public final String packageToPath(final String packageName) {
269 if (packageName == null) {
270 return packageName;
271 }
272 if (!isValidPackageName(packageName)) {
273 String message = "Package name: " + packageName + " is not valid";
274 LOG.warn(message);
275 throw new IllegalArgumentException(message);
276 }
277 return packageName.replace('.', File.separatorChar);
278 }
279
280
281
282
283
284 private static Hashtable<String, String> keywordMap() {
285 Hashtable<String, String> ht = new Hashtable<String, String>();
286 ht.put("class", "clazz");
287 return ht;
288 }
289
290
291
292
293
294
295
296
297
298
299
300 private String toJavaName(final String name, final boolean upperFirst) {
301
302 int size = name.length();
303 char[] ncChars = name.toCharArray();
304 int next = 0;
305
306 boolean uppercase = upperFirst;
307
308
309
310
311 boolean lowercase = (!uppercase);
312 if ((size > 1) && lowercase) {
313 if (Character.isUpperCase(ncChars[0]) && Character.isUpperCase(ncChars[1])) {
314 if (context != null && context.getBooleanProperty(XMLProperties.MEMBER_NAME_CAPITALISATION_STRICT)) {
315 lowercase = true;
316 } else {
317 lowercase = false;
318 }
319 }
320 }
321
322 for (int i = 0; i < size; i++) {
323 char ch = ncChars[i];
324
325 switch (ch) {
326 case '.':
327 case ' ':
328 ncChars[next++] = '_';
329 break;
330 case ':':
331 case '-':
332 uppercase = true;
333 break;
334 case '_':
335
336 if (_upperCaseAfterUnderscore) {
337 uppercase = true;
338 ncChars[next] = ch;
339 ++next;
340 break;
341 }
342
343
344
345
346
347
348 default:
349 if (uppercase) {
350 ncChars[next] = Character.toUpperCase(ch);
351 uppercase = false;
352 } else if (lowercase) {
353 ncChars[next] = Character.toLowerCase(ch);
354 lowercase = false;
355 } else {
356 ncChars[next] = ch;
357 }
358 ++next;
359 break;
360 }
361 }
362 return new String(ncChars, 0, next);
363 }
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378 public final String getQualifiedFileName(final String fileName, final String packageName) {
379 if ((packageName == null) || (packageName.length() == 0)) {
380 return fileName;
381 }
382 StringBuffer result = new StringBuffer();
383 result.append(packageToPath(packageName));
384 result.append('/');
385 result.append(fileName);
386 return result.toString();
387 }
388
389
390
391
392
393
394
395
396
397
398 public final String getPackageName(final String className) {
399 if ((className == null) || (className.length() < 1)) {
400 return className;
401 }
402
403 int idx = className.lastIndexOf('.');
404 if (idx >= 0) {
405 return className.substring(0, idx);
406 }
407 return "";
408 }
409
410
411
412
413
414
415
416
417 public final String extractFieldNameFromMethod(final Method method) {
418 if (method == null) {
419 return null;
420 }
421 String fieldName = null;
422 if (isSetMethod(method)) {
423 fieldName = method.getName().substring(METHOD_PREFIX_SET.length());
424 } else if (isCreateMethod(method)) {
425 fieldName = method.getName().substring(METHOD_PREFIX_CREATE.length());
426 } else if (isGetMethod(method)) {
427 fieldName = method.getName().substring(METHOD_PREFIX_GET.length());
428 } else if (isIsMethod(method)) {
429 fieldName = method.getName().substring(METHOD_PREFIX_IS.length());
430 } else if (isAddMethod(method)) {
431 fieldName = method.getName().substring(METHOD_PREFIX_ADD.length());
432 }
433 return toJavaMemberName(fieldName);
434 }
435
436
437
438
439
440
441
442
443
444 public final String extractFieldNameFromField(Field field) {
445 if (field == null) {
446 return null;
447 }
448 String fieldName = field.getName();
449 if (fieldName.charAt(0) == FIELD_UNDERSCORE_PREFIX) {
450 fieldName = fieldName.substring(1);
451 }
452 return fieldName;
453 }
454
455
456
457
458
459
460
461 public final boolean isSetMethod(final Method method) {
462 if (method == null) {
463 return false;
464 }
465 if (!method.getName().startsWith(METHOD_PREFIX_SET)) {
466 return false;
467 }
468 if (method.getParameterTypes().length != 1) {
469 return false;
470 }
471 if ((method.getReturnType() != void.class) && (method.getReturnType() != Void.class)) {
472 return false;
473 }
474 return true;
475 }
476
477
478
479
480
481
482
483 public final boolean isCreateMethod(final Method method) {
484 if (method == null) {
485 return false;
486 }
487 if (!method.getName().startsWith(METHOD_PREFIX_CREATE)) {
488 return false;
489 }
490 if (method.getParameterTypes().length != 0) {
491 return false;
492 }
493 if (method.getReturnType() == null) {
494 return false;
495 }
496 return true;
497 }
498
499
500
501
502
503
504
505 public final boolean isGetMethod(final Method method) {
506 if (method == null) {
507 return false;
508 }
509 if (!method.getName().startsWith(METHOD_PREFIX_GET)) {
510 return false;
511 }
512 if (method.getParameterTypes().length != 0) {
513 return false;
514 }
515 if (method.getReturnType() == null) {
516 return false;
517 }
518 return true;
519 }
520
521
522
523
524
525
526
527 public final boolean isIsMethod(final Method method) {
528 if (method == null) {
529 return false;
530 }
531 if (!method.getName().startsWith(METHOD_PREFIX_IS)) {
532 return false;
533 }
534 if (method.getParameterTypes().length != 0) {
535 return false;
536 }
537 if ((method.getReturnType().isPrimitive()) && (method.getReturnType() != Boolean.TYPE)) {
538 return false;
539 }
540 if ((!method.getReturnType().isPrimitive()) && (method.getReturnType() != Boolean.class)) {
541 return false;
542 }
543 return true;
544 }
545
546
547
548
549
550
551
552 public final boolean isAddMethod(final Method method) {
553 if (method == null) {
554 return false;
555 }
556 if (!method.getName().startsWith(METHOD_PREFIX_ADD)) {
557 return false;
558 }
559 if (method.getParameterTypes().length != 1) {
560 return false;
561 }
562 if ((method.getReturnType() != void.class) && (method.getReturnType() != Void.class)) {
563 return false;
564 }
565 return true;
566 }
567
568
569
570
571
572
573 public final String getAddMethodNameForField(final String fieldName) {
574 return METHOD_PREFIX_ADD + toJavaClassName(fieldName);
575 }
576
577
578
579
580
581
582 public final String getCreateMethodNameForField(final String fieldName) {
583 return METHOD_PREFIX_CREATE + toJavaClassName(fieldName);
584 }
585
586
587
588
589
590
591 public final String getGetMethodNameForField(final String fieldName) {
592 return METHOD_PREFIX_GET + toJavaClassName(fieldName);
593 }
594
595
596
597
598
599
600 public final String getIsMethodNameForField(final String fieldName) {
601 return METHOD_PREFIX_IS + toJavaClassName(fieldName);
602 }
603
604
605
606
607
608
609 public final String getSetMethodNameForField(final String fieldName) {
610 return METHOD_PREFIX_SET + toJavaClassName(fieldName);
611 }
612
613
614
615
616
617
618
619
620
621 public String getClassName(Class clazz) {
622 if (clazz == null) {
623 return null;
624 }
625 String name = clazz.getName();
626 int idx = name.lastIndexOf('.');
627 if (idx >= 0) {
628 name = name.substring(idx+1);
629 }
630 return name;
631 }
632 }