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