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