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