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 package org.exolab.castor.xml;
36
37 import java.beans.PropertyChangeEvent;
38 import java.beans.PropertyChangeListener;
39 import java.io.PrintWriter;
40 import java.lang.reflect.Field;
41 import java.lang.reflect.Method;
42 import java.lang.reflect.Modifier;
43 import java.util.ArrayList;
44 import java.util.Enumeration;
45 import java.util.Hashtable;
46 import java.util.List;
47 import java.util.Vector;
48
49 import org.castor.xml.InternalContext;
50 import org.castor.xml.JavaNaming;
51 import org.castor.xml.XMLProperties;
52 import org.castor.xml.XMLNaming;
53 import org.exolab.castor.mapping.CollectionHandler;
54 import org.exolab.castor.mapping.FieldHandler;
55 import org.exolab.castor.mapping.FieldHandlerFactory;
56 import org.exolab.castor.mapping.GeneralizedFieldHandler;
57 import org.exolab.castor.mapping.MappingException;
58 import org.exolab.castor.mapping.TypeConvertor;
59 import org.exolab.castor.mapping.loader.CollectionHandlers;
60 import org.exolab.castor.mapping.loader.FieldHandlerImpl;
61 import org.exolab.castor.mapping.loader.TypeInfo;
62 import org.exolab.castor.util.ReflectionUtil;
63 import org.exolab.castor.xml.descriptors.CoreDescriptors;
64 import org.exolab.castor.xml.handlers.ContainerFieldHandler;
65 import org.exolab.castor.xml.handlers.DateFieldHandler;
66 import org.exolab.castor.xml.handlers.DefaultFieldHandlerFactory;
67 import org.exolab.castor.xml.util.ContainerElement;
68 import org.exolab.castor.xml.util.XMLClassDescriptorImpl;
69 import org.exolab.castor.xml.util.XMLFieldDescriptorImpl;
70
71
72
73
74
75
76
77
78 public final class Introspector implements PropertyChangeListener {
79
80
81 private static final FieldHandlerFactory DEFAULT_HANDLER_FACTORY =
82 new DefaultFieldHandlerFactory();
83
84 private static final Class[] EMPTY_CLASS_ARGS = new Class[0];
85
86
87 private static final String LIST = "java.util.List";
88
89
90 private static final String MAP = "java.util.Map";
91
92
93 private static final String SET_COLLECTION = "java.util.Set";
94
95
96 private static final String COLLECTION_WRAPPER_PREFIX = "##container_for_";
97
98
99
100
101
102
103
104
105 private static final boolean WRAP_COLLECTIONS_DEFAULT = false;
106
107
108
109
110 private static final Class[] COLLECTIONS = loadCollections();
111
112
113
114
115
116 private static XMLNaming _defaultNaming = null;
117
118
119
120
121 private XMLNaming _xmlNaming = null;
122
123
124
125
126 private NodeType _primitiveNodeType = null;
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 private boolean _wrapCollectionsInContainer = WRAP_COLLECTIONS_DEFAULT;
148
149
150
151
152
153 private Vector<FieldHandlerFactory> _handlerFactoryList = null;
154
155
156
157
158 private Hashtable<Class, FieldHandlerFactory> _handlerFactoryMap = null;
159
160
161
162
163
164 private boolean _saveMapKeys = true;
165
166
167
168
169 private ClassLoader _classLoader = null;
170
171
172
173
174 private JavaNaming _javaNaming;
175
176 private InternalContext _internalContext;
177
178
179
180
181 public Introspector() {
182 this(null);
183 }
184
185
186
187
188
189
190 public Introspector(final ClassLoader classLoader) {
191 super();
192 _classLoader = classLoader;
193 init();
194 }
195
196 private void init() {
197 if (_internalContext != null) {
198 _javaNaming = _internalContext.getJavaNaming();
199 _xmlNaming = _internalContext.getXMLNaming();
200 setPrimitiveNodeType(_internalContext.getPrimitiveNodeType());
201 _wrapCollectionsInContainer = _internalContext
202 .getBooleanProperty(XMLProperties.WRAP_COLLECTIONS_PROPERTY).booleanValue();
203 _saveMapKeys =
204 _internalContext.getBooleanProperty(XMLProperties.SAVE_MAP_KEYS).booleanValue();
205 }
206 }
207
208 public void setInternalContext(InternalContext internalContext) {
209 if (internalContext == null) {
210 if (this._internalContext != null) {
211 this._internalContext.removePropertyChangeListener(this);
212 }
213 } else {
214 if (this._internalContext != internalContext) {
215 if (this._internalContext != null) {
216 this._internalContext.removePropertyChangeListener(this);
217 }
218 internalContext.addPropertyChangeListener(this);
219 }
220 }
221
222 _internalContext = internalContext;
223 init();
224 }
225
226
227
228
229
230
231
232 public synchronized void addFieldHandlerFactory(FieldHandlerFactory factory) {
233 if (factory == null) {
234 String err = "The argument 'factory' must not be null.";
235 throw new IllegalArgumentException(err);
236 }
237 if (_handlerFactoryList == null) {
238 _handlerFactoryList = new Vector<>();
239 }
240 _handlerFactoryList.add(factory);
241 registerHandlerFactory(factory);
242 }
243
244
245
246
247
248
249 public NodeType getPrimitiveNodeType() {
250 return _primitiveNodeType;
251 }
252
253
254
255
256
257
258
259
260 public XMLClassDescriptor generateClassDescriptor(Class c) throws MarshalException {
261 return generateClassDescriptor(c, null);
262 }
263
264
265
266
267
268
269
270
271
272 public XMLClassDescriptor generateClassDescriptor(Class c, PrintWriter errorWriter)
273 throws MarshalException {
274
275 if (c == null)
276 return null;
277
278
279 if (c.isArray())
280 return null;
281
282
283 if ((c == Void.class) || (c == Class.class) || (c == Object.class)) {
284 throw new MarshalException(MarshalException.BASE_CLASS_OR_VOID_ERR);
285 }
286
287
288 XMLClassDescriptor coreDesc = CoreDescriptors.getDescriptor(c);
289 if (coreDesc != null)
290 return coreDesc;
291
292
293
294
295
296
297 XMLClassDescriptorImpl classDesc = new IntrospectedXMLClassDescriptor(c);
298
299 Method[] methods = c.getMethods();
300 List<XMLFieldDescriptorImpl> dateDescriptors = new ArrayList<>(3);
301 Hashtable<String, MethodSet> methodSets = new Hashtable<>();
302
303 int methodCount = 0;
304
305 Class superClass = c.getSuperclass();
306 Class[] interfaces = c.getInterfaces();
307
308
309
310
311 for (int i = 0; i < methods.length; i++) {
312 Method method = methods[i];
313
314 Class owner = method.getDeclaringClass();
315
316
317
318 if (owner != c) {
319
320
321
322
323 if (!owner.isInterface())
324 continue;
325
326
327
328
329 if (interfaces.length > 0) {
330 boolean found = false;
331 for (int count = 0; count < interfaces.length; count++) {
332 if (interfaces[count] == owner) {
333 found = true;
334 break;
335 }
336 }
337 if (!found)
338 continue;
339 }
340 } else {
341
342 if (superClass != null) {
343 Class[] args = method.getParameterTypes();
344 String name = method.getName();
345 Method tmpMethod = null;
346 try {
347 tmpMethod = superClass.getMethod(name, args);
348 } catch (NoSuchMethodException nsme) {
349
350 }
351 if (tmpMethod != null)
352 continue;
353 }
354 }
355
356
357
358 if ((method.getModifiers() & Modifier.STATIC) != 0)
359 continue;
360
361 String methodName = method.getName();
362
363
364 if (methodName.startsWith(JavaNaming.METHOD_PREFIX_GET)) {
365 if (method.getParameterTypes().length != 0) {
366 continue;
367 }
368
369 ++methodCount;
370
371
372 Class type = method.getReturnType();
373 if (type == null)
374 continue;
375 if (!isDescriptable(type))
376 continue;
377
378
379 String fieldName = methodName.substring(3);
380 fieldName = _javaNaming.toJavaMemberName(fieldName);
381
382 MethodSet methodSet = methodSets.get(fieldName);
383 if (methodSet == null) {
384 methodSet = new MethodSet(fieldName);
385 methodSets.put(fieldName, methodSet);
386 }
387 methodSet._get = method;
388 } else if (methodName.startsWith(JavaNaming.METHOD_PREFIX_IS)) {
389 if (method.getParameterTypes().length != 0)
390 continue;
391
392 Class type = method.getReturnType();
393 if (type == null)
394 continue;
395 if (type.isPrimitive()) {
396 if (type != Boolean.TYPE)
397 continue;
398 } else {
399 if (type != Boolean.class)
400 continue;
401 }
402
403 ++methodCount;
404
405 String fieldName = methodName.substring(JavaNaming.METHOD_PREFIX_IS.length());
406 fieldName = _javaNaming.toJavaMemberName(fieldName);
407
408 MethodSet methodSet = methodSets.get(fieldName);
409 if (methodSet == null) {
410 methodSet = new MethodSet(fieldName);
411 methodSets.put(fieldName, methodSet);
412 }
413 methodSet._get = method;
414 }
415
416
417 else if (methodName.startsWith(JavaNaming.METHOD_PREFIX_ADD)) {
418 if (method.getParameterTypes().length != 1)
419 continue;
420
421 ++methodCount;
422
423 if (!isDescriptable(method.getParameterTypes()[0]))
424 continue;
425
426 String fieldName = methodName.substring(3);
427 fieldName = _javaNaming.toJavaMemberName(fieldName);
428 MethodSet methodSet = methodSets.get(fieldName);
429 if (methodSet == null) {
430 methodSet = new MethodSet(fieldName);
431 methodSets.put(fieldName, methodSet);
432 }
433 methodSet._add = method;
434 }
435
436 else if (methodName.startsWith(JavaNaming.METHOD_PREFIX_SET)) {
437 if (method.getParameterTypes().length != 1) {
438 continue;
439 }
440
441 ++methodCount;
442
443 if (!isDescriptable(method.getParameterTypes()[0]))
444 continue;
445
446 String fieldName = methodName.substring(3);
447 fieldName = _javaNaming.toJavaMemberName(fieldName);
448 MethodSet methodSet = methodSets.get(fieldName);
449 if (methodSet == null) {
450 methodSet = new MethodSet(fieldName);
451 methodSets.put(fieldName, methodSet);
452 }
453 methodSet._set = method;
454 } else if (methodName.startsWith(JavaNaming.METHOD_PREFIX_CREATE)) {
455 if (method.getParameterTypes().length != 0)
456 continue;
457 Class type = method.getReturnType();
458
459
460 if (!isDescriptable(type))
461 continue;
462
463 String fieldName = methodName.substring(JavaNaming.METHOD_PREFIX_CREATE.length());
464 fieldName = _javaNaming.toJavaMemberName(fieldName);
465 MethodSet methodSet = methodSets.get(fieldName);
466 if (methodSet == null) {
467 methodSet = new MethodSet(fieldName);
468 methodSets.put(fieldName, methodSet);
469 }
470 methodSet._create = method;
471 }
472 }
473
474
475
476
477 Enumeration<MethodSet> enumeration = methodSets.elements();
478
479 while (enumeration.hasMoreElements()) {
480
481 MethodSet methodSet = enumeration.nextElement();
482
483
484 String xmlName = _xmlNaming.toXMLName(methodSet._fieldName);
485
486 boolean isCollection = false;
487
488
489
490 Class type = null;
491 if (methodSet._add != null) {
492 type = methodSet._add.getParameterTypes()[0];
493 isCollection = true;
494 }
495
496
497
498 if (type == null) {
499 if (methodSet._get != null) {
500 type = methodSet._get.getReturnType();
501 } else if (methodSet._set != null) {
502 type = methodSet._set.getParameterTypes()[0];
503 } else {
504
505
506 continue;
507 }
508 }
509
510
511 isCollection = (isCollection || isCollection(type));
512
513 TypeInfo typeInfo = null;
514 CollectionHandler colHandler = null;
515
516
517
518 if (isCollection && (methodSet._add == null)) {
519
520 try {
521 colHandler = CollectionHandlers.getHandler(type);
522 } catch (MappingException mx) {
523
524
525 }
526
527
528 if (type.isArray()) {
529
530
531 if (type.getComponentType() == Byte.TYPE) {
532 colHandler = null;
533 } else
534 type = type.getComponentType();
535 }
536 }
537
538 typeInfo = new TypeInfo(type, null, null, false, null, colHandler);
539
540
541
542
543 FieldHandler handler = null;
544 boolean customHandler = false;
545 try {
546 handler = new FieldHandlerImpl(methodSet._fieldName, null, null, methodSet._get,
547 methodSet._set, typeInfo);
548
549 if (methodSet._add != null)
550 ((FieldHandlerImpl) handler).setAddMethod(methodSet._add);
551
552 if (methodSet._create != null)
553 ((FieldHandlerImpl) handler).setCreateMethod(methodSet._create);
554
555
556 if (isCollection && _saveMapKeys && isMapCollection(type)) {
557 ((FieldHandlerImpl) handler).setConvertFrom(new IdentityConvertor());
558 }
559
560
561 FieldHandlerFactory factory = getHandlerFactory(type);
562 if (factory != null) {
563 GeneralizedFieldHandler gfh = factory.createFieldHandler(type);
564 if (gfh != null) {
565 gfh.setFieldHandler(handler);
566 handler = gfh;
567 customHandler = true;
568
569
570 if (gfh.getFieldType() != null) {
571 type = gfh.getFieldType();
572 }
573 }
574 }
575
576 } catch (MappingException mx) {
577 throw new MarshalException(mx);
578 }
579
580
581 XMLFieldDescriptorImpl fieldDesc = createFieldDescriptor(type, methodSet._fieldName, xmlName);
582
583 if (isCollection) {
584 fieldDesc.setMultivalued(true);
585 fieldDesc.setNodeType(NodeType.Element);
586 }
587
588
589 if (java.util.Date.class.isAssignableFrom(type)) {
590
591 if (!customHandler) {
592 dateDescriptors.add(fieldDesc);
593 }
594 }
595
596 fieldDesc.setHandler(handler);
597
598
599 fieldDesc.setUseParentsNamespace(true);
600
601
602 if (isCollection && _wrapCollectionsInContainer) {
603 String fieldName = COLLECTION_WRAPPER_PREFIX + methodSet._fieldName;
604
605
606
607
608
609
610
611
612
613
614
615
616 Class cType = ContainerElement.class;
617 XMLClassDescriptorImpl containerClassDesc = new XMLClassDescriptorImpl(cType);
618
619
620 containerClassDesc.addFieldDescriptor(fieldDesc);
621
622
623
624 fieldDesc.setXMLName(null);
625 fieldDesc.setMatches("*");
626
627
628
629 FieldHandler cHandler = new ContainerFieldHandler(handler);
630 fieldDesc.setHandler(cHandler);
631
632 fieldDesc = createFieldDescriptor(cType, fieldName, xmlName);
633 fieldDesc.setClassDescriptor(containerClassDesc);
634 fieldDesc.setHandler(cHandler);
635
636
637 fieldDesc.setUseParentsNamespace(true);
638
639 }
640
641 classDesc.addFieldDescriptor(fieldDesc);
642
643
644 }
645
646
647
648 if (methodCount == 0) {
649
650 Field[] fields = c.getFields();
651 Hashtable<String, XMLFieldDescriptorImpl> descriptors = new Hashtable<>();
652 for (int i = 0; i < fields.length; i++) {
653 Field field = fields[i];
654
655 Class owner = field.getDeclaringClass();
656
657
658
659 if (owner != c) {
660
661
662
663
664 if (!owner.isInterface())
665 continue;
666
667
668
669
670 if (interfaces.length > 0) {
671 boolean found = false;
672 for (int count = 0; count < interfaces.length; count++) {
673 if (interfaces[count] == owner) {
674 found = true;
675 break;
676 }
677 }
678 if (!found)
679 continue;
680 }
681 }
682
683
684 int modifiers = field.getModifiers();
685 if (Modifier.isTransient(modifiers))
686 continue;
687 if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers))
688 continue;
689
690 Class type = field.getType();
691
692
693
694 if (!isDescriptable(type))
695 continue;
696
697
698
699
700 boolean isCollection = isCollection(type);
701
702
703 TypeInfo typeInfo = null;
704 CollectionHandler colHandler = null;
705
706
707
708 if (isCollection) {
709
710 try {
711 colHandler = CollectionHandlers.getHandler(type);
712 } catch (MappingException mx) {
713
714
715 }
716
717
718 if (type.isArray()) {
719
720
721 if (type.getComponentType() == Byte.TYPE) {
722 colHandler = null;
723 } else
724 type = type.getComponentType();
725
726 }
727 }
728
729 String fieldName = field.getName();
730 String xmlName = _xmlNaming.toXMLName(fieldName);
731
732
733
734
735 typeInfo = new TypeInfo(type, null, null, false, null, colHandler);
736
737 FieldHandler handler = null;
738 boolean customHandler = false;
739 try {
740 handler = new FieldHandlerImpl(field, typeInfo);
741
742
743 if (isCollection && _saveMapKeys && isMapCollection(type)) {
744 ((FieldHandlerImpl) handler).setConvertFrom(new IdentityConvertor());
745 }
746
747
748 FieldHandlerFactory factory = getHandlerFactory(type);
749 if (factory != null) {
750 GeneralizedFieldHandler gfh = factory.createFieldHandler(type);
751 if (gfh != null) {
752 gfh.setFieldHandler(handler);
753 handler = gfh;
754 customHandler = true;
755
756
757 if (gfh.getFieldType() != null) {
758 type = gfh.getFieldType();
759 }
760 }
761 }
762 } catch (MappingException mx) {
763 throw new MarshalException(mx);
764 }
765
766 XMLFieldDescriptorImpl fieldDesc = createFieldDescriptor(type, fieldName, xmlName);
767
768 if (isCollection) {
769 fieldDesc.setNodeType(NodeType.Element);
770 fieldDesc.setMultivalued(true);
771 }
772 descriptors.put(xmlName, fieldDesc);
773 classDesc.addFieldDescriptor(fieldDesc);
774 fieldDesc.setHandler(handler);
775
776
777 fieldDesc.setUseParentsNamespace(true);
778
779
780 if (java.util.Date.class.isAssignableFrom(type)) {
781 if (!customHandler) {
782 dateDescriptors.add(fieldDesc);
783 }
784 }
785
786 }
787 }
788
789
790
791 if (dateDescriptors != null) {
792 for (XMLFieldDescriptorImpl fieldDesc : dateDescriptors) {
793 FieldHandler handler = fieldDesc.getHandler();
794 fieldDesc.setImmutable(true);
795 DateFieldHandler dfh = new DateFieldHandler(handler);
796
797
798 Class type = fieldDesc.getFieldType();
799 if (java.sql.Date.class.isAssignableFrom(type)) {
800 dfh.setUseSQLDate(true);
801 }
802 fieldDesc.setHandler(dfh);
803 }
804 }
805
806
807 if ((superClass != null) && (superClass != Void.class) && (superClass != Object.class)
808 && (superClass != Class.class)) {
809 try {
810 XMLClassDescriptor parent = generateClassDescriptor(superClass, errorWriter);
811 if (parent != null) {
812 classDesc.setExtends(parent);
813 }
814 } catch (MarshalException mx) {
815
816 }
817
818 }
819
820 return classDesc;
821 }
822
823
824
825
826
827
828
829
830 public synchronized boolean removeFieldHandlerFactory(FieldHandlerFactory factory) {
831 if (factory == null) {
832 String err = "The argument 'factory' must not be null.";
833 throw new IllegalArgumentException(err);
834 }
835
836
837 if (_handlerFactoryList == null)
838 return false;
839
840 if (_handlerFactoryList.remove(factory)) {
841
842 _handlerFactoryMap.clear();
843 for (FieldHandlerFactory tmp : _handlerFactoryList) {
844 registerHandlerFactory(tmp);
845 }
846 return true;
847 }
848 return false;
849 }
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874 public void setWrapCollections(boolean wrapCollections) {
875 _wrapCollectionsInContainer = wrapCollections;
876 }
877
878
879
880
881 public static boolean introspected(XMLClassDescriptor descriptor) {
882 return (descriptor instanceof IntrospectedXMLClassDescriptor);
883 }
884
885
886
887
888
889
890
891 public static boolean marshallable(Class type) {
892
893
894 if (type == Void.class || type == Class.class)
895 return false;
896
897 if ((!type.isInterface() || (type == Object.class))) {
898
899 if (!isPrimitive(type)) {
900
901
902
903
904
905
906 if (!type.isArray()) {
907
908
909
910 try {
911 type.getConstructor(EMPTY_CLASS_ARGS);
912 } catch (NoSuchMethodException e) {
913
914
915
916 return (CoreDescriptors.getDescriptor(type) != null);
917 }
918 }
919 }
920 }
921 return true;
922 }
923
924
925
926
927
928
929
930 public void setNaming(XMLNaming naming) {
931 if (naming == null)
932 _xmlNaming = _defaultNaming;
933 else
934 _xmlNaming = naming;
935 }
936
937
938
939
940
941
942
943 public void setPrimitiveNodeType(NodeType nodeType) {
944 if (nodeType == NodeType.Element)
945 _primitiveNodeType = nodeType;
946 else
947 _primitiveNodeType = NodeType.Attribute;
948 }
949
950
951
952
953
954
955
956
957
958
959
960 public void setSaveMapKeys(boolean saveMapKeys) {
961 _saveMapKeys = saveMapKeys;
962 }
963
964
965
966
967
968
969
970
971 public static String toJavaName(String name, boolean upperFirst) {
972
973 int size = name.length();
974 char[] ncChars = name.toCharArray();
975 int next = 0;
976
977 boolean uppercase = upperFirst;
978
979 for (int i = 0; i < size; i++) {
980 char ch = ncChars[i];
981
982 switch (ch) {
983 case ':':
984 case '-':
985 uppercase = true;
986 break;
987 default:
988 if (uppercase == true) {
989 ncChars[next] = Character.toUpperCase(ch);
990 uppercase = false;
991 } else
992 ncChars[next] = ch;
993 ++next;
994 break;
995 }
996 }
997 return new String(ncChars, 0, next);
998 }
999
1000
1001
1002
1003
1004
1005 private XMLFieldDescriptorImpl createFieldDescriptor(Class type, String fieldName,
1006 String xmlName) {
1007
1008 XMLFieldDescriptorImpl fieldDesc = new XMLFieldDescriptorImpl(type, fieldName, xmlName, null);
1009
1010 if (type.isArray()) {
1011 fieldDesc.setNodeType(NodeType.Element);
1012 }
1013
1014 else if (type.isPrimitive()) {
1015 fieldDesc.setNodeType(_primitiveNodeType);
1016 } else {
1017 fieldDesc.setNodeType(NodeType.Element);
1018 }
1019
1020
1021 if (type == java.lang.Object.class) {
1022 fieldDesc.setMatches(xmlName + " *");
1023 }
1024
1025 return fieldDesc;
1026 }
1027
1028
1029
1030
1031
1032
1033
1034 private FieldHandlerFactory getHandlerFactory(Class type) {
1035 if (_handlerFactoryMap != null) {
1036 Class tmp = type;
1037 while (tmp != null) {
1038 Object obj = _handlerFactoryMap.get(tmp);
1039 if (obj != null) {
1040 return (FieldHandlerFactory) obj;
1041 }
1042 tmp = tmp.getSuperclass();
1043 }
1044 }
1045
1046
1047 if (DEFAULT_HANDLER_FACTORY.isSupportedType(type))
1048 return DEFAULT_HANDLER_FACTORY;
1049
1050 return null;
1051 }
1052
1053
1054
1055
1056
1057 private void registerHandlerFactory(FieldHandlerFactory factory) {
1058 if (_handlerFactoryMap == null)
1059 _handlerFactoryMap = new Hashtable<>();
1060
1061 Class[] types = factory.getSupportedTypes();
1062 for (int i = 0; i < types.length; i++) {
1063 _handlerFactoryMap.put(types[i], factory);
1064 }
1065 }
1066
1067
1068
1069
1070
1071 public static boolean isCollection(Class clazz) {
1072
1073 if (clazz.isArray())
1074 return true;
1075
1076 for (int i = 0; i < COLLECTIONS.length; i++) {
1077
1078
1079
1080
1081
1082
1083 if ((clazz == COLLECTIONS[i]) || (COLLECTIONS[i].isAssignableFrom(clazz))) {
1084 return true;
1085 }
1086 }
1087 return false;
1088 }
1089
1090
1091
1092
1093
1094 public static boolean isMapCollection(Class clazz) {
1095
1096 if (clazz.isArray())
1097 return false;
1098
1099 for (int i = 0; i < COLLECTIONS.length; i++) {
1100
1101
1102
1103
1104
1105
1106 if ((clazz == COLLECTIONS[i]) || (COLLECTIONS[i].isAssignableFrom(clazz))) {
1107 if (COLLECTIONS[i] == java.util.Hashtable.class)
1108 return true;
1109
1110 if (COLLECTIONS[i].getName().equals(MAP))
1111 return true;
1112 }
1113 }
1114 return false;
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124 private static boolean isDescriptable(Class type) {
1125
1126 if (type == Void.class || type == Class.class)
1127 return false;
1128
1129
1130 float javaVersion =
1131 Float.valueOf(System.getProperty("java.specification.version")).floatValue();
1132 if (javaVersion >= 1.5) {
1133 try {
1134 Boolean isEnum = ReflectionUtil.isEnumViaReflection(type);
1135 if (isEnum.booleanValue()) {
1136 return true;
1137 }
1138 } catch (Exception e) {
1139
1140 }
1141 }
1142
1143 if ((!type.isInterface()) && (type != Object.class) && (!isPrimitive(type))) {
1144
1145
1146
1147
1148
1149
1150 if (!type.isArray()) {
1151
1152
1153
1154
1155 try {
1156 type.getConstructor(EMPTY_CLASS_ARGS);
1157 } catch (NoSuchMethodException e) {
1158
1159
1160
1161
1162 return (CoreDescriptors.getDescriptor(type) != null);
1163 }
1164 }
1165 }
1166 return true;
1167 }
1168
1169
1170
1171
1172
1173
1174 private static boolean isPrimitive(Class type) {
1175
1176 if (type.isPrimitive()) {
1177 return true;
1178 }
1179
1180 if ((type == Boolean.class) || (type == Character.class)) {
1181 return true;
1182 }
1183
1184 Class superClass = type.getSuperclass();
1185 if (superClass == Number.class) {
1186 return true;
1187 }
1188
1189 if (superClass != null) {
1190 return superClass.getName().equals("java.lang.Enum");
1191 } else {
1192 return false;
1193 }
1194
1195 }
1196
1197
1198
1199
1200
1201
1202
1203 private static Class[] loadCollections() {
1204
1205
1206 List<Class> collections = new ArrayList<>(6);
1207
1208
1209 collections.add(Vector.class);
1210 collections.add(Enumeration.class);
1211 collections.add(Hashtable.class);
1212
1213
1214 ClassLoader loader = Vector.class.getClassLoader();
1215
1216
1217 Class clazz = null;
1218 try {
1219 if (loader != null) {
1220 clazz = loader.loadClass(LIST);
1221 } else
1222 clazz = Class.forName(LIST);
1223 } catch (ClassNotFoundException cnfx) {
1224
1225
1226
1227 }
1228 if (clazz != null) {
1229
1230
1231 collections.add(clazz);
1232
1233 clazz = null;
1234 try {
1235
1236 if (loader != null) {
1237 clazz = loader.loadClass(MAP);
1238 } else
1239 clazz = Class.forName(MAP);
1240 if (clazz != null) {
1241 collections.add(clazz);
1242 }
1243
1244 if (loader != null) {
1245 clazz = loader.loadClass(SET_COLLECTION);
1246 } else
1247 clazz = Class.forName(SET_COLLECTION);
1248 if (clazz != null) {
1249 collections.add(clazz);
1250 }
1251
1252
1253 } catch (ClassNotFoundException cnfx) {
1254
1255
1256 }
1257 }
1258
1259 return collections.toArray(new Class[collections.size()]);
1260 }
1261
1262
1263 public void propertyChange(PropertyChangeEvent event) {
1264 if (event.getPropertyName().equals(XMLProperties.PRIMITIVE_NODE_TYPE)) {
1265 if (event.getNewValue() instanceof String) {
1266 this.setPrimitiveNodeType(NodeType.getNodeType((String) event.getNewValue()));
1267 } else {
1268 throw new IllegalArgumentException(
1269 "The value for '" + XMLProperties.PRIMITIVE_NODE_TYPE + "' must be of type String");
1270 }
1271 }
1272 }
1273
1274
1275
1276
1277
1278
1279 class IdentityConvertor implements TypeConvertor {
1280 public Object convert(final Object object) {
1281 return object;
1282 }
1283 }
1284
1285
1286
1287
1288 class MethodSet {
1289
1290 Method _add = null;
1291
1292
1293 Method _create = null;
1294
1295
1296 Method _get = null;
1297
1298
1299 Method _set = null;
1300
1301
1302 String _fieldName = null;
1303
1304 MethodSet(String fieldName) {
1305 super();
1306 this._fieldName = fieldName;
1307 }
1308 }
1309
1310 }
1311
1312
1313
1314
1315
1316 class IntrospectedXMLClassDescriptor extends XMLClassDescriptorImpl {
1317
1318
1319
1320
1321
1322 IntrospectedXMLClassDescriptor(Class type) {
1323 super(type);
1324 setIntrospected(true);
1325 }
1326
1327
1328
1329
1330
1331
1332 public IntrospectedXMLClassDescriptor(Class type, String xmlName) {
1333 super(type, xmlName);
1334 setIntrospected(true);
1335 }
1336
1337 }