1 8 package com.mvnforum.jaxb.db.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 import org.xml.sax.helpers.LocatorImpl ; 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 42 public class SAXUnmarshallerHandlerImpl 43 implements SAXUnmarshallerHandler, UnmarshallingContext 44 { 45 53 private boolean isUnmarshalInProgress = true; 54 55 56 57 public SAXUnmarshallerHandlerImpl( UnmarshallerImpl _parent, GrammarInfo _gi ) { 58 this.parent = _parent; 59 grammarInfo = _gi; 60 startPrefixMapping("",""); } 62 63 private final GrammarInfo grammarInfo; 64 public GrammarInfo getGrammarInfo() { return grammarInfo; } 65 66 69 private final boolean shouldCollectText() { 70 return collectText[stackTop]; 71 } 72 73 public void startDocument() throws SAXException { 74 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 { 87 runPatchers(); 88 isUnmarshalInProgress = false; 89 } 90 91 public void startElement( String uri, String local, String qname, Attributes atts ) 92 throws SAXException { 93 94 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 UnmarshallingEventHandler unmarshaller = 106 grammarInfo.createUnmarshaller(uri,local,this); 107 if(unmarshaller==null) { 108 throw new SAXParseException ( 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 uri, String local, String qname ) 130 throws SAXException { 131 132 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 149 private Object result; 150 public Object getResult() throws UnmarshalException { 151 if(isUnmarshalInProgress) 152 throw new IllegalStateException (); 153 154 if(!aborted) return result; 155 156 throw new UnmarshalException((String )null); 158 } 159 160 161 162 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 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 { 187 handlerLen--; 188 handlers[handlerLen]=null; getCurrentHandler().leaveChild(mementos[handlerLen]); 190 } 191 192 public UnmarshallingEventHandler getCurrentHandler() { 193 return handlers[handlerLen-1]; 194 } 195 196 197 private StringBuffer buffer = new StringBuffer (); 203 204 protected void consumeText( String str, boolean ignorable ) throws SAXException { 205 if(ignorable && str.trim().length()==0) 206 return; 209 210 getCurrentHandler().text(str); 212 } 213 private void processText( boolean ignorable ) throws SAXException { 214 if( shouldCollectText() ) 215 consumeText(buffer.toString(),ignorable); 216 217 if(buffer.length()<1024) buffer.setLength(0); 220 else buffer = new StringBuffer (); 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 private String [] nsBind = new String [16]; 241 private int nsLen=0; 242 243 private int[] idxStack = new int[16]; 247 248 public void startPrefixMapping( String prefix, String uri ) { 249 if(nsBind.length==nsLen) { 250 String [] n = new String [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 prefix ) { 259 nsLen-=2; 260 } 261 public String resolveNamespacePrefix( String 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 [] getNewlyDeclaredPrefixes() { 272 return getPrefixList( idxStack[stackTop-1] ); 273 } 274 275 public String [] getAllDeclaredPrefixes() { 276 return getPrefixList( 2 ); } 278 279 private String [] getPrefixList( int startIndex ) { 280 int size = (idxStack[stackTop]-startIndex)/2; 281 String [] r = new String [size]; 282 for( int i=0; i<r.length; i++ ) 283 r[i] = nsBind[startIndex+i*2]; 284 return r; 285 } 286 287 288 public Iterator getPrefixes(String uri) { 292 return Collections.unmodifiableList( 295 getAllPrefixesInList(uri)).iterator(); 296 } 297 298 private List getAllPrefixesInList(String uri) { 299 List a = new ArrayList (); 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 (); 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 a.add(nsBind[i]); 317 318 return a; 319 } 320 321 public String getPrefix(String 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 (); 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 return nsBind[i]; 334 335 return null; 336 } 337 338 public String getNamespaceURI(String prefix) { 339 if( prefix==null ) 340 throw new IllegalArgumentException (); 341 if( prefix.equals(XMLConstants.XMLNS_ATTRIBUTE) ) 342 return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; 343 344 return resolveNamespacePrefix(prefix); 345 } 346 347 355 private AttributesImpl[] attStack = new AttributesImpl[16]; 356 359 private int elementDepth; 360 363 private int stackTop; 364 365 371 private boolean[] collectText = new boolean[16]; 372 373 public void pushAttributes( Attributes atts, boolean collectTextFlag ) { 374 375 if( attStack.length==elementDepth ) { 376 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 AttributesImpl a = attStack[stackTop]; 395 if( a==null ) 396 attStack[stackTop] = a = new AttributesImpl(); 397 else 398 a.clear(); 399 400 for( int i=0; i<atts.getLength(); i++ ) { 404 String auri = atts.getURI(i); 405 String alocal = atts.getLocalName(i); 406 String avalue = atts.getValue(i); 407 String aqname = atts.getQName(i); 408 409 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 if( auri=="http://www.w3.org/2001/XMLSchema-instance" && alocal=="nil" ) { 424 String v = avalue.trim(); 425 if(v.equals("false") || v.equals("0")) 426 continue; } 428 429 a.addAttribute( 431 auri, 432 alocal, 433 aqname, 434 atts.getType(i), 435 avalue ); 436 } 437 438 439 idxStack[stackTop] = nsLen; 441 442 collectText[stackTop] = collectTextFlag; 443 } 444 public void popAttributes() { 445 stackTop--; 446 elementDepth--; 447 } 448 public Attributes getUnconsumedAttributes() { 449 return attStack[stackTop]; 450 } 451 455 public int getAttribute( String uri, String local ) { 456 return attStack[stackTop].getIndexFast(uri,local); 457 } 458 public void consumeAttribute( int idx ) throws SAXException { 459 AttributesImpl a = attStack[stackTop]; 460 461 String uri = a.getURI(idx); 462 String local = a.getLocalName(idx); 463 String qname = a.getQName(idx); 464 String value = a.getValue(idx); 465 466 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 eatAttribute( int idx ) throws SAXException { 477 AttributesImpl a = attStack[stackTop]; 478 479 String value = a.getValue(idx); 480 481 a.removeAttribute(idx); 483 484 return value; 485 } 486 487 497 private Runnable [] patchers = null; 498 private int patchersLen = 0; 499 500 public void addPatcher( Runnable job ) { 501 if( patchers==null ) 503 patchers = new Runnable [32]; 504 if( patchers.length == patchersLen ) { 505 Runnable [] buf = new Runnable [patchersLen*2]; 506 System.arraycopy(patchers,0,buf,0,patchersLen); 507 patchers = buf; 508 } 509 patchers[patchersLen++] = job; 510 } 511 512 513 private void runPatchers() { 514 if( patchers!=null ) { 515 for( int i=0; i<patchersLen; i++ ) 516 patchers[i].run(); 517 } 518 } 519 520 521 private Hashtable idmap = null; 522 523 public String addToIdTable( String id ) { 524 if(idmap==null) idmap = new Hashtable (); 525 idmap.put( id, getCurrentHandler().owner() ); 526 return id; 527 } 528 529 public Object getObjectFromId( String id ) { 530 if(idmap==null) return null; 531 return idmap.get(id); 532 } 533 534 535 536 public void skippedEntity( String name ) { 542 } 543 public void processingInstruction( String target, String data ) { 544 } 546 public void setDocumentLocator( Locator loc ) { 547 locator = loc; 548 } 549 public Locator getLocator() { return locator; } 550 551 private Locator locator = DUMMY_LOCATOR; 552 553 private static final Locator DUMMY_LOCATOR = new LocatorImpl (); 554 555 556 private final UnmarshallerImpl parent; 562 private boolean aborted = false; 563 564 public void handleEvent(ValidationEvent event, boolean canRecover ) throws SAXException { 565 ValidationEventHandler eventHandler; 566 try { 567 eventHandler = parent.getEventHandler(); 568 } catch( JAXBException e ) { 569 throw new JAXBAssertionError(); 571 } 572 573 boolean recover = eventHandler.handleEvent(event); 574 575 if(!recover) aborted = true; 578 579 if( !canRecover || !recover ) 580 throw new SAXException ( new UnmarshalException( 581 event.getMessage(), 582 event.getLinkedException() ) ); 583 } 584 585 public String getBaseUri() { return null; } 591 public boolean isUnparsedEntity(String s) { return true; } 592 public boolean isNotation(String s) { return true; } 593 594 595 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 613 private String computeExpectedRootElements() { 614 String r = ""; 615 616 String [] 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 |