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 package org.exolab.castor.xml;
39
40 import java.io.PrintWriter;
41 import java.io.Serializable;
42 import java.lang.reflect.Array;
43 import java.lang.reflect.InvocationTargetException;
44 import java.lang.reflect.Method;
45 import java.lang.reflect.Modifier;
46 import java.text.MessageFormat;
47 import java.util.ArrayList;
48 import java.util.HashMap;
49 import java.util.Hashtable;
50 import java.util.Locale;
51 import java.util.Map;
52 import java.util.ResourceBundle;
53 import java.util.StringTokenizer;
54
55 import org.apache.commons.lang3.StringUtils;
56 import org.apache.commons.logging.Log;
57 import org.apache.commons.logging.LogFactory;
58 import org.castor.core.util.Base64Decoder;
59 import org.castor.core.util.HexDecoder;
60 import org.castor.xml.InternalContext;
61 import org.exolab.castor.mapping.ClassDescriptor;
62 import org.exolab.castor.mapping.FieldHandler;
63 import org.exolab.castor.mapping.MapItem;
64 import org.exolab.castor.util.DefaultObjectFactory;
65 import org.exolab.castor.util.ObjectFactory;
66 import org.exolab.castor.xml.descriptors.PrimitivesClassDescriptor;
67 import org.exolab.castor.xml.descriptors.StringClassDescriptor;
68 import org.exolab.castor.xml.parsing.AnyNodeUnmarshalHandler;
69 import org.exolab.castor.xml.parsing.AttributeSetBuilder;
70 import org.exolab.castor.xml.parsing.NamespaceHandling;
71 import org.exolab.castor.xml.parsing.StrictElementHandler;
72 import org.exolab.castor.xml.parsing.UnmarshalListenerDelegate;
73 import org.exolab.castor.xml.parsing.UnmarshalStateStack;
74 import org.exolab.castor.xml.parsing.primitive.objects.PrimitiveObjectFactory;
75 import org.exolab.castor.xml.util.XMLFieldDescriptorImpl;
76 import org.xml.sax.AttributeList;
77 import org.xml.sax.Attributes;
78 import org.xml.sax.ContentHandler;
79 import org.xml.sax.DocumentHandler;
80 import org.xml.sax.ErrorHandler;
81 import org.xml.sax.Locator;
82 import org.xml.sax.SAXException;
83 import org.xml.sax.SAXParseException;
84
85
86
87
88
89
90
91
92
93 public final class UnmarshalHandler extends MarshalFramework
94 implements ContentHandler, DocumentHandler, ErrorHandler {
95
96
97
98 static final Log LOG = LogFactory.getLog(UnmarshalHandler.class);
99
100
101 protected static ResourceBundle resourceBundle;
102
103 static {
104 resourceBundle = ResourceBundle.getBundle("UnmarshalHandlerMessages", Locale.getDefault());
105 }
106
107
108
109
110
111
112
113
114 private static final String ERROR_DID_NOT_FIND_CLASSDESCRIPTOR =
115 "unable to find or create a ClassDescriptor for class: ";
116
117
118
119
120
121 private static final String XML_PREFIX = "xml";
122
123
124
125
126 private static final String XMLNS = "xmlns";
127
128
129
130
131 private final static String XMLNS_PREFIX = "xmlns:";
132
133
134
135
136 private static final String XSI_TYPE = "type";
137
138 static final String XML_SPACE = "space";
139 static final String XML_SPACE_WITH_PREFIX = "xml:space";
140 static final String PRESERVE = "preserve";
141
142
143
144
145
146 private UnmarshalState _topState = null;
147 private Class<?> _topClass = null;
148
149
150
151
152 private Object _topObject = null;
153
154
155
156
157
158 private boolean _clearCollections = false;
159
160
161
162
163 private Locator _locator = null;
164
165
166
167
168 private IDResolver _idResolver = null;
169
170
171
172
173 private boolean _validate = true;
174
175
176
177
178 private Hashtable<String, ReferenceInfo> _resolveTable = new Hashtable<String, ReferenceInfo>();
179
180 private Map<Class<?>, String> _javaPackages = null;
181
182 private ClassLoader _loader = null;
183
184 private static final StringClassDescriptor STRING_DESCRIPTOR = new StringClassDescriptor();
185
186
187
188
189 private org.exolab.castor.types.AnyNode _node = null;
190
191
192
193
194
195 private ObjectFactory _objectFactory = new DefaultObjectFactory();
196
197
198
199
200 private boolean _reuseObjects = false;
201
202
203
204
205
206 private boolean _strictAttributes = false;
207
208
209
210
211 private boolean _wsPreserve = false;
212
213
214
215
216 private StrictElementHandler _strictElementHandler = new StrictElementHandler();
217
218
219
220
221 private UnmarshalStateStack _stateStack = new UnmarshalStateStack();
222
223
224
225
226 private UnmarshalListenerDelegate _delegateUnmarshalListener = new UnmarshalListenerDelegate();
227
228 private AnyNodeUnmarshalHandler _anyNodeHandler = null;
229
230 private NamespaceHandling _namespaceHandling = new NamespaceHandling();
231
232 private AttributeSetBuilder _attributeSetFactory = null;
233
234
235
236
237
238
239
240
241
242 protected UnmarshalHandler() {
243 this(null);
244 }
245
246
247
248
249
250
251 protected UnmarshalHandler(final Class<?> topClass) {
252 this(null, topClass);
253 }
254
255
256
257
258
259
260
261 protected UnmarshalHandler(final InternalContext internalContext, final Class<?> topClass) {
262 super(internalContext);
263 _idResolver = new IDResolverImpl();
264 _javaPackages = new HashMap<Class<?>, String>();
265 _topClass = topClass;
266 _anyNodeHandler = new AnyNodeUnmarshalHandler(_namespaceHandling);
267 _attributeSetFactory = new AttributeSetBuilder(_namespaceHandling);
268 }
269
270
271
272
273
274
275
276 public void addNamespaceToPackageMapping(String nsURI, String packageName) {
277 _namespaceHandling.addNamespaceToPackageMapping(nsURI, packageName);
278
279 }
280
281
282
283
284
285
286
287
288 public Object getCurrentObject() {
289 if (!_stateStack.isEmpty()) {
290 UnmarshalState state = _stateStack.getLastState();
291 if (state != null) {
292 return state.getObject();
293 }
294 }
295 return null;
296 }
297
298
299
300
301
302
303 public Object getObject() {
304 if (_topState != null) {
305 return _topState.getObject();
306 }
307 return null;
308 }
309
310
311
312
313
314
315 public void setClassLoader(ClassLoader loader) {
316 _loader = loader;
317 }
318
319
320
321
322
323
324
325
326
327 public void setClearCollections(boolean clear) {
328 _clearCollections = clear;
329 }
330
331
332
333
334
335
336 public void setDebug(boolean debug) {
337
338 }
339
340
341
342
343
344
345
346
347 public void setIDResolver(final IDResolver idResolver) {
348 ((IDResolverImpl) _idResolver).setResolver(idResolver);
349 }
350
351
352
353
354
355
356
357
358
359 public void setIgnoreExtraAttributes(boolean ignoreExtraAtts) {
360 _strictAttributes = (!ignoreExtraAtts);
361 }
362
363
364
365
366
367
368
369
370 public void setIgnoreExtraElements(boolean ignoreExtraElems) {
371 _strictElementHandler.setIgnoreExtraElements(ignoreExtraElems);
372 }
373
374
375
376
377
378
379 public void setLogWriter(PrintWriter printWriter) {
380
381 }
382
383
384
385
386
387
388
389
390 public void setReuseObjects(boolean reuse) {
391 _reuseObjects = reuse;
392 }
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 public void setRootObject(Object root) {
410 _topObject = root;
411 }
412
413
414
415
416
417
418
419
420 public void setUnmarshalListener(org.exolab.castor.xml.UnmarshalListener listener) {
421 _delegateUnmarshalListener.setUnmarshalListener(listener);
422 }
423
424
425
426
427
428
429
430 public void setUnmarshalListener(org.castor.xml.UnmarshalListener listener) {
431 _delegateUnmarshalListener.setUnmarshalListener(listener);
432 }
433
434
435
436
437
438
439
440
441 public void setValidation(boolean validate) {
442 this._validate = validate;
443 }
444
445
446
447
448
449
450
451
452 public void setWhitespacePreserve(boolean preserve) {
453 _wsPreserve = preserve;
454 }
455
456
457
458
459
460 public void characters(char[] ch, int start, int length) throws SAXException {
461 new CharactersProcessor(this).compute(ch, start, length);
462 }
463
464
465 public void endDocument() throws org.xml.sax.SAXException {
466
467
468
469 }
470
471
472 public void endElement(String name) throws org.xml.sax.SAXException {
473 new EndElementProcessor(this).compute(name);
474 }
475
476
477
478
479
480
481
482
483
484 byte[] decodeBinaryData(final XMLFieldDescriptor descriptor, final String binaryData) {
485
486 byte[] decodedValue;
487 if ((descriptor.isMultivalued() && HexDecoder.DATA_TYPE.equals(descriptor.getComponentType()))
488 || HexDecoder.DATA_TYPE.equals(descriptor.getSchemaType())) {
489 decodedValue = HexDecoder.decode(binaryData);
490 } else {
491 decodedValue = Base64Decoder.decode(binaryData);
492 }
493 return decodedValue;
494 }
495
496
497
498
499
500
501
502
503
504
505 public void endElement(String namespaceURI, String localName, String qName)
506 throws org.xml.sax.SAXException {
507 if (StringUtils.isEmpty(qName)) {
508 if (StringUtils.isEmpty(localName)) {
509 String error = resourceBundle.getString("unmarshalHandler.error.localName.and.qName.null");
510 throw new SAXException(error);
511 }
512 qName = localName;
513 if (StringUtils.isNotEmpty(namespaceURI)) {
514
515 String prefix = _namespaceHandling.getNamespacePrefix(namespaceURI);
516 if (StringUtils.isEmpty(prefix))
517 qName = prefix + ":" + localName;
518 }
519 }
520
521 endElement(qName);
522 }
523
524
525
526
527
528
529
530 public void endPrefixMapping(String prefix) throws SAXException {
531
532
533
534 if (_anyNodeHandler.hasAnyUnmarshaller()) {
535 _anyNodeHandler.endPrefixMapping(prefix);
536 }
537
538 }
539
540
541 public void ignorableWhitespace(char[] ch, int start, int length)
542 throws org.xml.sax.SAXException {
543
544
545
546 if (_strictElementHandler.skipElement()) {
547 return;
548 }
549
550 if (_stateStack.isEmpty()) {
551 return;
552 }
553
554 if (_anyNodeHandler.hasAnyUnmarshaller()) {
555 _anyNodeHandler.ignorableWhitespace(ch, start, length);
556 } else {
557 UnmarshalState state = _stateStack.getLastState();
558 if (state.isWhitespacePreserving()) {
559 if (state.getBuffer() == null)
560 state.setBuffer(new StringBuffer());
561 state.getBuffer().append(ch, start, length);
562 }
563 }
564 }
565
566 public void processingInstruction(String target, String data) throws org.xml.sax.SAXException {
567
568 }
569
570 public void setDocumentLocator(Locator locator) {
571 this._locator = locator;
572 }
573
574 public Locator getDocumentLocator() {
575 return _locator;
576 }
577
578
579
580
581
582
583 public void skippedEntity(String name) throws SAXException {
584
585
586 }
587
588
589
590
591 public void startDocument() throws org.xml.sax.SAXException {
592
593
594
595
596
597 }
598
599 private void extractNamespaceInformation(Attributes attributes) {
600
601 if (attributes == null || attributes.getLength() == 0) {
602 return;
603 }
604
605
606
607 for (int i = 0; i < attributes.getLength(); i++) {
608 String attributeName = attributes.getQName(i);
609 if (StringUtils.isNotEmpty(attributeName)) {
610 if (attributeName.equals(XMLNS)) {
611 _namespaceHandling.addDefaultNamespace(attributes.getValue(i));
612 } else if (attributeName.startsWith(XMLNS_PREFIX)) {
613 String prefix = attributeName.substring(XMLNS_PREFIX.length());
614 _namespaceHandling.addNamespace(prefix, attributes.getValue(i));
615 }
616 } else {
617
618
619 attributeName = attributes.getLocalName(i);
620 if (XMLNS.equals(attributeName)) {
621 _namespaceHandling.addDefaultNamespace(attributes.getValue(i));
622 }
623 }
624 }
625 }
626
627
628
629
630
631
632
633
634
635
636
637 public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
638 throws org.xml.sax.SAXException {
639 if (LOG.isTraceEnabled()) {
640 String trace;
641 if (StringUtils.isNotEmpty(qName))
642 trace = MessageFormat.format(
643 resourceBundle.getString("unmarshalHandler.log.trace.startElement"),
644 new Object[] {qName});
645 else
646 trace = MessageFormat.format(
647 resourceBundle.getString("unmarshalHandler.log.trace.startElement"),
648 new Object[] {localName});
649 LOG.trace(trace);
650 }
651
652
653
654 if (_strictElementHandler.skipStartElement()) {
655 return;
656 }
657
658
659
660 if (_anyNodeHandler.hasAnyUnmarshaller()) {
661 _anyNodeHandler.startElement(namespaceURI, localName, qName, atts);
662 return;
663 }
664
665
666
667 if (_namespaceHandling.isNewNamespaceScopeNecessary()) {
668 _namespaceHandling.startNamespaceScope();
669 } else {
670 _namespaceHandling.setNewNamespaceScopeNecessary(true);
671 }
672
673
674 extractNamespaceInformation(atts);
675
676
677 String tmpQName = null;
678
679 if (StringUtils.isEmpty(localName)) {
680 if (StringUtils.isEmpty(qName)) {
681 String error = resourceBundle.getString("unmarshalHandler.error.localName.and.qName.null");
682 throw new SAXException(error);
683 }
684 localName = qName;
685 tmpQName = qName;
686 } else {
687 if (StringUtils.isEmpty(qName)) {
688 if (StringUtils.isEmpty(namespaceURI)) {
689 tmpQName = localName;
690 } else {
691 String prefix = _namespaceHandling.getNamespacePrefix(namespaceURI);
692 if (StringUtils.isNotEmpty(prefix)) {
693 tmpQName = prefix + ":" + localName;
694 }
695 }
696
697 } else {
698 tmpQName = qName;
699 }
700 }
701 _anyNodeHandler.preservePassedArguments(tmpQName, atts);
702
703 int idx = localName.indexOf(':');
704 if (idx >= 0) {
705 String prefix = localName.substring(0, idx);
706 localName = localName.substring(idx + 1);
707 if (StringUtils.isEmpty(namespaceURI)) {
708 namespaceURI = _namespaceHandling.getNamespaceURI(prefix);
709 }
710 } else {
711
712 String defaultNamespace = _namespaceHandling.getDefaultNamespaceURI();
713
714 if (defaultNamespace != null && !defaultNamespace.equals("http://castor.exolab.org")) {
715 namespaceURI = defaultNamespace;
716 }
717
718 if (StringUtils.isEmpty(namespaceURI))
719 namespaceURI = null;
720 }
721
722
723 startElementProcessing(localName, namespaceURI, _attributeSetFactory.getAttributeSet(atts));
724
725 }
726
727
728
729
730
731
732
733
734
735
736
737
738 public void startElement(String name, AttributeList attList) throws org.xml.sax.SAXException {
739 if (LOG.isTraceEnabled()) {
740 String trace = MessageFormat.format(
741 resourceBundle.getString("unmarshalHandler.log.trace.startElement"), new Object[] {name});
742 LOG.trace(trace);
743 }
744
745
746
747 if (_strictElementHandler.skipStartElement()) {
748 return;
749 }
750
751
752
753 if (_anyNodeHandler.hasAnyUnmarshaller()) {
754 _anyNodeHandler.startElement(name, attList);
755 return;
756 }
757
758 _anyNodeHandler.preservePassedArguments(name, attList);
759
760
761 String namespace = null;
762
763
764
765
766 _namespaceHandling.createNamespace();
767
768 String prefix = "";
769
770 int idx = name.indexOf(':');
771 if (idx >= 0) {
772 prefix = name.substring(0, idx);
773 name = name.substring(idx + 1);
774 }
775
776 namespace = _namespaceHandling.getNamespaceURI(prefix);
777
778
779
780
781 startElementProcessing(name, namespace, _attributeSetFactory.getAttributeSet(attList));
782
783 }
784
785
786
787
788
789
790
791
792
793
794 void startElementProcessing(String name, String namespace, AttributeSet atts)
795 throws SAXException {
796 new StartElementProcessor(this).compute(name, namespace, atts);
797 }
798
799 void processFirstElement(String name, String namespace, AttributeSet atts, String xmlSpace)
800 throws SAXException {
801 if (_topClass == null) {
802 if (_topObject != null) {
803 _topClass = _topObject.getClass();
804 }
805 }
806
807
808
809
810
811
812
813
814
815
816 if (getInternalContext().getXMLClassDescriptorResolver() == null) {
817
818 String message =
819 resourceBundle.getString("unmarshalHandler.log.warn.class.descriptor.not.set");
820 LOG.warn(message);
821 throw new IllegalStateException(message);
822 }
823
824 _topState = new UnmarshalState();
825 _topState.setElementName(name);
826 _topState.setWhitespacePreserving((xmlSpace != null) ? PRESERVE.equals(xmlSpace) : _wsPreserve);
827
828 XMLClassDescriptor classDesc = null;
829
830
831 String instanceClassname = null;
832 if (_topClass == null) {
833
834
835 instanceClassname = getInstanceType(atts, null);
836 if (instanceClassname != null) {
837
838 try {
839 _topClass = loadClass(instanceClassname, null);
840 } catch (ClassNotFoundException cnfe) {
841 }
842
843 if (_topClass == null) {
844 classDesc = getClassDescriptor(instanceClassname);
845 if (classDesc != null) {
846 _topClass = classDesc.getJavaClass();
847 }
848 if (_topClass == null) {
849 String error = MessageFormat.format(
850 resourceBundle.getString("unmarshalHandler.error.class.not.found"),
851 new Object[] {instanceClassname});
852 throw new SAXException(error);
853 }
854 }
855 } else {
856 classDesc = resolveByXMLName(name, namespace, null);
857 if (classDesc == null) {
858 classDesc = getClassDescriptor(name, _loader);
859 if (classDesc == null) {
860 classDesc = getClassDescriptor(getJavaNaming().toJavaClassName(name));
861 }
862 }
863 if (classDesc != null) {
864 _topClass = classDesc.getJavaClass();
865 }
866 }
867
868 if (_topClass == null) {
869 String err = MessageFormat.format(
870 resourceBundle.getString("unmarshalHandler.error.class.root.not.found"),
871 new Object[] {name});
872 throw new SAXException(err);
873 }
874 }
875
876
877 XMLFieldDescriptorImpl fieldDesc =
878 new XMLFieldDescriptorImpl(_topClass, name, name, NodeType.Element);
879
880 _topState.setFieldDescriptor(fieldDesc);
881
882
883 if (classDesc == null) {
884 classDesc = getClassDescriptor(_topClass);
885 }
886
887
888 if (classDesc == null) {
889 if (isPrimitive(_topClass)) {
890 classDesc = new PrimitivesClassDescriptor(_topClass);
891 fieldDesc.setIncremental(false);
892 _topState.setPrimitiveOrImmutable(true);
893 }
894 }
895
896 fieldDesc.setClassDescriptor(classDesc);
897 if (classDesc == null) {
898
899 if ((!isPrimitive(_topClass)) && (!Serializable.class.isAssignableFrom(_topClass))) {
900 throw new SAXException(MarshalException.NON_SERIALIZABLE_ERR);
901 }
902
903 String err = MessageFormat.format(
904 resourceBundle.getString("unmarshalHandler.error.create.class.descriptor"),
905 new Object[] {_topClass.getName()});
906
907 throw new SAXException(err);
908 }
909 _topState.setClassDescriptor(classDesc);
910 _topState.setType(_topClass);
911
912 if ((_topObject == null) && (!_topState.isPrimitiveOrImmutable())) {
913
914 String topPackage = getJavaPackage(_topClass);
915
916 if (instanceClassname == null) {
917 instanceClassname = getInstanceType(atts, topPackage);
918 } else {
919
920
921 instanceClassname = null;
922 }
923
924 if (instanceClassname != null) {
925 Class<?> instanceClass = null;
926 try {
927
928 XMLClassDescriptor xcd = getClassDescriptor(instanceClassname);
929
930 boolean loadClass = true;
931 if (xcd != null) {
932 instanceClass = xcd.getJavaClass();
933 if (instanceClass != null) {
934 loadClass = (!instanceClassname.equals(instanceClass.getName()));
935 }
936 }
937
938 if (loadClass) {
939 try {
940 instanceClass = loadClass(instanceClassname, null);
941 } catch (ClassNotFoundException cnfe) {
942
943
944 if (xcd != null) {
945 instanceClass = xcd.getJavaClass();
946 }
947 }
948 }
949
950 if (instanceClass == null) {
951 String error = MessageFormat.format(
952 resourceBundle.getString("unmarshalHandler.error.class.not.found"),
953 new Object[] {instanceClassname});
954 throw new SAXException(error);
955 }
956
957 if (!_topClass.isAssignableFrom(instanceClass)) {
958 String err = MessageFormat.format(
959 resourceBundle.getString("unmarshalHandler.error.not.subclass"),
960 new Object[] {instanceClass, _topClass});
961 throw new SAXException(err);
962 }
963
964 } catch (Exception ex) {
965 String err = MessageFormat.format(
966 resourceBundle.getString("unmarshalHandler.error.unable.instantiate"),
967 new Object[] {instanceClassname});
968 throw new SAXException(err, ex);
969 }
970
971
972 Arguments args = processConstructorArgs(atts, classDesc);
973 _topState.setObject(createInstance(instanceClass, args));
974 } else {
975
976
977 Arguments args = processConstructorArgs(atts, classDesc);
978 _topState.setObject(createInstance(_topClass, args));
979 }
980 } else {
981
982 _topState.setObject(_topObject);
983 }
984
985 _stateStack.pushState(_topState);
986
987 if (!_topState.isPrimitiveOrImmutable()) {
988
989
990 Object stateObject = _topState.getObject();
991 Object parentObject =
992 (_topState.getParent() == null) ? null : _topState.getParent().getObject();
993
994 _delegateUnmarshalListener.initialized(stateObject, parentObject);
995 processAttributes(atts, classDesc);
996 _delegateUnmarshalListener.attributesProcessed(stateObject, parentObject);
997 _namespaceHandling.processNamespaces(classDesc, _stateStack.getLastState().getObject());
998 }
999
1000 String pkg = getJavaPackage(_topClass);
1001 if (getMappedPackage(namespace) == null) {
1002 addNamespaceToPackageMapping(namespace, pkg);
1003 }
1004 }
1005
1006
1007
1008
1009
1010
1011
1012 boolean isValidating() {
1013 return _validate;
1014 }
1015
1016
1017
1018
1019
1020
1021
1022 public void startPrefixMapping(String prefix, String uri) throws SAXException {
1023
1024
1025
1026 if (Namespaces.XML_NAMESPACE_PREFIX.equals(prefix) && Namespaces.XML_NAMESPACE.equals(uri)) {
1027 return;
1028 } else if (XMLNS.equals(prefix)) {
1029 return;
1030 }
1031
1032
1033
1034
1035 if (_anyNodeHandler.hasAnyUnmarshaller()) {
1036 _anyNodeHandler.startPrefixMapping(prefix, uri);
1037 } else if (_namespaceHandling.isNewNamespaceScopeNecessary()) {
1038 _namespaceHandling.stopNamespaceScope();
1039 }
1040 _namespaceHandling.addNamespace(prefix, uri);
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050 }
1051
1052
1053
1054
1055
1056
1057 public void error(SAXParseException exception) throws org.xml.sax.SAXException {
1058 String error = MessageFormat
1059 .format(resourceBundle.getString("unmarshalHandler.error.sax.exception"), new Object[] {
1060 exception.getMessage(), exception.getLineNumber(), exception.getColumnNumber()});
1061 throw new SAXException(error, exception);
1062 }
1063
1064 public void fatalError(SAXParseException exception) throws org.xml.sax.SAXException {
1065 this.error(exception);
1066
1067 }
1068
1069
1070 public void warning(SAXParseException exception) throws org.xml.sax.SAXException {
1071 this.error(exception);
1072
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105 void addReference(final String idRef, final Object parent, final XMLFieldDescriptor descriptor) {
1106
1107 ReferenceInfo refInfo = new ReferenceInfo(idRef, parent, descriptor);
1108 refInfo.setNext(_resolveTable.get(idRef));
1109 _resolveTable.put(idRef, refInfo);
1110 }
1111
1112
1113
1114
1115
1116
1117
1118 Object createInstance(final Class<?> type, final Arguments args) throws SAXException {
1119 Object instance = null;
1120 try {
1121 if (args == null) {
1122 instance = _objectFactory.createInstance(type);
1123 } else {
1124 instance = _objectFactory.createInstance(type, args.getTypes(), args.getValues());
1125 }
1126 } catch (Exception ex) {
1127 String error = MessageFormat.format(
1128 resourceBundle.getString("unmarshalHandler.error.unable.instantiate"),
1129 new Object[] {type.getName()});
1130 throw new SAXException(error, ex);
1131 }
1132 return instance;
1133 }
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143 String getInstanceType(AttributeSet atts, String currentPackage) throws SAXException {
1144
1145 if (atts == null)
1146 return null;
1147
1148
1149 String type = atts.getValue(XSI_TYPE, XSI_NAMESPACE);
1150
1151 if (type != null) {
1152
1153 if (type.startsWith(JAVA_PREFIX)) {
1154 return type.substring(JAVA_PREFIX.length());
1155 }
1156
1157
1158 int idx = type.indexOf(':');
1159 String typeNamespaceURI = null;
1160 if (idx >= 0) {
1161
1162 String prefix = type.substring(0, idx);
1163 type = type.substring(idx + 1);
1164 typeNamespaceURI = _namespaceHandling.getNamespaceURI(prefix);
1165 }
1166
1167
1168
1169 XMLClassDescriptor classDesc = null;
1170
1171 try {
1172 classDesc = getInternalContext().getXMLClassDescriptorResolver().resolveByXMLName(type,
1173 typeNamespaceURI, _loader);
1174
1175 if (classDesc != null)
1176 return classDesc.getJavaClass().getName();
1177
1178
1179
1180
1181
1182 final String className = getJavaNaming().toJavaClassName(type);
1183
1184 String adjClassName = className;
1185 String mappedPackage = getMappedPackage(typeNamespaceURI);
1186 if ((mappedPackage != null) && (mappedPackage.length() > 0)) {
1187 adjClassName = mappedPackage + "." + className;
1188 }
1189 classDesc =
1190 getInternalContext().getXMLClassDescriptorResolver().resolve(adjClassName, _loader);
1191 if (classDesc != null)
1192 return classDesc.getJavaClass().getName();
1193
1194
1195 if (StringUtils.isNotEmpty(currentPackage)) {
1196 adjClassName = currentPackage + '.' + className;
1197 }
1198
1199 classDesc =
1200 getInternalContext().getXMLClassDescriptorResolver().resolve(adjClassName, _loader);
1201 if (classDesc != null)
1202 return classDesc.getJavaClass().getName();
1203
1204
1205
1206
1207
1208
1209 classDesc = getInternalContext().getXMLClassDescriptorResolver().resolve(type, _loader);
1210 if (classDesc != null)
1211 return classDesc.getJavaClass().getName();
1212 } catch (ResolverException rx) {
1213 throw new SAXException(rx);
1214 }
1215 }
1216 return null;
1217 }
1218
1219
1220
1221
1222
1223
1224
1225 private String getMappedPackage(final String namespace) {
1226 return _namespaceHandling.getMappedPackage(namespace);
1227 }
1228
1229
1230
1231
1232
1233
1234
1235
1236 void processAttributes(final AttributeSet atts, XMLClassDescriptor classDesc)
1237 throws SAXException {
1238
1239
1240 if ((atts == null) || (atts.getSize() == 0)) {
1241 if (classDesc != null) {
1242 XMLFieldDescriptor[] descriptors = classDesc.getAttributeDescriptors();
1243 for (int i = 0; i < descriptors.length; i++) {
1244 XMLFieldDescriptor descriptor = descriptors[i];
1245 if (descriptor == null) {
1246 continue;
1247 }
1248
1249
1250
1251 if (descriptor.isRequired() && (isValidating() || LOG.isDebugEnabled())) {
1252 String errorMsg;
1253 if (_locator != null) {
1254 errorMsg = MessageFormat.format(
1255 resourceBundle.getString("unmarshalHandler.error.attribute.missing.location"),
1256 classDesc.getXMLName(), descriptor.getXMLName(), _locator.getLineNumber(),
1257 _locator.getColumnNumber());
1258 } else {
1259 errorMsg = MessageFormat.format(
1260 resourceBundle.getString("unmarshalHandler.error.attribute.missing"),
1261 classDesc.getXMLName(), descriptor.getXMLName());
1262 }
1263 if (isValidating()) {
1264 throw new SAXException(errorMsg);
1265 }
1266 LOG.debug(errorMsg);
1267 }
1268 }
1269 }
1270 return;
1271 }
1272
1273
1274 UnmarshalState state = _stateStack.getLastState();
1275 Object object = state.getObject();
1276
1277 if (classDesc == null) {
1278 classDesc = state.getClassDescriptor();
1279 if (classDesc == null) {
1280
1281
1282 processWrapperAttributes(atts);
1283 return;
1284 }
1285 }
1286
1287
1288
1289
1290
1291
1292 boolean[] processedAtts = new boolean[atts.getSize()];
1293 XMLFieldDescriptor[] descriptors = classDesc.getAttributeDescriptors();
1294 for (XMLFieldDescriptor descriptor : descriptors) {
1295
1296 String name = descriptor.getXMLName();
1297 String namespace = descriptor.getNameSpaceURI();
1298 String path = descriptor.getLocationPath();
1299 StringBuilder fullAttributePath = new StringBuilder();
1300
1301 if (StringUtils.isNotEmpty(path)) {
1302 fullAttributePath.append(path).append('/');
1303 }
1304
1305 fullAttributePath.append(name);
1306
1307 if (!name.equals(fullAttributePath.toString())) {
1308 int index = atts.getIndex(name, namespace);
1309 if (index >= 0) {
1310 processedAtts[index] = true;
1311 }
1312 continue;
1313 }
1314
1315 int index = atts.getIndex(name, namespace);
1316
1317 String attValue = null;
1318 if (index >= 0) {
1319 attValue = atts.getValue(index);
1320 processedAtts[index] = true;
1321 }
1322
1323 try {
1324 processAttribute(name, namespace, attValue, descriptor, classDesc, object);
1325 } catch (IllegalStateException ise) {
1326 String error = MessageFormat.format(
1327 resourceBundle.getString("unmarshalHandler.error.unable.add.attribute"),
1328 new Object[] {name, state.getClassDescriptor().getJavaClass().getName(), ise});
1329 throw new SAXException(error, ise);
1330 }
1331 }
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342 for (int i = 0; i < processedAtts.length; i++) {
1343 if (processedAtts[i]) {
1344 continue;
1345 }
1346
1347 String namespace = atts.getNamespace(i);
1348 String name = atts.getName(i);
1349
1350
1351 if (XSI_NAMESPACE.equals(namespace)) {
1352 if (NIL_ATTR.equals(name)) {
1353 String value = atts.getValue(i);
1354 state.setNil(("true".equals(value)));
1355 }
1356 continue;
1357 }
1358
1359
1360 if (name.startsWith(XML_PREFIX + ':')) {
1361
1362
1363
1364
1365 if (LOG.isDebugEnabled()) {
1366 String debugMsg = MessageFormat.format(
1367 resourceBundle.getString("unmarshalHandler.log.debug.ignore.extra.attribute"),
1368 new Object[] {name, state.getClassDescriptor().getJavaClass().getName()});
1369 LOG.debug(debugMsg);
1370 }
1371 continue;
1372 }
1373
1374
1375
1376
1377 XMLFieldDescriptor descriptor =
1378 classDesc.getFieldDescriptor(name, namespace, NodeType.Attribute);
1379
1380 if (descriptor == null) {
1381
1382
1383 String path = state.getElementName();
1384 Integer parentStateIndex = _stateStack.getFirstParentStateIndex();
1385 while (parentStateIndex >= 0) {
1386 UnmarshalState targetState = _stateStack.peekAtState(parentStateIndex--);
1387 if (targetState.isWrapper()) {
1388 path = targetState.getElementName() + '/' + path;
1389 continue;
1390 }
1391 classDesc = targetState.getClassDescriptor();
1392 descriptor = classDesc.getFieldDescriptor(name, namespace, NodeType.Attribute);
1393
1394 if (descriptor != null) {
1395 String tmpPath = descriptor.getLocationPath();
1396 if (path.equals(StringUtils.defaultString(tmpPath))) {
1397 _stateStack.resetParentState();
1398 break;
1399 }
1400 }
1401
1402 path = targetState.getElementName() + '/' + path;
1403
1404
1405
1406
1407 descriptor = null;
1408 }
1409 }
1410 if (descriptor == null) {
1411 if (_strictAttributes) {
1412
1413 String errorMsg = MessageFormat.format(
1414 resourceBundle.getString("unmarshalHandler.error.strict.attribute.error"),
1415 new Object[] {name, state.getElementName()});
1416 throw new SAXException(errorMsg);
1417 }
1418 continue;
1419 }
1420
1421 try {
1422 processAttribute(name, namespace, atts.getValue(i), descriptor, classDesc, object);
1423 } catch (IllegalStateException ise) {
1424 String errorMsg = MessageFormat.format(
1425 resourceBundle.getString("unmarshalHandler.error.unable.add.attribute"),
1426 new Object[] {name, state.getClassDescriptor().getJavaClass().getName(), ise});
1427 throw new SAXException(errorMsg, ise);
1428 }
1429 }
1430
1431 }
1432
1433
1434
1435
1436
1437
1438
1439 void processWrapperAttributes(final AttributeSet atts) throws SAXException {
1440
1441 UnmarshalState state = _stateStack.getLastState();
1442
1443
1444
1445 for (int i = 0; i < atts.getSize(); i++) {
1446 String name = atts.getName(i);
1447 String namespace = atts.getNamespace(i);
1448
1449
1450 if (XSI_NAMESPACE.equals(namespace)) {
1451 continue;
1452 }
1453
1454 XMLFieldDescriptor descriptor = null;
1455 XMLClassDescriptor classDesc = null;
1456
1457
1458 String path = state.getElementName();
1459 UnmarshalState targetState = null;
1460 while (_stateStack.hasAnotherParentState()) {
1461 targetState = _stateStack.removeParentState();
1462 if (targetState.isWrapper()) {
1463 path = targetState.getElementName() + '/' + path;
1464 continue;
1465 }
1466 classDesc = targetState.getClassDescriptor();
1467
1468 XMLFieldDescriptor[] descriptors = classDesc.getAttributeDescriptors();
1469 boolean found = false;
1470 for (int a = 0; a < descriptors.length; a++) {
1471 descriptor = descriptors[a];
1472 if (descriptor == null) {
1473 continue;
1474 }
1475 if (descriptor.matches(name)) {
1476 String tmpPath = descriptor.getLocationPath();
1477 if (path.equals(StringUtils.defaultString(tmpPath))) {
1478 found = true;
1479 break;
1480 }
1481 }
1482 }
1483 if (found) {
1484 _stateStack.resetParentState();
1485 break;
1486 }
1487
1488 path = targetState.getElementName() + '/' + path;
1489
1490
1491
1492
1493 descriptor = null;
1494 }
1495 if (descriptor != null) {
1496 try {
1497 processAttribute(name, namespace, atts.getValue(i), descriptor, classDesc,
1498 targetState.getObject());
1499 } catch (IllegalStateException ise) {
1500 String errorMsg = MessageFormat.format(
1501 resourceBundle.getString("unmarshalHandler.error.unable.add.attribute"),
1502 new Object[] {name, state.getClassDescriptor().getJavaClass().getName(), ise});
1503 throw new SAXException(errorMsg, ise);
1504 }
1505 }
1506 }
1507
1508 }
1509
1510
1511
1512
1513 private void processAttribute(final String attName, final String attNamespace, String attValue,
1514 XMLFieldDescriptor descriptor, final XMLClassDescriptor classDesc, Object parent)
1515 throws SAXException {
1516
1517
1518 while (descriptor.isContainer()) {
1519 FieldHandler handler = descriptor.getHandler();
1520 Object containerObject = handler.getValue(parent);
1521
1522 if (containerObject == null) {
1523 containerObject = handler.newInstance(parent);
1524 handler.setValue(parent, containerObject);
1525 }
1526
1527 ClassDescriptor containerClassDesc =
1528 ((XMLFieldDescriptorImpl) descriptor).getClassDescriptor();
1529 descriptor = ((XMLClassDescriptor) containerClassDesc).getFieldDescriptor(attName,
1530 attNamespace, NodeType.Attribute);
1531 parent = containerObject;
1532 }
1533
1534 if (attValue == null) {
1535
1536
1537
1538 if (descriptor.isRequired() && isValidating()) {
1539 String errorMsg;
1540 if (_locator != null) {
1541 errorMsg = MessageFormat.format(
1542 resourceBundle.getString("unmarshalHandler.error.attribute.missing.location"),
1543 new Object[] {classDesc.getXMLName(), attName, _locator.getLineNumber(),
1544 _locator.getColumnNumber()});
1545 } else {
1546 errorMsg = MessageFormat.format(
1547 resourceBundle.getString("unmarshalHandler.error.attribute.missing"),
1548 new Object[] {classDesc.getXMLName(), attName});
1549 }
1550 throw new SAXException(errorMsg);
1551 }
1552 return;
1553 }
1554
1555
1556 if (classDesc.getIdentity() == descriptor) {
1557
1558 try {
1559 ((IDResolverImpl) _idResolver).bind(attValue, parent,
1560 isValidating() && !getInternalContext().getLenientIdValidation());
1561 } catch (ValidationException e) {
1562 String errorMsg =
1563 MessageFormat.format(resourceBundle.getString("unmarshalHandler.error.duplicated.id"),
1564 new Object[] {attValue});
1565 throw new SAXException(errorMsg, e);
1566 }
1567
1568
1569 UnmarshalState state = _stateStack.getLastState();
1570 state.setKey(attValue);
1571
1572
1573 resolveReferences(attValue, parent);
1574 } else if (descriptor.isReference()) {
1575
1576 if (descriptor.isMultivalued()) {
1577 StringTokenizer st = new StringTokenizer(attValue);
1578 while (st.hasMoreTokens()) {
1579 processIDREF(st.nextToken(), descriptor, parent);
1580 }
1581 } else {
1582 processIDREF(attValue, descriptor, parent);
1583 }
1584
1585
1586 return;
1587 }
1588
1589
1590
1591 if (descriptor.isConstructorArgument()) {
1592 return;
1593 }
1594
1595
1596 FieldHandler handler = descriptor.getHandler();
1597 if (handler == null) {
1598 return;
1599 }
1600
1601
1602 Class<?> type = descriptor.getFieldType();
1603 String valueType = descriptor.getSchemaType();
1604 boolean isPrimative = isPrimitive(type);
1605 boolean isQName = StringUtils.equals(valueType, QNAME_NAME);
1606
1607 boolean isByteArray = false;
1608 if (type.isArray()) {
1609 isByteArray = (type.getComponentType() == Byte.TYPE);
1610 }
1611
1612
1613 if (descriptor.isMultivalued()) {
1614 StringTokenizer attrValueTokenizer = new StringTokenizer(attValue);
1615 while (attrValueTokenizer.hasMoreTokens()) {
1616 attValue = attrValueTokenizer.nextToken();
1617 setAttributeValueOnObject(attValue, descriptor, parent, handler, type, isPrimative, isQName,
1618 isByteArray);
1619 }
1620 } else {
1621 setAttributeValueOnObject(attValue, descriptor, parent, handler, type, isPrimative, isQName,
1622 isByteArray);
1623 }
1624
1625 }
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642 private void setAttributeValueOnObject(final String attValue, final XMLFieldDescriptor descriptor,
1643 final Object parent, final FieldHandler handler, final Class<?> type,
1644 final boolean isPrimitive, final boolean isQName, final boolean isByteArray)
1645 throws SAXException {
1646
1647 Object value = attValue;
1648
1649 if (isPrimitive) {
1650 value = toPrimitiveObject(type, attValue, descriptor);
1651 }
1652
1653
1654 if (isByteArray) {
1655 if (attValue == null) {
1656 value = new byte[0];
1657 } else {
1658
1659 if (HexDecoder.DATA_TYPE.equals(descriptor.getComponentType())) {
1660 value = HexDecoder.decode(attValue);
1661 } else {
1662 value = Base64Decoder.decode(attValue);
1663 }
1664 }
1665 }
1666
1667
1668 if (isQName) {
1669 value = _namespaceHandling.resolveNamespace(value);
1670 }
1671
1672 handler.setValue(parent, value);
1673 }
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683 Arguments processConstructorArgs(final AttributeSet atts, final XMLClassDescriptor classDesc)
1684 throws SAXException {
1685
1686 if (classDesc == null) {
1687 return new Arguments();
1688 }
1689
1690
1691
1692
1693
1694
1695
1696
1697 int count = 0;
1698 XMLFieldDescriptor[] descriptors = classDesc.getAttributeDescriptors();
1699 for (XMLFieldDescriptor fieldDescriptor : descriptors) {
1700 if (fieldDescriptor == null) {
1701 continue;
1702 }
1703 if (fieldDescriptor.isConstructorArgument()) {
1704 ++count;
1705 }
1706 }
1707
1708 Arguments args = new Arguments();
1709
1710 if (count == 0) {
1711 return args;
1712 }
1713
1714 args.setValues(new Object[count]);
1715 args.setTypes(new Class[count]);
1716
1717 for (XMLFieldDescriptor descriptor : descriptors) {
1718
1719 if (descriptor == null) {
1720 continue;
1721 }
1722 if (!descriptor.isConstructorArgument()) {
1723 continue;
1724 }
1725
1726 int argIndex = descriptor.getConstructorArgumentIndex();
1727 if (argIndex >= count) {
1728 String errorMsg = MessageFormat.format(
1729 resourceBundle.getString("unmarshalHandler.error.index.out.of.bound"),
1730 new Object[] {argIndex});
1731 throw new SAXException(errorMsg);
1732 }
1733
1734 args.setType(argIndex, descriptor.getFieldType());
1735 String name = descriptor.getXMLName();
1736 String namespace = descriptor.getNameSpaceURI();
1737
1738 int index = atts.getIndex(name, namespace);
1739
1740 if (index >= 0) {
1741 Object value = atts.getValue(index);
1742
1743
1744 if (isPrimitive(args.getType(argIndex))) {
1745 value = toPrimitiveObject(args.getType(argIndex), (String) value, descriptor);
1746 } else {
1747
1748
1749 value = convertToEnumObject(descriptor, value);
1750 }
1751
1752
1753
1754 String valueType = descriptor.getSchemaType();
1755 if (StringUtils.equals(valueType, QNAME_NAME)) {
1756 value = _namespaceHandling.resolveNamespace(value);
1757 }
1758 args.setValue(argIndex, value);
1759 } else {
1760 if (isPrimitive(args.getType(argIndex))) {
1761 args.setValue(argIndex, toPrimitiveObject(args.getType(argIndex), null, descriptor));
1762 } else {
1763 args.setValue(argIndex, null);
1764 }
1765 }
1766 }
1767 return args;
1768 }
1769
1770
1771
1772
1773
1774
1775
1776
1777 private Object convertToEnumObject(final XMLFieldDescriptor descriptor, Object value) {
1778 Class<?> fieldType = descriptor.getFieldType();
1779 Method valueOfMethod;
1780 try {
1781 valueOfMethod = fieldType.getMethod("valueOf", new Class[] {String.class});
1782 if (valueOfMethod != null && Modifier.isStatic(valueOfMethod.getModifiers())) {
1783 Class<?> returnType = valueOfMethod.getReturnType();
1784 if (returnType.isAssignableFrom(fieldType)) {
1785 Object enumObject = valueOfMethod.invoke(null, new Object[] {value});
1786 value = enumObject;
1787 }
1788 }
1789 } catch (SecurityException e) {
1790
1791 } catch (NoSuchMethodException e) {
1792
1793 } catch (IllegalArgumentException e) {
1794
1795 } catch (IllegalAccessException e) {
1796
1797 } catch (InvocationTargetException e) {
1798
1799 }
1800 return value;
1801 }
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811 boolean processIDREF(final String idRef, final XMLFieldDescriptor descriptor,
1812 final Object parent) {
1813 Object value = _idResolver.resolve(idRef);
1814 if (value == null) {
1815
1816 addReference(idRef, parent, descriptor);
1817 } else {
1818 FieldHandler handler = descriptor.getHandler();
1819 if (handler != null) {
1820 handler.setValue(parent, value);
1821 }
1822 }
1823 return (value != null);
1824 }
1825
1826
1827
1828
1829
1830
1831
1832 private XMLClassDescriptor getClassDescriptor(String className) throws SAXException {
1833 Class<?> type = null;
1834 try {
1835
1836 if (_loader != null) {
1837 type = _loader.loadClass(className);
1838 }
1839
1840 else
1841 type = Class.forName(className);
1842 } catch (ClassNotFoundException cnfe) {
1843 return null;
1844 }
1845 return getClassDescriptor(type);
1846
1847 }
1848
1849
1850
1851
1852
1853
1854
1855 XMLClassDescriptor getClassDescriptor(final Class<?> cls) throws SAXException {
1856 if (cls == null) {
1857 return null;
1858 }
1859
1860
1861
1862 if (cls == String.class) {
1863 return STRING_DESCRIPTOR;
1864 }
1865
1866 if (cls.isArray()) {
1867 return null;
1868 }
1869 if (isPrimitive(cls)) {
1870 return null;
1871 }
1872
1873
1874
1875
1876
1877
1878 XMLClassDescriptor classDesc = null;
1879
1880 try {
1881 InternalContext ctx = getInternalContext();
1882 classDesc = (XMLClassDescriptor) ctx.getXMLClassDescriptorResolver().resolve(cls);
1883 } catch (ResolverException rx) {
1884
1885 }
1886
1887 if (classDesc != null) {
1888 return new InternalXMLClassDescriptor(classDesc);
1889 }
1890
1891 if (LOG.isDebugEnabled()) {
1892 LOG.debug(ERROR_DID_NOT_FIND_CLASSDESCRIPTOR + cls.getName());
1893 }
1894
1895 return classDesc;
1896 }
1897
1898
1899
1900
1901
1902
1903
1904
1905 XMLClassDescriptor getClassDescriptor(String className, ClassLoader loader) throws SAXException {
1906
1907
1908
1909
1910
1911
1912 XMLClassDescriptor classDesc = null;
1913 try {
1914 classDesc = getInternalContext().getXMLClassDescriptorResolver().resolve(className, loader);
1915 } catch (ResolverException rx) {
1916 throw new SAXException(rx);
1917 }
1918
1919
1920 if (classDesc != null) {
1921 return new InternalXMLClassDescriptor(classDesc);
1922 }
1923
1924 if (LOG.isDebugEnabled()) {
1925 LOG.debug(ERROR_DID_NOT_FIND_CLASSDESCRIPTOR + className);
1926 }
1927
1928 return classDesc;
1929 }
1930
1931
1932
1933
1934 XMLClassDescriptor resolveByXMLName(String name, String namespace, ClassLoader loader)
1935 throws SAXException {
1936
1937 try {
1938 return getInternalContext().getXMLClassDescriptorResolver().resolveByXMLName(name, namespace,
1939 loader);
1940 } catch (ResolverException rx) {
1941 throw new SAXException(rx);
1942 }
1943
1944 }
1945
1946
1947
1948
1949
1950
1951
1952 String getJavaPackage(Class<?> type) {
1953 if (type == null)
1954 return null;
1955 String pkg = _javaPackages.get(type);
1956 if (pkg == null) {
1957 pkg = type.getName();
1958 int idx = pkg.lastIndexOf('.');
1959 if (idx > 0)
1960 pkg = pkg.substring(0, idx);
1961 else
1962 pkg = "";
1963 _javaPackages.put(type, pkg);
1964 }
1965 return pkg;
1966 }
1967
1968
1969
1970
1971
1972
1973 String className(Class<?> type) {
1974 if (type.isArray()) {
1975 return className(type.getComponentType()) + "[]";
1976 }
1977 return type.getName();
1978 }
1979
1980
1981
1982
1983
1984
1985
1986
1987 static boolean isWhitespace(CharSequence sb) {
1988 for (int i = 0; i < sb.length(); i++) {
1989 char ch = sb.charAt(i);
1990 switch (ch) {
1991 case ' ':
1992 case '\n':
1993 case '\t':
1994 case '\r':
1995 break;
1996 default:
1997 return false;
1998 }
1999 }
2000 return true;
2001 }
2002
2003
2004
2005
2006
2007
2008
2009 Class<?> loadClass(String className, ClassLoader loader) throws ClassNotFoundException {
2010
2011 if (loader != null)
2012 return loader.loadClass(className);
2013
2014 else if (_loader != null)
2015 return _loader.loadClass(className);
2016
2017 return Class.forName(className);
2018 }
2019
2020
2021
2022
2023
2024
2025
2026
2027 private void resolveReferences(final String id, final Object value)
2028 throws org.xml.sax.SAXException {
2029 if ((id == null) || (value == null)) {
2030 return;
2031 }
2032 if (_resolveTable == null) {
2033 return;
2034 }
2035
2036 ReferenceInfo refInfo = _resolveTable.remove(id);
2037 while (refInfo != null) {
2038 try {
2039 FieldHandler handler = refInfo.getDescriptor().getHandler();
2040 if (handler != null) {
2041 handler.setValue(refInfo.getTarget(), value);
2042 }
2043
2044
2045 if (refInfo.getTarget() instanceof MapItem) {
2046 resolveReferences(refInfo.getTarget().toString(), refInfo.getTarget());
2047 }
2048 } catch (java.lang.IllegalStateException ise) {
2049 String errorMsg =
2050 MessageFormat.format(resourceBundle.getString("unmarshalHandler.error.resolving.idRef"),
2051 new Object[] {id, ise.toString()});
2052 throw new SAXException(errorMsg, ise);
2053 }
2054 refInfo = refInfo.getNext();
2055 }
2056 }
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067 Object toPrimitiveObject(final Class<?> type, final String value,
2068 final XMLFieldDescriptor fieldDesc) throws SAXException {
2069 try {
2070 return toPrimitiveObject(type, value);
2071 } catch (Exception ex) {
2072 UnmarshalState state = _stateStack.getLastState();
2073 if (state != null) {
2074 if (state.getObject() != null) {
2075 String errorMsg = MessageFormat.format(
2076 resourceBundle.getString("unmarshalHandler.error.unmarshal.field.of.class"),
2077 new Object[] {fieldDesc.getFieldName(), state.getObject().getClass().getName()});
2078 throw new SAXException(errorMsg, ex);
2079 }
2080 }
2081 String errorMsg =
2082 MessageFormat.format(resourceBundle.getString("unmarshalHandler.error.unmarshal.field"),
2083 new Object[] {fieldDesc.getFieldName()});
2084 throw new SAXException(errorMsg, ex);
2085 }
2086 }
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096 public static Object toPrimitiveObject(final Class<?> type, String value) {
2097 return PrimitiveObjectFactory.getInstance().getObject(type, value);
2098 }
2099
2100
2101
2102
2103 class Arguments {
2104
2105
2106
2107 private Object[] _values = null;
2108
2109
2110
2111 private Class<?>[] _types = null;
2112
2113
2114
2115
2116
2117
2118 public int size() {
2119 if (_values == null) {
2120 return 0;
2121 }
2122 return _values.length;
2123 }
2124
2125 public Class<?>[] getTypes() {
2126 return _types;
2127 }
2128
2129 public Object[] getValues() {
2130 return _values;
2131 }
2132
2133 public Class<?> getType(int index) {
2134 return _types[index];
2135 }
2136
2137 public void setValues(Object[] values) {
2138 _values = values;
2139 }
2140
2141 public void setValue(int index, Object value) {
2142 _values[index] = value;
2143 }
2144
2145 public void setTypes(Class<?>[] types) {
2146 _types = types;
2147 }
2148
2149 public void setType(int index, Class<?> type) {
2150 _types[index] = type;
2151 }
2152
2153 }
2154
2155
2156
2157
2158
2159
2160 public static class ArrayHandler {
2161
2162 Class<?> _componentType = null;
2163
2164 ArrayList<Object> _items = null;
2165
2166
2167
2168
2169
2170
2171 ArrayHandler(final Class<?> componentType) {
2172 if (componentType == null) {
2173 String errMsg = resourceBundle.getString("unmarshalHandler.error.componentType.null");
2174 throw new IllegalArgumentException(errMsg);
2175 }
2176 _componentType = componentType;
2177 _items = new ArrayList<Object>();
2178 }
2179
2180
2181
2182
2183
2184
2185 public void addObject(final Object obj) {
2186 if (obj == null) {
2187 return;
2188 }
2189
2190
2191
2192
2193
2194
2195 _items.add(obj);
2196 }
2197
2198
2199
2200
2201
2202
2203 public Object getObject() {
2204 int size = _items.size();
2205 Object array = Array.newInstance(_componentType, size);
2206 for (int i = 0; i < size; i++) {
2207 Array.set(array, i, _items.get(i));
2208 }
2209 return array;
2210 }
2211
2212
2213
2214
2215
2216
2217 public Class<?> componentType() {
2218 return _componentType;
2219 }
2220
2221 }
2222
2223
2224
2225
2226
2227
2228 public ObjectFactory getObjectFactory() {
2229 return _objectFactory;
2230 }
2231
2232
2233
2234
2235
2236
2237 public void setObjectFactory(ObjectFactory objectFactory) {
2238 _objectFactory = objectFactory;
2239 }
2240
2241
2242
2243
2244
2245
2246 public UnmarshalStateStack getStateStack() {
2247 return _stateStack;
2248 }
2249
2250
2251
2252
2253
2254
2255 public UnmarshalState getTopState() {
2256 return _topState;
2257 }
2258
2259
2260
2261
2262
2263
2264 public StrictElementHandler getStrictElementHandler() {
2265 return _strictElementHandler;
2266 }
2267
2268
2269
2270
2271
2272
2273 public NamespaceHandling getNamespaceHandling() {
2274 return _namespaceHandling;
2275 }
2276
2277
2278
2279
2280
2281
2282 public ClassLoader getClassLoader() {
2283 return _loader;
2284 }
2285
2286
2287
2288
2289
2290
2291 public AnyNodeUnmarshalHandler getAnyNodeHandler() {
2292 return _anyNodeHandler;
2293 }
2294
2295
2296
2297
2298
2299
2300 public UnmarshalListenerDelegate getDelegateUnmarshalListener() {
2301 return _delegateUnmarshalListener;
2302 }
2303
2304
2305
2306
2307
2308
2309 public boolean isReuseObjects() {
2310 return _reuseObjects;
2311 }
2312
2313
2314
2315
2316
2317
2318 public Hashtable<String, ReferenceInfo> getResolveTable() {
2319 return _resolveTable;
2320 }
2321
2322
2323
2324
2325
2326
2327 public org.exolab.castor.types.AnyNode getAnyNode() {
2328 return _node;
2329 }
2330
2331
2332
2333
2334
2335
2336 public void setAnyNode(org.exolab.castor.types.AnyNode node) {
2337 _node = node;
2338 }
2339
2340
2341
2342
2343
2344
2345 public boolean isClearCollections() {
2346 return _clearCollections;
2347 }
2348
2349
2350
2351 }
2352