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.exolab.castor.xml;
47
48 import java.util.HashMap;
49 import java.util.HashSet;
50 import java.util.Iterator;
51 import java.util.Map;
52 import java.util.Set;
53 import java.util.Vector;
54
55 import org.castor.xml.BackwardCompatibilityContext;
56 import org.castor.xml.InternalContext;
57 import org.castor.xml.AbstractInternalContext;
58 import org.castor.xml.JavaNaming;
59 import org.exolab.castor.mapping.ClassDescriptor;
60 import org.exolab.castor.mapping.CollectionHandler;
61 import org.exolab.castor.mapping.FieldDescriptor;
62 import org.exolab.castor.mapping.MappingException;
63 import org.exolab.castor.mapping.loader.CollectionHandlers;
64 import org.exolab.castor.util.ReflectionUtil;
65
66
67
68
69
70
71
72
73
74 abstract class MarshalFramework {
75
76
77
78
79
80
81
82
83
84
85 private static final double JDK_VERSION_1_5 = 1.5;
86
87
88
89
90 public static final String XSI_NAMESPACE
91 = "http://www.w3.org/2001/XMLSchema-instance";
92
93
94
95
96 public static final String XSI_SCHEMA_LOCATION = "schemaLocation";
97
98
99
100
101 public static final String XSI_NO_NAMESPACE_SCHEMA_LOCATION
102 = "noNamespaceSchemaLocation";
103
104
105
106
107 public static final String XML_LANG_ATTR = "xml:lang";
108
109
110
111
112 public static final String LANG_ATTR = "lang";
113
114
115
116
117 public static final String NIL_ATTR = "nil";
118
119
120
121
122 public static final String XSI_NIL_ATTR = "xsi:nil";
123
124
125
126
127 public static final String XML_SPACE_ATTR = "xml:space";
128
129
130
131
132 public static final String SPACE_ATTR = "space";
133
134
135
136
137 public static final String TYPE_ATTR = "type";
138
139
140
141
142 public static final String TRUE_VALUE = "true";
143
144
145
146
147
148
149
150
151 static final String INTERNAL_XML_NAME = "-error-if-this-is-used-";
152
153
154
155
156
157
158 static final String JAVA_PREFIX = "java:";
159
160
161
162
163 static final String QNAME_NAME = "QName";
164
165
166
167
168 static final XMLFieldDescriptor[] NO_FIELD_DESCRIPTORS
169 = new XMLFieldDescriptor[0];
170
171
172
173
174
175
176
177
178
179 private InternalContext _internalContext;
180
181
182
183
184
185
186
187
188
189
190
191
192
193 public MarshalFramework(final InternalContext internalContext) {
194 if (internalContext == null) {
195 _internalContext = new BackwardCompatibilityContext();
196 } else {
197 _internalContext = internalContext;
198 }
199 }
200
201
202
203
204
205 public JavaNaming getJavaNaming() {
206 return _internalContext.getJavaNaming();
207 }
208
209
210
211
212
213
214 private void setJavaNaming(final JavaNaming javaNaming) {
215 _internalContext.setJavaNaming(javaNaming);
216 }
217
218
219
220
221
222 public InternalContext getInternalContext() {
223 return _internalContext;
224 }
225
226
227
228
229
230 public void setInternalContext(final InternalContext internalContext) {
231 _internalContext = internalContext;
232 }
233
234
235
236
237
238
239
240
241 public static boolean isCollection(final Class clazz) {
242 return CollectionHandlers.hasHandler(clazz);
243 }
244
245
246
247
248
249
250
251 public CollectionHandler getCollectionHandler(final Class clazz) {
252 CollectionHandler handler = null;
253 try {
254 handler = CollectionHandlers.getHandler(clazz);
255 }
256 catch (MappingException mx) {
257
258 }
259 return handler;
260 }
261
262
263
264
265
266
267
268
269
270
271
272 static boolean isPrimitive(final Class type) {
273
274 if (type == null) {
275 return false;
276 }
277
278
279 if (type.isPrimitive()) {
280 return true;
281 }
282
283
284 if (type == String.class) {
285 return true;
286 }
287
288
289 if ((type == Boolean.class) || (type == Character.class)) {
290 return true;
291 }
292
293 Class superClass = type.getSuperclass();
294 if (superClass == Number.class) {
295 return true;
296 }
297
298 if (superClass != null) {
299 return superClass.getName().equals("java.lang.Enum");
300 }
301
302 return false;
303
304 }
305
306
307
308
309
310
311
312
313 static boolean isEnum(final Class type) {
314
315 if (type == null) {
316 return false;
317 }
318
319 float javaVersion =
320 Float.valueOf(System.getProperty("java.specification.version")).floatValue();
321 if (javaVersion >= JDK_VERSION_1_5) {
322 try {
323 Boolean isEnum = ReflectionUtil.isEnumViaReflection(type);
324 return isEnum.booleanValue();
325 } catch (Exception e) {
326
327 }
328 }
329
330
331
332 return false;
333
334 }
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361 static final boolean hasFieldsAtLocation
362 (final String location, final XMLClassDescriptor classDesc) {
363
364 XMLFieldDescriptor[] descriptors = classDesc.getElementDescriptors();
365 for (int i = 0; i < descriptors.length; i++) {
366 if (descriptors[i] == null) {
367 continue;
368 }
369 String tmpLocation = descriptors[i].getLocationPath();
370 if ((tmpLocation != null) && (tmpLocation.startsWith(location))) {
371 return true;
372 }
373 }
374
375
376 descriptors = classDesc.getAttributeDescriptors();
377 for (int i = 0; i < descriptors.length; i++) {
378 if (descriptors[i] == null) {
379 continue;
380 }
381 String tmpLocation = descriptors[i].getLocationPath();
382 if ((tmpLocation != null) && (tmpLocation.startsWith(location))) {
383 return true;
384 }
385 }
386
387
388 XMLFieldDescriptor content = classDesc.getContentDescriptor();
389 if (content != null) {
390 String tmpLocation = content.getLocationPath();
391 if ((tmpLocation != null) && (tmpLocation.startsWith(location))) {
392 return true;
393 }
394 }
395 return false;
396 }
397
398
399
400
401
402
403
404
405
406
407 public static boolean namespaceEquals(final String ns1, final String ns2) {
408 if (ns1 == null) {
409 return ((ns2 == null) || (ns2.length() == 0));
410 }
411 if (ns2 == null) {
412 return (ns1.length() == 0);
413 }
414 return ns1.equals(ns2);
415 }
416
417
418
419
420
421
422
423
424
425
426
427 static boolean primitiveOrWrapperEquals(final Class a, final Class b) {
428 if (!isPrimitive(a)) {
429 return false;
430 }
431 if (!isPrimitive(b)) {
432 return false;
433 }
434
435 if (a == b) {
436 return true;
437 }
438
439
440 if ((a == Boolean.class) || (a == Boolean.TYPE)) {
441 return ((b == Boolean.class) || (b == Boolean.TYPE));
442 }
443
444 else if ((a == Byte.class) || (a == Byte.TYPE)) {
445 return ((b == Byte.class) || (b == Byte.TYPE));
446 }
447
448 else if ((a == Character.class) || (a == Character.TYPE)) {
449 return ((b == Character.class) || (b == Character.TYPE));
450 }
451
452 else if ((a == Double.class) || (a == Double.TYPE)) {
453 return ((b == Double.class) || (b == Double.TYPE));
454 }
455 else if ((a == Float.class) || (a == Float.TYPE)) {
456 return ((b == Float.class) || (b == Float.TYPE));
457 }
458
459 else if ((a == Integer.class) || (a == Integer.TYPE)) {
460 return ((b == Integer.class) || (b == Integer.TYPE));
461 }
462
463 else if ((a == Long.class) || (a == Long.TYPE)) {
464 return ((b == Long.class) || (b == Long.TYPE));
465 }
466
467 else if ((a == Short.class) || (a == Short.TYPE)) {
468 return ((b == Short.class) || (b == Short.TYPE));
469 }
470
471 return false;
472 }
473
474
475
476
477 private static final InheritanceMatch[] NO_MATCH_ARRAY = new InheritanceMatch[0];
478
479
480
481
482
483
484
485
486
487
488
489
490 protected InheritanceMatch[] searchInheritance(final String name,
491 final String namespace,
492 final XMLClassDescriptor classDesc)
493 throws MarshalException {
494 Iterator classDescriptorIterator = null;
495
496 try {
497
498
499 String className = getJavaNaming().toJavaClassName(name);
500
501
502 Class clazz = classDesc.getJavaClass();
503 String pkg = null;
504 if (clazz != null) {
505 while (clazz.getDeclaringClass() != null) {
506 clazz = clazz.getDeclaringClass();
507 }
508 pkg = clazz.getName();
509 int idx = pkg.lastIndexOf('.');
510 if (idx >= 0) {
511 pkg = pkg.substring(0, idx + 1);
512 className = pkg + className;
513 }
514 }
515 getInternalContext().getXMLClassDescriptorResolver().resolve(
516 className, classDesc.getClass().getClassLoader());
517
518
519
520 classDescriptorIterator =
521 getInternalContext().getXMLClassDescriptorResolver().resolveAllByXMLName(
522 name, namespace, null);
523 }
524 catch (ResolverException rx) {
525 Throwable actual = rx.getCause();
526 if (actual instanceof MarshalException) {
527 throw (MarshalException) actual;
528 }
529 if (actual != null) {
530 throw new MarshalException(actual);
531 }
532 throw new MarshalException(rx);
533 }
534
535 Vector inheritanceList = null;
536 XMLFieldDescriptor descriptor = null;
537 XMLFieldDescriptor[] descriptors = classDesc.getElementDescriptors();
538 XMLClassDescriptor cdInherited = null;
539
540 if (classDescriptorIterator.hasNext()) {
541 while (classDescriptorIterator.hasNext() && (descriptor == null)) {
542 cdInherited = (XMLClassDescriptor) classDescriptorIterator.next();
543 Class subclass = cdInherited.getJavaClass();
544
545 for (int i = 0; i < descriptors.length; i++) {
546
547 if (descriptors[i] == null) {
548 continue;
549 }
550
551
552 if (INTERNAL_XML_NAME.equals(descriptors[i].getXMLName())) {
553 continue;
554 }
555
556
557 Class superclass = descriptors[i].getFieldType();
558
559
560 if (superclass.isAssignableFrom(subclass) && (superclass != Object.class)) {
561 descriptor = descriptors[i];
562 if (inheritanceList == null) {
563 inheritanceList = new Vector(3);
564 }
565 inheritanceList.addElement(new InheritanceMatch(descriptor, cdInherited));
566 }
567 }
568 }
569
570 if (descriptor == null) {
571 cdInherited = null;
572 }
573 }
574
575 if (inheritanceList != null) {
576 InheritanceMatch[] result = new InheritanceMatch[inheritanceList.size()];
577 inheritanceList.toArray(result);
578 return result;
579 }
580 return NO_MATCH_ARRAY;
581
582 }
583
584
585
586
587
588
589
590 public static class InheritanceMatch {
591
592
593
594 public XMLFieldDescriptor parentFieldDesc;
595
596
597
598 public XMLClassDescriptor inheritedClassDesc;
599
600 public InheritanceMatch(XMLFieldDescriptor fieldDesc, XMLClassDescriptor classDesc) {
601 parentFieldDesc = fieldDesc;
602 inheritedClassDesc = classDesc;
603 }
604 }
605
606
607
608
609
610
611
612 class InternalXMLClassDescriptor implements XMLClassDescriptor {
613
614 private XMLClassDescriptor _classDesc = null;
615
616
617
618
619 private XMLFieldDescriptor[] _attributes = null;
620
621
622
623 private XMLFieldDescriptor[] _elements = null;
624
625
626
627 private FieldDescriptor[] _fields = null;
628
629
630
631
632 private Map _properties = new HashMap();
633
634
635
636
637 private Set _natures = new HashSet();
638
639
640
641
642
643 protected InternalXMLClassDescriptor(XMLClassDescriptor classDesc)
644 {
645 if (classDesc == null) {
646 String err = "The argument 'classDesc' must not be null.";
647 throw new IllegalArgumentException(err);
648 }
649
650
651 while (classDesc instanceof InternalXMLClassDescriptor) {
652 classDesc = ((InternalXMLClassDescriptor) classDesc).getClassDescriptor();
653 }
654 _classDesc = classDesc;
655 }
656
657
658
659
660
661
662
663 public XMLClassDescriptor getClassDescriptor() {
664 return _classDesc;
665 }
666
667
668
669
670
671
672
673
674
675
676 public XMLFieldDescriptor[] getAttributeDescriptors() {
677 if (_attributes == null) {
678 _attributes = _classDesc.getAttributeDescriptors();
679 }
680 return _attributes;
681 }
682
683
684
685
686
687
688
689
690 public XMLFieldDescriptor getContentDescriptor() {
691 return _classDesc.getContentDescriptor();
692 }
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710 public XMLFieldDescriptor getFieldDescriptor
711 (final String name, final String namespace, final NodeType nodeType)
712 {
713 return _classDesc.getFieldDescriptor(name, namespace, nodeType);
714 }
715
716
717
718
719
720
721
722
723 public XMLFieldDescriptor[] getElementDescriptors() {
724 if (_elements == null) {
725 _elements = _classDesc.getElementDescriptors();
726 }
727 return _elements;
728 }
729
730
731
732
733 public String getNameSpacePrefix() {
734 return _classDesc.getNameSpacePrefix();
735 }
736
737
738
739
740 public String getNameSpaceURI() {
741 return _classDesc.getNameSpaceURI();
742 }
743
744
745
746
747
748
749
750
751
752 public TypeValidator getValidator() {
753 return _classDesc.getValidator();
754 }
755
756
757
758
759
760
761 public String getXMLName() {
762 return _classDesc.getXMLName();
763 }
764
765
766
767
768
769
770
771
772 public boolean introspected() {
773 return Introspector.introspected(_classDesc);
774 }
775
776
777
778
779
780 public boolean canAccept(final String name, final String namespace, final Object object) {
781 return _classDesc.canAccept(name, namespace, object);
782 }
783
784
785
786
787
788
789 public void checkDescriptorForCorrectOrderWithinSequence(
790 final XMLFieldDescriptor elementDescriptor,
791 final UnmarshalState parentState,
792 final String xmlName)
793 throws ValidationException {
794 _classDesc.checkDescriptorForCorrectOrderWithinSequence(elementDescriptor, parentState, xmlName);
795 }
796
797
798
799
800
801
802
803
804
805
806 public Class getJavaClass() {
807 return _classDesc.getJavaClass();
808 }
809
810
811
812
813
814
815
816 public FieldDescriptor[] getFields() {
817 if (_fields == null) {
818 _fields = _classDesc.getFields();
819 }
820 return _fields;
821 }
822
823
824
825
826
827
828
829 public ClassDescriptor getExtends() {
830 return _classDesc.getExtends();
831 }
832
833
834
835
836
837
838
839 public FieldDescriptor getIdentity() {
840 return _classDesc.getIdentity();
841 }
842
843
844
845
846
847
848 public boolean isChoice() {
849 return false;
850 }
851
852
853
854
855
856
857
858
859 public Object getProperty(final String name) {
860 return _properties.get(name);
861 }
862
863
864
865
866
867
868
869
870
871 public void setProperty(final String name, final Object value) {
872 _properties.put(name, value);
873 }
874
875
876
877
878
879
880
881 public void addNature(final String nature) {
882 _natures.add(nature);
883 }
884
885
886
887
888
889
890
891
892 public boolean hasNature(final String nature) {
893 return _natures.contains(nature);
894 }
895
896 }
897
898
899 }