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