1 8 package com.sun.japex.testsuite.impl.runtime; 9 10 import java.util.ArrayList ; 11 import java.util.Collections ; 12 import java.util.Hashtable ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 16 import javax.xml.XMLConstants ; 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 ; 23 import org.xml.sax.Locator ; 24 import org.xml.sax.SAXException ; 25 import org.xml.sax.SAXParseException ; 26 27 import com.sun.xml.bind.JAXBAssertionError; 28 import com.sun.xml.bind.unmarshaller.Messages; 29 import com.sun.xml.bind.unmarshaller.Tracer; 30 import com.sun.xml.bind.util.AttributesImpl; 31 32 41 public class SAXUnmarshallerHandlerImpl 42 implements SAXUnmarshallerHandler, UnmarshallingContext 43 { 44 52 private boolean isUnmarshalInProgress = true; 53 54 55 56 public SAXUnmarshallerHandlerImpl( UnmarshallerImpl _parent, GrammarInfo _gi ) { 57 this.parent = _parent; 58 grammarInfo = _gi; 59 startPrefixMapping("",""); } 61 62 private final GrammarInfo grammarInfo; 63 public GrammarInfo getGrammarInfo() { return grammarInfo; } 64 65 68 private final boolean shouldCollectText() { 69 return collectText[stackTop]; 70 } 71 72 public void startDocument() throws SAXException { 73 result = null; 75 handlerLen=0; 76 patchers=null; 77 patchersLen=0; 78 aborted = false; 79 isUnmarshalInProgress = true; 80 81 stackTop=0; 82 elementDepth=1; 83 } 84 85 public void endDocument() throws SAXException { 86 runPatchers(); 87 isUnmarshalInProgress = false; 88 } 89 90 public void startElement( String uri, String local, String qname, Attributes atts ) 91 throws SAXException { 92 93 if( uri==null || uri.length()==0 ) 95 uri=""; 96 if( local==null || local.length()==0 ) 97 local=qname; 98 if( qname==null || qname.length()==0 ) 99 qname=local; 100 101 if(result==null) { 102 UnmarshallingEventHandler unmarshaller = 105 grammarInfo.createUnmarshaller(uri,local,this); 106 if(unmarshaller==null) { 107 throw new SAXParseException ( 114 Messages.format( Messages.UNEXPECTED_ROOT_ELEMENT2, 115 uri, local, computeExpectedRootElements() ), 116 getLocator() ); 117 } 118 result = unmarshaller.owner(); 119 120 pushContentHandler(unmarshaller,0); 121 } 122 123 processText(true); 124 125 getCurrentHandler().enterElement(uri,local,qname,atts); 126 } 127 128 public final void endElement( String uri, String local, String qname ) 129 throws SAXException { 130 131 if( uri==null || uri.length()==0 ) 133 uri=""; 134 if( local==null || local.length()==0 ) 135 local=qname; 136 if( qname==null || qname.length()==0 ) 137 qname=local; 138 139 processText(false); 140 getCurrentHandler().leaveElement(uri,local,qname); 141 } 142 143 144 145 146 147 148 private Object result; 149 public Object getResult() throws UnmarshalException { 150 if(isUnmarshalInProgress) 151 throw new IllegalStateException (); 152 153 if(!aborted) return result; 154 155 throw new UnmarshalException((String )null); 157 } 158 159 160 161 private UnmarshallingEventHandler[] handlers = new UnmarshallingEventHandler[16]; 167 private int[] mementos = new int[16]; 168 private int handlerLen=0; 169 170 public void pushContentHandler( UnmarshallingEventHandler handler, int memento ) { 171 if(handlerLen==handlers.length) { 172 UnmarshallingEventHandler[] h = new UnmarshallingEventHandler[handlerLen*2]; 174 int[] m = new int[handlerLen*2]; 175 System.arraycopy(handlers,0,h,0,handlerLen); 176 System.arraycopy(mementos,0,m,0,handlerLen); 177 handlers = h; 178 mementos = m; 179 } 180 handlers[handlerLen] = handler; 181 mementos[handlerLen] = memento; 182 handlerLen++; 183 } 184 185 public void popContentHandler() throws SAXException { 186 handlerLen--; 187 handlers[handlerLen]=null; getCurrentHandler().leaveChild(mementos[handlerLen]); 189 } 190 191 public UnmarshallingEventHandler getCurrentHandler() { 192 return handlers[handlerLen-1]; 193 } 194 195 196 private StringBuffer buffer = new StringBuffer (); 202 203 protected void consumeText( String str, boolean ignorable ) throws SAXException { 204 if(ignorable && str.trim().length()==0) 205 return; 208 209 getCurrentHandler().text(str); 211 } 212 private void processText( boolean ignorable ) throws SAXException { 213 if( shouldCollectText() ) 214 consumeText(buffer.toString(),ignorable); 215 216 if(buffer.length()<1024) buffer.setLength(0); 219 else buffer = new StringBuffer (); 220 } 221 222 public final void characters( char[] buf, int start, int len ) { 223 if( shouldCollectText() ) 224 buffer.append(buf,start,len); 225 } 226 227 public final void ignorableWhitespace( char[] buf, int start, int len ) { 228 characters(buf,start,len); 229 } 230 231 232 233 234 private String [] nsBind = new String [16]; 240 private int nsLen=0; 241 242 private int[] idxStack = new int[16]; 246 247 public void startPrefixMapping( String prefix, String uri ) { 248 if(nsBind.length==nsLen) { 249 String [] n = new String [nsLen*2]; 251 System.arraycopy(nsBind,0,n,0,nsLen); 252 nsBind=n; 253 } 254 nsBind[nsLen++] = prefix; 255 nsBind[nsLen++] = uri; 256 } 257 public void endPrefixMapping( String prefix ) { 258 nsLen-=2; 259 } 260 public String resolveNamespacePrefix( String prefix ) { 261 if(prefix.equals("xml")) 262 return "http://www.w3.org/XML/1998/namespace"; 263 264 for( int i=idxStack[stackTop]-2; i>=0; i-=2 ) { 265 if(prefix.equals(nsBind[i])) 266 return nsBind[i+1]; 267 } 268 return null; 269 } 270 public String [] getNewlyDeclaredPrefixes() { 271 return getPrefixList( idxStack[stackTop-1] ); 272 } 273 274 public String [] getAllDeclaredPrefixes() { 275 return getPrefixList( 2 ); } 277 278 private String [] getPrefixList( int startIndex ) { 279 int size = (idxStack[stackTop]-startIndex)/2; 280 String [] r = new String [size]; 281 for( int i=0; i<r.length; i++ ) 282 r[i] = nsBind[startIndex+i*2]; 283 return r; 284 } 285 286 287 public Iterator getPrefixes(String uri) { 291 return Collections.unmodifiableList( 294 getAllPrefixesInList(uri)).iterator(); 295 } 296 297 private List getAllPrefixesInList(String uri) { 298 List a = new ArrayList (); 299 300 if( uri.equals(XMLConstants.XML_NS_URI) ) { 301 a.add(XMLConstants.XML_NS_PREFIX); 302 return a; 303 } 304 if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) ) { 305 a.add(XMLConstants.XMLNS_ATTRIBUTE); 306 return a; 307 } 308 if( uri==null ) 309 throw new IllegalArgumentException (); 310 311 for( int i=nsLen-2; i>=0; i-=2 ) 312 if(uri.equals(nsBind[i+1])) 313 if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) ) 314 a.add(nsBind[i]); 316 317 return a; 318 } 319 320 public String getPrefix(String uri) { 321 if( uri.equals(XMLConstants.XML_NS_URI) ) 322 return XMLConstants.XML_NS_PREFIX; 323 if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) ) 324 return XMLConstants.XMLNS_ATTRIBUTE; 325 if( uri==null ) 326 throw new IllegalArgumentException (); 327 328 for( int i=idxStack[stackTop]-2; i>=0; i-=2 ) 329 if(uri.equals(nsBind[i+1])) 330 if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) ) 331 return nsBind[i]; 333 334 return null; 335 } 336 337 public String getNamespaceURI(String prefix) { 338 if( prefix.equals(XMLConstants.XMLNS_ATTRIBUTE) ) 339 return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; 340 if( prefix==null ) 341 throw new IllegalArgumentException (); 342 343 return resolveNamespacePrefix(prefix); 344 } 345 346 354 private AttributesImpl[] attStack = new AttributesImpl[16]; 355 358 private int elementDepth; 359 362 private int stackTop; 363 364 370 private boolean[] collectText = new boolean[16]; 371 372 public void pushAttributes( Attributes atts, boolean collectTextFlag ) { 373 374 if( attStack.length==elementDepth ) { 375 AttributesImpl[] buf1 = new AttributesImpl[attStack.length*2]; 377 System.arraycopy(attStack,0,buf1,0,attStack.length); 378 attStack = buf1; 379 380 int[] buf2 = new int[idxStack.length*2]; 381 System.arraycopy(idxStack,0,buf2,0,idxStack.length); 382 idxStack = buf2; 383 384 boolean[] buf3 = new boolean[collectText.length*2]; 385 System.arraycopy(collectText,0,buf3,0,collectText.length); 386 collectText = buf3; 387 } 388 389 elementDepth++; 390 stackTop++; 391 392 AttributesImpl a = attStack[stackTop]; 394 if( a==null ) 395 attStack[stackTop] = a = new AttributesImpl(); 396 else 397 a.clear(); 398 399 for( int i=0; i<atts.getLength(); i++ ) { 403 String auri = atts.getURI(i); 404 String alocal = atts.getLocalName(i); 405 String avalue = atts.getValue(i); 406 407 if( auri=="http://www.w3.org/2001/XMLSchema-instance" && alocal=="nil" ) { 414 String v = avalue.trim(); 415 if(v.equals("false") || v.equals("0")) 416 continue; } 418 419 a.addAttribute( 421 auri, 422 alocal, 423 atts.getQName(i), 424 atts.getType(i), 425 avalue ); 426 } 427 428 429 idxStack[stackTop] = nsLen; 431 432 collectText[stackTop] = collectTextFlag; 433 } 434 public void popAttributes() { 435 stackTop--; 436 elementDepth--; 437 } 438 public Attributes getUnconsumedAttributes() { 439 return attStack[stackTop]; 440 } 441 445 public int getAttribute( String uri, String local ) { 446 return attStack[stackTop].getIndexFast(uri,local); 447 } 448 public void consumeAttribute( int idx ) throws SAXException { 449 AttributesImpl a = attStack[stackTop]; 450 451 String uri = a.getURI(idx); 452 String local = a.getLocalName(idx); 453 String qname = a.getQName(idx); 454 String value = a.getValue(idx); 455 456 a.removeAttribute(idx); 460 461 462 getCurrentHandler().enterAttribute(uri,local,qname); 463 consumeText(value,false); 464 getCurrentHandler().leaveAttribute(uri,local,qname); 465 } 466 public String eatAttribute( int idx ) throws SAXException { 467 AttributesImpl a = attStack[stackTop]; 468 469 String value = a.getValue(idx); 470 471 a.removeAttribute(idx); 473 474 return value; 475 } 476 477 487 private Runnable [] patchers = null; 488 private int patchersLen = 0; 489 490 public void addPatcher( Runnable job ) { 491 if( patchers==null ) 493 patchers = new Runnable [32]; 494 if( patchers.length == patchersLen ) { 495 Runnable [] buf = new Runnable [patchersLen*2]; 496 System.arraycopy(patchers,0,buf,0,patchersLen); 497 patchers = buf; 498 } 499 patchers[patchersLen++] = job; 500 } 501 502 503 private void runPatchers() { 504 if( patchers!=null ) { 505 for( int i=0; i<patchersLen; i++ ) 506 patchers[i].run(); 507 } 508 } 509 510 511 private Hashtable idmap = null; 512 513 public String addToIdTable( String id ) { 514 if(idmap==null) idmap = new Hashtable (); 515 idmap.put( id, getCurrentHandler().owner() ); 516 return id; 517 } 518 519 public Object getObjectFromId( String id ) { 520 if(idmap==null) return null; 521 return idmap.get(id); 522 } 523 524 525 526 public void skippedEntity( String name ) { 532 } 533 public void processingInstruction( String target, String data ) { 534 } 536 public void setDocumentLocator( Locator loc ) { 537 locator = loc; 538 } 539 public Locator getLocator() { return locator; } 540 541 private Locator locator; 542 543 544 private final UnmarshallerImpl parent; 550 private boolean aborted = false; 551 552 public void handleEvent(ValidationEvent event, boolean canRecover ) throws SAXException { 553 ValidationEventHandler eventHandler; 554 try { 555 eventHandler = parent.getEventHandler(); 556 } catch( JAXBException e ) { 557 throw new JAXBAssertionError(); 559 } 560 561 boolean recover = eventHandler.handleEvent(event); 562 563 if(!recover) aborted = true; 566 567 if( !canRecover || !recover ) 568 throw new SAXException ( new UnmarshalException( 569 event.getMessage(), 570 event.getLinkedException() ) ); 571 } 572 573 public String getBaseUri() { return null; } 579 public boolean isUnparsedEntity(String s) { return true; } 580 public boolean isNotation(String s) { return true; } 581 582 583 private Tracer tracer; 589 public void setTracer( Tracer t ) { 590 this.tracer = t; 591 } 592 public Tracer getTracer() { 593 if(tracer==null) 594 tracer = new Tracer.Standard(); 595 return tracer; 596 } 597 598 601 private String computeExpectedRootElements() { 602 String r = ""; 603 604 String [] probePoints = grammarInfo.getProbePoints(); 605 for( int i=0; i<probePoints.length; i+=2 ) { 606 if( grammarInfo.recognize(probePoints[i],probePoints[i+1]) ) { 607 if(r.length()!=0) r+=','; 608 r += "<{"+probePoints[i]+"}"+probePoints[i+1]+">"; 609 } 610 } 611 612 return r; 613 } 614 } 615 | Popular Tags |