KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mvnforum > jaxb > db > impl > runtime > SAXUnmarshallerHandlerImpl


1 //
2
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v1.0.5-b16-fcs
3
// See <a HREF="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
4
// Any modifications to this file will be lost upon recompilation of the source schema.
5
// Generated on: 2005.12.17 at 09:43:27 AM GMT+07:00
6
//
7

8 package com.mvnforum.jaxb.db.impl.runtime;
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.Collections JavaDoc;
12 import java.util.Hashtable JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.List JavaDoc;
15
16 import javax.xml.XMLConstants JavaDoc;
17 import javax.xml.bind.JAXBException;
18 import javax.xml.bind.UnmarshalException;
19 import javax.xml.bind.ValidationEvent;
20 import javax.xml.bind.ValidationEventHandler;
21
22 import org.xml.sax.Attributes JavaDoc;
23 import org.xml.sax.Locator JavaDoc;
24 import org.xml.sax.SAXException JavaDoc;
25 import org.xml.sax.SAXParseException JavaDoc;
26 import org.xml.sax.helpers.LocatorImpl JavaDoc;
27
28 import com.sun.xml.bind.JAXBAssertionError;
29 import com.sun.xml.bind.unmarshaller.Messages;
30 import com.sun.xml.bind.unmarshaller.Tracer;
31 import com.sun.xml.bind.util.AttributesImpl;
32
33 /**
34  * Implementation of {@link UnmarshallerHandler}.
35  *
36  * This object converts SAX events into unmarshaller events and
37  * cooridnates the entire unmarshalling process.
38  *
39  * @author
40  * <a HREF="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
41  */

42 public class SAXUnmarshallerHandlerImpl
43     implements SAXUnmarshallerHandler, UnmarshallingContext
44 {
45     /**
46      * This flag is set to true at the startDocument event
47      * and false at the endDocument event.
48      *
49      * Until the first document is unmarshalled, we don't
50      * want to return an object. So this variable is initialized
51      * to true.
52      */

53     private boolean isUnmarshalInProgress = true;
54     
55     
56     
57     public SAXUnmarshallerHandlerImpl( UnmarshallerImpl _parent, GrammarInfo _gi ) {
58         this.parent = _parent;
59         grammarInfo = _gi;
60         startPrefixMapping("",""); // by default, the default ns is bound to "".
61
}
62     
63     private final GrammarInfo grammarInfo;
64     public GrammarInfo getGrammarInfo() { return grammarInfo; }
65     
66     /**
67      * Returns true if we should be collecting characters in the current element.
68      */

69     private final boolean shouldCollectText() {
70         return collectText[stackTop];
71     }
72     
73     public void startDocument() throws SAXException JavaDoc {
74         // reset the object
75
result = null;
76         handlerLen=0;
77         patchers=null;
78         patchersLen=0;
79         aborted = false;
80         isUnmarshalInProgress = true;
81         
82         stackTop=0;
83         elementDepth=1;
84     }
85     
86     public void endDocument() throws SAXException JavaDoc {
87         runPatchers();
88         isUnmarshalInProgress = false;
89     }
90     
91     public void startElement( String JavaDoc uri, String JavaDoc local, String JavaDoc qname, Attributes JavaDoc atts )
92             throws SAXException JavaDoc {
93         
94         // work gracefully with misconfigured parsers that don't support namespaces
95
if( uri==null )
96             uri="";
97         if( local==null || local.length()==0 )
98             local=qname;
99         if( qname==null || qname.length()==0 )
100             qname=local;
101         
102         if(result==null) {
103             // this is the root element.
104
// create a root object and start unmarshalling
105
UnmarshallingEventHandler unmarshaller =
106                 grammarInfo.createUnmarshaller(uri,local,this);
107             if(unmarshaller==null) {
108                 // the registry doesn't know about this element.
109
//
110
// the no.1 cause of this problem is that your application is configuring
111
// an XML parser by your self and you forgot to call
112
// the SAXParserFactory.setNamespaceAware(true). When this happens, you see
113
// the namespace URI is reported as empty whereas you expect something else.
114
throw new SAXParseException JavaDoc(
115                     Messages.format( Messages.UNEXPECTED_ROOT_ELEMENT2,
116                         uri, local, computeExpectedRootElements() ),
117                     getLocator() );
118             }
119             result = unmarshaller.owner();
120
121             pushContentHandler(unmarshaller,0);
122         }
123     
124         processText(true);
125     
126         getCurrentHandler().enterElement(uri,local,qname,atts);
127     }
128
129     public final void endElement( String JavaDoc uri, String JavaDoc local, String JavaDoc qname )
130             throws SAXException JavaDoc {
131         
132         // work gracefully with misconfigured parsers that don't support namespaces
133
if( uri==null )
134             uri="";
135         if( local==null || local.length()==0 )
136             local=qname;
137         if( qname==null || qname.length()==0 )
138             qname=local;
139         
140         processText(false);
141         getCurrentHandler().leaveElement(uri,local,qname);
142     }
143     
144     
145     
146     
147     
148     /** Root object that is being unmarshalled. */
149     private Object JavaDoc result;
150     public Object JavaDoc getResult() throws UnmarshalException {
151         if(isUnmarshalInProgress)
152             throw new IllegalStateException JavaDoc();
153         
154         if(!aborted) return result;
155         
156         // there was an error.
157
throw new UnmarshalException((String JavaDoc)null);
158     }
159
160     
161     
162 //
163
//
164
// handler stack maintainance
165
//
166
//
167
private UnmarshallingEventHandler[] handlers = new UnmarshallingEventHandler[16];
168     private int[] mementos = new int[16];
169     private int handlerLen=0;
170     
171     public void pushContentHandler( UnmarshallingEventHandler handler, int memento ) {
172         if(handlerLen==handlers.length) {
173             // expand buffer
174
UnmarshallingEventHandler[] h = new UnmarshallingEventHandler[handlerLen*2];
175             int[] m = new int[handlerLen*2];
176             System.arraycopy(handlers,0,h,0,handlerLen);
177             System.arraycopy(mementos,0,m,0,handlerLen);
178             handlers = h;
179             mementos = m;
180         }
181         handlers[handlerLen] = handler;
182         mementos[handlerLen] = memento;
183         handlerLen++;
184     }
185     
186     public void popContentHandler() throws SAXException JavaDoc {
187         handlerLen--;
188         handlers[handlerLen]=null; // this handler is removed
189
getCurrentHandler().leaveChild(mementos[handlerLen]);
190     }
191
192     public UnmarshallingEventHandler getCurrentHandler() {
193         return handlers[handlerLen-1];
194     }
195
196
197 //
198
//
199
// text handling
200
//
201
//
202
private StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
203     
204     protected void consumeText( String JavaDoc str, boolean ignorable ) throws SAXException JavaDoc {
205          if(ignorable && str.trim().length()==0)
206             // if we are allowed to ignore text and
207
// the text is ignorable, ignore.
208
return;
209         
210         // otherwise perform a transition by this token.
211
getCurrentHandler().text(str);
212     }
213     private void processText( boolean ignorable ) throws SAXException JavaDoc {
214         if( shouldCollectText() )
215             consumeText(buffer.toString(),ignorable);
216         
217         // avoid excessive object allocation, but also avoid
218
// keeping a huge array inside StringBuffer.
219
if(buffer.length()<1024) buffer.setLength(0);
220         else buffer = new StringBuffer JavaDoc();
221     }
222     
223     public final void characters( char[] buf, int start, int len ) {
224         if( shouldCollectText() )
225             buffer.append(buf,start,len);
226     }
227
228     public final void ignorableWhitespace( char[] buf, int start, int len ) {
229         characters(buf,start,len);
230     }
231
232
233
234     
235 //
236
//
237
// namespace binding maintainance
238
//
239
//
240
private String JavaDoc[] nsBind = new String JavaDoc[16];
241     private int nsLen=0;
242     
243     // in the current scope, nsBind[0] - nsBind[idxStack[idxStackTop]-1]
244
// are active.
245
// use {@link #elementDepth} and {@link stackTop} to access.
246
private int[] idxStack = new int[16];
247     
248     public void startPrefixMapping( String JavaDoc prefix, String JavaDoc uri ) {
249         if(nsBind.length==nsLen) {
250             // expand the buffer
251
String JavaDoc[] n = new String JavaDoc[nsLen*2];
252             System.arraycopy(nsBind,0,n,0,nsLen);
253             nsBind=n;
254         }
255         nsBind[nsLen++] = prefix;
256         nsBind[nsLen++] = uri;
257     }
258     public void endPrefixMapping( String JavaDoc prefix ) {
259         nsLen-=2;
260     }
261     public String JavaDoc resolveNamespacePrefix( String JavaDoc prefix ) {
262         if(prefix.equals("xml"))
263             return "http://www.w3.org/XML/1998/namespace";
264         
265         for( int i=idxStack[stackTop]-2; i>=0; i-=2 ) {
266             if(prefix.equals(nsBind[i]))
267                 return nsBind[i+1];
268         }
269         return null;
270     }
271     public String JavaDoc[] getNewlyDeclaredPrefixes() {
272         return getPrefixList( idxStack[stackTop-1] );
273     }
274
275     public String JavaDoc[] getAllDeclaredPrefixes() {
276         return getPrefixList( 2 ); // skip the default ""->"" mapping
277
}
278     
279     private String JavaDoc[] getPrefixList( int startIndex ) {
280         int size = (idxStack[stackTop]-startIndex)/2;
281         String JavaDoc[] r = new String JavaDoc[size];
282         for( int i=0; i<r.length; i++ )
283             r[i] = nsBind[startIndex+i*2];
284         return r;
285     }
286
287     
288     //
289
// NamespaceContext2 implementation
290
//
291
public Iterator JavaDoc getPrefixes(String JavaDoc uri) {
292         // wrap it into unmodifiable list so that the remove method
293
// will throw UnsupportedOperationException.
294
return Collections.unmodifiableList(
295             getAllPrefixesInList(uri)).iterator();
296     }
297     
298     private List JavaDoc getAllPrefixesInList(String JavaDoc uri) {
299         List JavaDoc a = new ArrayList JavaDoc();
300         
301         if( uri.equals(XMLConstants.XML_NS_URI) ) {
302             a.add(XMLConstants.XML_NS_PREFIX);
303             return a;
304         }
305         if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) ) {
306             a.add(XMLConstants.XMLNS_ATTRIBUTE);
307             return a;
308         }
309         if( uri==null )
310             throw new IllegalArgumentException JavaDoc();
311           
312         for( int i=nsLen-2; i>=0; i-=2 )
313             if(uri.equals(nsBind[i+1]))
314                 if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) )
315                     // make sure that this prefix is still effective.
316
a.add(nsBind[i]);
317          
318         return a;
319     }
320
321     public String JavaDoc getPrefix(String JavaDoc uri) {
322         if( uri.equals(XMLConstants.XML_NS_URI) )
323             return XMLConstants.XML_NS_PREFIX;
324         if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) )
325             return XMLConstants.XMLNS_ATTRIBUTE;
326         if( uri==null )
327             throw new IllegalArgumentException JavaDoc();
328           
329         for( int i=idxStack[stackTop]-2; i>=0; i-=2 )
330             if(uri.equals(nsBind[i+1]))
331                 if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) )
332                     // make sure that this prefix is still effective.
333
return nsBind[i];
334          
335         return null;
336     }
337
338      public String JavaDoc getNamespaceURI(String JavaDoc prefix) {
339          if( prefix==null )
340              throw new IllegalArgumentException JavaDoc();
341          if( prefix.equals(XMLConstants.XMLNS_ATTRIBUTE) )
342              return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
343         
344          return resolveNamespacePrefix(prefix);
345      }
346
347 //
348
//
349
// Attribute handling
350
//
351
//
352
/**
353      * Attributes stack.
354      */

355     private AttributesImpl[] attStack = new AttributesImpl[16];
356     /**
357      * Element nesting level.
358      */

359     private int elementDepth;
360     /**
361      * Always {@link #elementDepth}-1.
362      */

363     private int stackTop;
364     
365     /**
366      * Stack of collectText flag.
367      * False means text can be ignored for this element.
368      *
369      * Use {@link #elementDepth} and {@link #stackTop} to access the array.
370      */

371     private boolean[] collectText = new boolean[16];
372     
373     public void pushAttributes( Attributes JavaDoc atts, boolean collectTextFlag ) {
374         
375         if( attStack.length==elementDepth ) {
376             // reallocate the buffer
377
AttributesImpl[] buf1 = new AttributesImpl[attStack.length*2];
378             System.arraycopy(attStack,0,buf1,0,attStack.length);
379             attStack = buf1;
380             
381             int[] buf2 = new int[idxStack.length*2];
382             System.arraycopy(idxStack,0,buf2,0,idxStack.length);
383             idxStack = buf2;
384             
385             boolean[] buf3 = new boolean[collectText.length*2];
386             System.arraycopy(collectText,0,buf3,0,collectText.length);
387             collectText = buf3;
388         }
389         
390         elementDepth++;
391         stackTop++;
392         
393         // push the stack
394
AttributesImpl a = attStack[stackTop];
395         if( a==null )
396             attStack[stackTop] = a = new AttributesImpl();
397         else
398             a.clear();
399         
400         // since Attributes object is mutable, it is criticall important
401
// to make a copy.
402
// also symbolize attribute names
403
for( int i=0; i<atts.getLength(); i++ ) {
404             String JavaDoc auri = atts.getURI(i);
405             String JavaDoc alocal = atts.getLocalName(i);
406             String JavaDoc avalue = atts.getValue(i);
407             String JavaDoc aqname = atts.getQName(i);
408             
409             // work gracefully with misconfigured parsers that don't support namespaces
410
if( auri==null )
411                 auri="";
412             if( alocal==null || alocal.length()==0 )
413                 alocal=aqname;
414             if( aqname==null || aqname.length()==0 )
415                 aqname=alocal;
416
417             // <foo xsi:nil="false">some value</foo> is a valid fragment, however
418
// we need a look ahead to correctly handle this case.
419
// (because when we process @xsi:nil, we don't know what the value is,
420
// and by the time we read "false", we can't cancel this attribute anymore.)
421
//
422
// as a quick workaround, we remove @xsi:nil if the value is false.
423
if( auri=="http://www.w3.org/2001/XMLSchema-instance" && alocal=="nil" ) {
424                 String JavaDoc v = avalue.trim();
425                 if(v.equals("false") || v.equals("0"))
426                     continue; // skip this attribute
427
}
428             
429             // otherwise just add it.
430
a.addAttribute(
431                     auri,
432                     alocal,
433                     aqname,
434                     atts.getType(i),
435                     avalue );
436         }
437         
438         
439         // start a new namespace scope
440
idxStack[stackTop] = nsLen;
441         
442         collectText[stackTop] = collectTextFlag;
443     }
444     public void popAttributes() {
445         stackTop--;
446         elementDepth--;
447     }
448     public Attributes JavaDoc getUnconsumedAttributes() {
449         return attStack[stackTop];
450     }
451     /**
452      * @param uri,local
453      * has to be interned.
454      */

455     public int getAttribute( String JavaDoc uri, String JavaDoc local ) {
456         return attStack[stackTop].getIndexFast(uri,local);
457     }
458     public void consumeAttribute( int idx ) throws SAXException JavaDoc {
459         AttributesImpl a = attStack[stackTop];
460         
461         String JavaDoc uri = a.getURI(idx);
462         String JavaDoc local = a.getLocalName(idx);
463         String JavaDoc qname = a.getQName(idx);
464         String JavaDoc value = a.getValue(idx);
465
466         // mark the attribute as consumed
467
// we need to remove the attribute before we process it
468
// because the event handler might access attributes.
469
a.removeAttribute(idx);
470         
471         
472         getCurrentHandler().enterAttribute(uri,local,qname);
473         consumeText(value,false);
474         getCurrentHandler().leaveAttribute(uri,local,qname);
475     }
476     public String JavaDoc eatAttribute( int idx ) throws SAXException JavaDoc {
477         AttributesImpl a = attStack[stackTop];
478         
479         String JavaDoc value = a.getValue(idx);
480
481         // mark the attribute as consumed
482
a.removeAttribute(idx);
483         
484         return value;
485     }
486
487 //
488
//
489
// ID/IDREF related code
490
//
491
//
492
/**
493      * Submitted patchers in the order they've submitted.
494      * Many XML vocabulary doesn't use ID/IDREF at all, so we
495      * initialize it with null.
496      */

497     private Runnable JavaDoc[] patchers = null;
498     private int patchersLen = 0;
499     
500     public void addPatcher( Runnable JavaDoc job ) {
501         // re-allocate buffer if necessary
502
if( patchers==null )
503             patchers = new Runnable JavaDoc[32];
504         if( patchers.length == patchersLen ) {
505             Runnable JavaDoc[] buf = new Runnable JavaDoc[patchersLen*2];
506             System.arraycopy(patchers,0,buf,0,patchersLen);
507             patchers = buf;
508         }
509         patchers[patchersLen++] = job;
510     }
511     
512     /** Executes all the patchers. */
513     private void runPatchers() {
514         if( patchers!=null ) {
515             for( int i=0; i<patchersLen; i++ )
516                 patchers[i].run();
517         }
518     }
519
520     /** Records ID->Object map. */
521     private Hashtable JavaDoc idmap = null;
522
523     public String JavaDoc addToIdTable( String JavaDoc id ) {
524         if(idmap==null) idmap = new Hashtable JavaDoc();
525         idmap.put( id, getCurrentHandler().owner() );
526         return id;
527     }
528     
529     public Object JavaDoc getObjectFromId( String JavaDoc id ) {
530         if(idmap==null) return null;
531         return idmap.get(id);
532     }
533     
534
535
536 //
537
//
538
// Other SAX callbacks
539
//
540
//
541
public void skippedEntity( String JavaDoc name ) {
542     }
543     public void processingInstruction( String JavaDoc target, String JavaDoc data ) {
544         // just ignore
545
}
546     public void setDocumentLocator( Locator JavaDoc loc ) {
547         locator = loc;
548     }
549     public Locator JavaDoc getLocator() { return locator; }
550     
551     private Locator JavaDoc locator = DUMMY_LOCATOR;
552
553     private static final Locator JavaDoc DUMMY_LOCATOR = new LocatorImpl JavaDoc();
554
555
556 //
557
//
558
// error handling
559
//
560
//
561
private final UnmarshallerImpl parent;
562     private boolean aborted = false;
563     
564     public void handleEvent(ValidationEvent event, boolean canRecover ) throws SAXException JavaDoc {
565         ValidationEventHandler eventHandler;
566         try {
567             eventHandler = parent.getEventHandler();
568         } catch( JAXBException e ) {
569             // impossible.
570
throw new JAXBAssertionError();
571         }
572
573         boolean recover = eventHandler.handleEvent(event);
574         
575         // if the handler says "abort", we will not return the object
576
// from the unmarshaller.getResult()
577
if(!recover) aborted = true;
578         
579         if( !canRecover || !recover )
580             throw new SAXException JavaDoc( new UnmarshalException(
581                 event.getMessage(),
582                 event.getLinkedException() ) );
583     }
584   
585 //
586
//
587
// ValidationContext implementation
588
//
589
//
590
public String JavaDoc getBaseUri() { return null; }
591     public boolean isUnparsedEntity(String JavaDoc s) { return true; }
592     public boolean isNotation(String JavaDoc s) { return true; }
593
594
595 //
596
//
597
// debug trace methods
598
//
599
//
600
private Tracer tracer;
601     public void setTracer( Tracer t ) {
602         this.tracer = t;
603     }
604     public Tracer getTracer() {
605         if(tracer==null)
606             tracer = new Tracer.Standard();
607         return tracer;
608     }
609     
610     /**
611      * Computes the names of possible root elements for a better error diagnosis.
612      */

613     private String JavaDoc computeExpectedRootElements() {
614         String JavaDoc r = "";
615         
616         String JavaDoc[] probePoints = grammarInfo.getProbePoints();
617         for( int i=0; i<probePoints.length; i+=2 ) {
618             if( grammarInfo.recognize(probePoints[i],probePoints[i+1]) ) {
619                 if(r.length()!=0) r+=',';
620                 r += "<{"+probePoints[i]+"}"+probePoints[i+1]+">";
621             }
622         }
623         
624         return r;
625     }
626 }
627
Popular Tags