1 package com.sun.tools.xjc.runtime; 2 3 import java.util.ArrayList ; 4 import java.util.Collections ; 5 import java.util.Hashtable ; 6 import java.util.Iterator ; 7 import java.util.List ; 8 9 import javax.xml.XMLConstants ; 10 import javax.xml.bind.JAXBException; 11 import javax.xml.bind.UnmarshalException; 12 import javax.xml.bind.ValidationEvent; 13 import javax.xml.bind.ValidationEventHandler; 14 15 import org.xml.sax.Attributes ; 16 import org.xml.sax.Locator ; 17 import org.xml.sax.SAXException ; 18 import org.xml.sax.SAXParseException ; 19 import org.xml.sax.helpers.LocatorImpl ; 20 21 import com.sun.xml.bind.JAXBAssertionError; 22 import com.sun.xml.bind.unmarshaller.Messages; 23 import com.sun.xml.bind.unmarshaller.Tracer; 24 import com.sun.xml.bind.util.AttributesImpl; 25 26 35 public class SAXUnmarshallerHandlerImpl 36 implements SAXUnmarshallerHandler, UnmarshallingContext 37 { 38 46 private boolean isUnmarshalInProgress = true; 47 48 49 50 public SAXUnmarshallerHandlerImpl( UnmarshallerImpl _parent, GrammarInfo _gi ) { 51 this.parent = _parent; 52 grammarInfo = _gi; 53 startPrefixMapping("",""); } 55 56 private final GrammarInfo grammarInfo; 57 public GrammarInfo getGrammarInfo() { return grammarInfo; } 58 59 62 private final boolean shouldCollectText() { 63 return collectText[stackTop]; 64 } 65 66 public void startDocument() throws SAXException { 67 result = null; 69 handlerLen=0; 70 patchers=null; 71 patchersLen=0; 72 aborted = false; 73 isUnmarshalInProgress = true; 74 75 stackTop=0; 76 elementDepth=1; 77 } 78 79 public void endDocument() throws SAXException { 80 runPatchers(); 81 isUnmarshalInProgress = false; 82 } 83 84 public void startElement( String uri, String local, String qname, Attributes atts ) 85 throws SAXException { 86 87 if( uri==null ) 89 uri=""; 90 if( local==null || local.length()==0 ) 91 local=qname; 92 if( qname==null || qname.length()==0 ) 93 qname=local; 94 95 if(result==null) { 96 UnmarshallingEventHandler unmarshaller = 99 grammarInfo.createUnmarshaller(uri,local,this); 100 if(unmarshaller==null) { 101 throw new SAXParseException ( 108 Messages.format( Messages.UNEXPECTED_ROOT_ELEMENT2, 109 uri, local, computeExpectedRootElements() ), 110 getLocator() ); 111 } 112 result = unmarshaller.owner(); 113 114 pushContentHandler(unmarshaller,0); 115 } 116 117 processText(true); 118 119 getCurrentHandler().enterElement(uri,local,qname,atts); 120 } 121 122 public final void endElement( String uri, String local, String qname ) 123 throws SAXException { 124 125 if( uri==null ) 127 uri=""; 128 if( local==null || local.length()==0 ) 129 local=qname; 130 if( qname==null || qname.length()==0 ) 131 qname=local; 132 133 processText(false); 134 getCurrentHandler().leaveElement(uri,local,qname); 135 } 136 137 138 139 140 141 142 private Object result; 143 public Object getResult() throws UnmarshalException { 144 if(isUnmarshalInProgress) 145 throw new IllegalStateException (); 146 147 if(!aborted) return result; 148 149 throw new UnmarshalException((String )null); 151 } 152 153 154 155 private UnmarshallingEventHandler[] handlers = new UnmarshallingEventHandler[16]; 161 private int[] mementos = new int[16]; 162 private int handlerLen=0; 163 164 public void pushContentHandler( UnmarshallingEventHandler handler, int memento ) { 165 if(handlerLen==handlers.length) { 166 UnmarshallingEventHandler[] h = new UnmarshallingEventHandler[handlerLen*2]; 168 int[] m = new int[handlerLen*2]; 169 System.arraycopy(handlers,0,h,0,handlerLen); 170 System.arraycopy(mementos,0,m,0,handlerLen); 171 handlers = h; 172 mementos = m; 173 } 174 handlers[handlerLen] = handler; 175 mementos[handlerLen] = memento; 176 handlerLen++; 177 } 178 179 public void popContentHandler() throws SAXException { 180 handlerLen--; 181 handlers[handlerLen]=null; getCurrentHandler().leaveChild(mementos[handlerLen]); 183 } 184 185 public UnmarshallingEventHandler getCurrentHandler() { 186 return handlers[handlerLen-1]; 187 } 188 189 190 private StringBuffer buffer = new StringBuffer (); 196 197 protected void consumeText( String str, boolean ignorable ) throws SAXException { 198 if(ignorable && str.trim().length()==0) 199 return; 202 203 getCurrentHandler().text(str); 205 } 206 private void processText( boolean ignorable ) throws SAXException { 207 if( shouldCollectText() ) 208 consumeText(buffer.toString(),ignorable); 209 210 if(buffer.length()<1024) buffer.setLength(0); 213 else buffer = new StringBuffer (); 214 } 215 216 public final void characters( char[] buf, int start, int len ) { 217 if( shouldCollectText() ) 218 buffer.append(buf,start,len); 219 } 220 221 public final void ignorableWhitespace( char[] buf, int start, int len ) { 222 characters(buf,start,len); 223 } 224 225 226 227 228 private String [] nsBind = new String [16]; 234 private int nsLen=0; 235 236 private int[] idxStack = new int[16]; 240 241 public void startPrefixMapping( String prefix, String uri ) { 242 if(nsBind.length==nsLen) { 243 String [] n = new String [nsLen*2]; 245 System.arraycopy(nsBind,0,n,0,nsLen); 246 nsBind=n; 247 } 248 nsBind[nsLen++] = prefix; 249 nsBind[nsLen++] = uri; 250 } 251 public void endPrefixMapping( String prefix ) { 252 nsLen-=2; 253 } 254 public String resolveNamespacePrefix( String prefix ) { 255 if(prefix.equals("xml")) 256 return "http://www.w3.org/XML/1998/namespace"; 257 258 for( int i=idxStack[stackTop]-2; i>=0; i-=2 ) { 259 if(prefix.equals(nsBind[i])) 260 return nsBind[i+1]; 261 } 262 return null; 263 } 264 public String [] getNewlyDeclaredPrefixes() { 265 return getPrefixList( idxStack[stackTop-1] ); 266 } 267 268 public String [] getAllDeclaredPrefixes() { 269 return getPrefixList( 2 ); } 271 272 private String [] getPrefixList( int startIndex ) { 273 int size = (idxStack[stackTop]-startIndex)/2; 274 String [] r = new String [size]; 275 for( int i=0; i<r.length; i++ ) 276 r[i] = nsBind[startIndex+i*2]; 277 return r; 278 } 279 280 281 public Iterator getPrefixes(String uri) { 285 return Collections.unmodifiableList( 288 getAllPrefixesInList(uri)).iterator(); 289 } 290 291 private List getAllPrefixesInList(String uri) { 292 List a = new ArrayList (); 293 294 if( uri.equals(XMLConstants.XML_NS_URI) ) { 295 a.add(XMLConstants.XML_NS_PREFIX); 296 return a; 297 } 298 if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) ) { 299 a.add(XMLConstants.XMLNS_ATTRIBUTE); 300 return a; 301 } 302 if( uri==null ) 303 throw new IllegalArgumentException (); 304 305 for( int i=nsLen-2; i>=0; i-=2 ) 306 if(uri.equals(nsBind[i+1])) 307 if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) ) 308 a.add(nsBind[i]); 310 311 return a; 312 } 313 314 public String getPrefix(String uri) { 315 if( uri.equals(XMLConstants.XML_NS_URI) ) 316 return XMLConstants.XML_NS_PREFIX; 317 if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) ) 318 return XMLConstants.XMLNS_ATTRIBUTE; 319 if( uri==null ) 320 throw new IllegalArgumentException (); 321 322 for( int i=idxStack[stackTop]-2; i>=0; i-=2 ) 323 if(uri.equals(nsBind[i+1])) 324 if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) ) 325 return nsBind[i]; 327 328 return null; 329 } 330 331 public String getNamespaceURI(String prefix) { 332 if( prefix==null ) 333 throw new IllegalArgumentException (); 334 if( prefix.equals(XMLConstants.XMLNS_ATTRIBUTE) ) 335 return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; 336 337 return resolveNamespacePrefix(prefix); 338 } 339 340 348 private AttributesImpl[] attStack = new AttributesImpl[16]; 349 352 private int elementDepth; 353 356 private int stackTop; 357 358 364 private boolean[] collectText = new boolean[16]; 365 366 public void pushAttributes( Attributes atts, boolean collectTextFlag ) { 367 368 if( attStack.length==elementDepth ) { 369 AttributesImpl[] buf1 = new AttributesImpl[attStack.length*2]; 371 System.arraycopy(attStack,0,buf1,0,attStack.length); 372 attStack = buf1; 373 374 int[] buf2 = new int[idxStack.length*2]; 375 System.arraycopy(idxStack,0,buf2,0,idxStack.length); 376 idxStack = buf2; 377 378 boolean[] buf3 = new boolean[collectText.length*2]; 379 System.arraycopy(collectText,0,buf3,0,collectText.length); 380 collectText = buf3; 381 } 382 383 elementDepth++; 384 stackTop++; 385 386 AttributesImpl a = attStack[stackTop]; 388 if( a==null ) 389 attStack[stackTop] = a = new AttributesImpl(); 390 else 391 a.clear(); 392 393 for( int i=0; i<atts.getLength(); i++ ) { 397 String auri = atts.getURI(i); 398 String alocal = atts.getLocalName(i); 399 String avalue = atts.getValue(i); 400 String aqname = atts.getQName(i); 401 402 if( auri==null ) 404 auri=""; 405 if( alocal==null || alocal.length()==0 ) 406 alocal=aqname; 407 if( aqname==null || aqname.length()==0 ) 408 aqname=alocal; 409 410 if( auri=="http://www.w3.org/2001/XMLSchema-instance" && alocal=="nil" ) { 417 String v = avalue.trim(); 418 if(v.equals("false") || v.equals("0")) 419 continue; } 421 422 a.addAttribute( 424 auri, 425 alocal, 426 aqname, 427 atts.getType(i), 428 avalue ); 429 } 430 431 432 idxStack[stackTop] = nsLen; 434 435 collectText[stackTop] = collectTextFlag; 436 } 437 public void popAttributes() { 438 stackTop--; 439 elementDepth--; 440 } 441 public Attributes getUnconsumedAttributes() { 442 return attStack[stackTop]; 443 } 444 448 public int getAttribute( String uri, String local ) { 449 return attStack[stackTop].getIndexFast(uri,local); 450 } 451 public void consumeAttribute( int idx ) throws SAXException { 452 AttributesImpl a = attStack[stackTop]; 453 454 String uri = a.getURI(idx); 455 String local = a.getLocalName(idx); 456 String qname = a.getQName(idx); 457 String value = a.getValue(idx); 458 459 a.removeAttribute(idx); 463 464 465 getCurrentHandler().enterAttribute(uri,local,qname); 466 consumeText(value,false); 467 getCurrentHandler().leaveAttribute(uri,local,qname); 468 } 469 public String eatAttribute( int idx ) throws SAXException { 470 AttributesImpl a = attStack[stackTop]; 471 472 String value = a.getValue(idx); 473 474 a.removeAttribute(idx); 476 477 return value; 478 } 479 480 490 private Runnable [] patchers = null; 491 private int patchersLen = 0; 492 493 public void addPatcher( Runnable job ) { 494 if( patchers==null ) 496 patchers = new Runnable [32]; 497 if( patchers.length == patchersLen ) { 498 Runnable [] buf = new Runnable [patchersLen*2]; 499 System.arraycopy(patchers,0,buf,0,patchersLen); 500 patchers = buf; 501 } 502 patchers[patchersLen++] = job; 503 } 504 505 506 private void runPatchers() { 507 if( patchers!=null ) { 508 for( int i=0; i<patchersLen; i++ ) 509 patchers[i].run(); 510 } 511 } 512 513 514 private Hashtable idmap = null; 515 516 public String addToIdTable( String id ) { 517 if(idmap==null) idmap = new Hashtable (); 518 idmap.put( id, getCurrentHandler().owner() ); 519 return id; 520 } 521 522 public Object getObjectFromId( String id ) { 523 if(idmap==null) return null; 524 return idmap.get(id); 525 } 526 527 528 529 public void skippedEntity( String name ) { 535 } 536 public void processingInstruction( String target, String data ) { 537 } 539 public void setDocumentLocator( Locator loc ) { 540 locator = loc; 541 } 542 public Locator getLocator() { return locator; } 543 544 private Locator locator = DUMMY_LOCATOR; 545 546 private static final Locator DUMMY_LOCATOR = new LocatorImpl (); 547 548 549 private final UnmarshallerImpl parent; 555 private boolean aborted = false; 556 557 public void handleEvent(ValidationEvent event, boolean canRecover ) throws SAXException { 558 ValidationEventHandler eventHandler; 559 try { 560 eventHandler = parent.getEventHandler(); 561 } catch( JAXBException e ) { 562 throw new JAXBAssertionError(); 564 } 565 566 boolean recover = eventHandler.handleEvent(event); 567 568 if(!recover) aborted = true; 571 572 if( !canRecover || !recover ) 573 throw new SAXException ( new UnmarshalException( 574 event.getMessage(), 575 event.getLinkedException() ) ); 576 } 577 578 public String getBaseUri() { return null; } 584 public boolean isUnparsedEntity(String s) { return true; } 585 public boolean isNotation(String s) { return true; } 586 587 588 private Tracer tracer; 594 public void setTracer( Tracer t ) { 595 this.tracer = t; 596 } 597 public Tracer getTracer() { 598 if(tracer==null) 599 tracer = new Tracer.Standard(); 600 return tracer; 601 } 602 603 606 private String computeExpectedRootElements() { 607 String r = ""; 608 609 String [] probePoints = grammarInfo.getProbePoints(); 610 for( int i=0; i<probePoints.length; i+=2 ) { 611 if( grammarInfo.recognize(probePoints[i],probePoints[i+1]) ) { 612 if(r.length()!=0) r+=','; 613 r += "<{"+probePoints[i]+"}"+probePoints[i+1]+">"; 614 } 615 } 616 617 return r; 618 } 619 } 620 | Popular Tags |