1 8 package com.sun.japex.testsuite.impl.runtime; 9 10 import java.util.HashSet ; 11 import java.util.Iterator ; 12 import java.util.Set ; 13 14 import javax.xml.bind.JAXBException; 15 import javax.xml.bind.ValidationEvent; 16 import javax.xml.bind.ValidationEventHandler; 17 import javax.xml.bind.helpers.NotIdentifiableEventImpl; 18 import javax.xml.bind.helpers.ValidationEventLocatorImpl; 19 20 import org.xml.sax.ContentHandler ; 21 import org.xml.sax.SAXException ; 22 import org.xml.sax.helpers.AttributesImpl ; 23 24 import com.sun.xml.bind.JAXBAssertionError; 25 import com.sun.xml.bind.JAXBObject; 26 import com.sun.xml.bind.marshaller.IdentifiableObject; 27 import com.sun.xml.bind.marshaller.Messages; 28 import com.sun.xml.bind.marshaller.NamespacePrefixMapper; 29 import com.sun.xml.bind.serializer.AbortSerializationException; 30 import com.sun.xml.bind.serializer.Util; 31 32 41 public class SAXMarshaller implements XMLSerializer 42 { 43 47 private final AttributesImpl attributes = new AttributesImpl (); 48 49 50 private final ContentHandler writer; 51 52 53 private final MarshallerImpl owner; 54 55 56 private final Set idReferencedObjects = new HashSet (); 57 58 59 private final Set objectsWithId = new HashSet (); 60 61 62 private JAXBObject currentTarget; 63 64 68 public SAXMarshaller( ContentHandler _writer, NamespacePrefixMapper prefixMapper, MarshallerImpl _owner ) { 69 this.writer = _writer; 70 this.owner = _owner; 71 this.nsContext = new NamespaceContextImpl( 72 prefixMapper!=null?prefixMapper:defaultNamespacePrefixMapper); 73 } 74 75 76 private final NamespaceContextImpl nsContext; 77 78 public NamespaceContext2 getNamespaceContext() { return nsContext; } 79 80 86 87 private String [] elementStack = new String [16];; 88 private int elementLen=0; 89 90 91 92 private void pushElement( String uri, String local ) { 93 if(elementStack.length==elementLen) { 94 String [] buf = new String [elementStack.length*2]; 96 System.arraycopy( elementStack, 0, buf, 0, elementStack.length ); 97 elementStack = buf; 98 } 99 elementStack[elementLen++] = uri; 100 elementStack[elementLen++] = local; 101 } 102 103 private void popElement() { elementLen-=2; } 104 105 private String getCurrentElementUri() { return elementStack[elementLen-2]; } 106 private String getCurrentElementLocal() { return elementStack[elementLen-1]; } 107 108 109 110 111 112 117 public void startElement( String uri, String local ) throws SAXException { 118 boolean isRoot = false; 119 String suggestion = null; 120 if( elementLen==0 ) { 121 isRoot = true; 122 suggestion = ""; 124 } 125 126 writePendingText(); 127 nsContext.startElement(); 128 pushElement(uri,local); 130 nsContext.declareNamespace(uri,suggestion,false); 132 133 if( isRoot ) { 135 String [] uris = nsContext.getNamespacePrefixMapper().getPreDeclaredNamespaceUris(); 137 if( uris!=null ) { 138 for( int i=0; i<uris.length; i++ ) { 139 if( uris[i]!=null ) 140 nsContext.declareNamespace(uris[i],null,false); 141 } 142 } 143 } 144 } 145 146 147 private final PrefixCallback startPrefixCallback = new PrefixCallback() { 148 public void onPrefixMapping( String prefix, String nsUri ) throws SAXException { 149 writer.startPrefixMapping(prefix,nsUri); 150 } 151 }; 152 private final PrefixCallback endPrefixCallback = new PrefixCallback() { 153 public void onPrefixMapping( String prefix, String nsUri ) throws SAXException { 154 writer.endPrefixMapping(prefix); 155 } 156 }; 157 158 public void endNamespaceDecls() throws SAXException { 159 nsContext.endNamespaceDecls(); 160 } 161 162 166 public void endAttributes() throws SAXException { 167 String uri = getCurrentElementUri(); 169 String local = getCurrentElementLocal(); 170 171 String prefix = nsContext.getPrefix(uri); 172 _assert(prefix!=null); 174 String qname; 175 if(prefix.length()!=0 ) 176 qname = prefix+':'+local; 177 else 178 qname = local; 179 180 nsContext.iterateDeclaredPrefixes(startPrefixCallback); 182 183 writer.startElement( uri, local, qname, attributes ); 185 186 187 attributes.clear(); 189 190 textBuf.setLength(0); 192 } 193 194 198 public void endElement() throws SAXException { 199 writePendingText(); 200 201 String uri = getCurrentElementUri(); 202 String local = getCurrentElementLocal(); 203 204 String prefix = nsContext.getPrefix(uri); 205 _assert(prefix!=null); 207 String qname; 208 if(prefix.length()!=0) 209 qname = prefix+':'+local; 210 else 211 qname = local; 212 213 writer.endElement( uri, local, qname ); 214 215 nsContext.iterateDeclaredPrefixes(endPrefixCallback); 218 219 popElement(); 220 221 textBuf.setLength(0); 223 224 nsContext.endElement(); 225 } 226 227 228 229 private final StringBuffer textBuf = new StringBuffer (); 230 231 268 public void text( String text, String fieldName ) throws SAXException { 269 if(text==null) { 272 reportError(Util.createMissingObjectError(currentTarget,fieldName)); 273 return; 274 } 275 276 if(textBuf.length()!=0) 277 textBuf.append(' '); 278 textBuf.append(text); 279 } 280 281 285 private void writePendingText() throws SAXException { 286 int len = textBuf.length(); 288 289 if(len!=0) 290 writer.characters( textBuf.toString().toCharArray(), 0, len ); 291 } 292 293 307 public void startAttribute( String uri, String local ) { 308 textBuf.setLength(0); 310 311 this.attNamespaceUri = uri; 313 this.attLocalName = local; 314 } 315 316 private String attNamespaceUri; 318 private String attLocalName; 319 320 public void endAttribute() { 321 332 String qname; 333 if(attNamespaceUri.length()==0) { 334 qname = attLocalName; 336 } else { 337 qname = nsContext.declareNamespace(attNamespaceUri,null,true)+':'+attLocalName; 338 } 339 340 attributes.addAttribute(attNamespaceUri,attLocalName,qname,"CDATA",textBuf.toString()); 341 } 342 343 public String onID( IdentifiableObject owner, String value ) throws SAXException { 344 objectsWithId.add(owner); 345 return value; 346 } 347 public String onIDREF( IdentifiableObject obj ) throws SAXException { 348 idReferencedObjects.add(obj); 349 String id = obj.____jaxb____getId(); 350 if(id==null) { 351 reportError( new NotIdentifiableEventImpl( 352 ValidationEvent.ERROR, 353 Messages.format(Messages.ERR_NOT_IDENTIFIABLE), 354 new ValidationEventLocatorImpl(obj) ) ); 355 } 356 return id; 357 } 358 359 void reconcileID() throws AbortSerializationException { 360 idReferencedObjects.removeAll(objectsWithId); 362 363 for( Iterator itr=idReferencedObjects.iterator(); itr.hasNext(); ) { 364 IdentifiableObject o = (IdentifiableObject)itr.next(); 365 reportError( new NotIdentifiableEventImpl( 366 ValidationEvent.ERROR, 367 Messages.format(Messages.ERR_DANGLING_IDREF,o.____jaxb____getId()), 368 new ValidationEventLocatorImpl(o) ) ); 369 } 370 371 idReferencedObjects.clear(); 373 objectsWithId.clear(); 374 } 375 376 377 378 public void childAsBody( JAXBObject o, String fieldName ) throws SAXException { 379 if(o==null) { 380 reportMissingObjectError(fieldName); 383 return; 386 } 387 388 JAXBObject oldTarget = currentTarget; 389 currentTarget = o; 390 391 owner.context.getGrammarInfo().castToXMLSerializable(o).serializeBody(this); 392 393 currentTarget = oldTarget; 394 } 395 396 public void childAsAttributes( JAXBObject o, String fieldName ) throws SAXException { 397 if(o==null) { 398 reportMissingObjectError(fieldName); 399 return; 400 } 401 402 JAXBObject oldTarget = currentTarget; 403 currentTarget = o; 404 405 owner.context.getGrammarInfo().castToXMLSerializable(o).serializeAttributes(this); 406 407 currentTarget = oldTarget; 408 } 409 410 public void childAsURIs( JAXBObject o, String fieldName ) throws SAXException { 411 if(o==null) { 412 reportMissingObjectError(fieldName); 413 return; 414 } 415 416 JAXBObject oldTarget = currentTarget; 417 currentTarget = o; 418 419 owner.context.getGrammarInfo().castToXMLSerializable(o).serializeURIs(this); 420 421 currentTarget = oldTarget; 422 } 423 424 425 public void reportError( ValidationEvent ve ) throws AbortSerializationException { 426 ValidationEventHandler handler; 427 428 try { 429 handler = owner.getEventHandler(); 430 } catch( JAXBException e ) { 431 throw new AbortSerializationException(e); 432 } 433 434 if(!handler.handleEvent(ve)) { 435 if(ve.getLinkedException() instanceof Exception ) 436 throw new AbortSerializationException((Exception )ve.getLinkedException()); 437 else 438 throw new AbortSerializationException(ve.getMessage()); 439 } 440 } 441 442 443 public void reportMissingObjectError(String fieldName) throws SAXException { 444 reportError(Util.createMissingObjectError(currentTarget,fieldName)); 445 } 446 447 448 private static void _assert( boolean b ) { 449 if(!b) 450 throw new JAXBAssertionError(); 451 } 452 453 457 private static NamespacePrefixMapper defaultNamespacePrefixMapper = new NamespacePrefixMapper() { 458 public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { 459 if( namespaceUri.equals("http://www.w3.org/2001/XMLSchema-instance") ) 460 return "xsi"; 461 return suggestion; 462 } 463 }; 464 } 465 | Popular Tags |