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