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