1 38 39 40 package com.sun.xml.fastinfoset.stax; 41 42 import com.sun.xml.fastinfoset.Encoder; 43 import com.sun.xml.fastinfoset.EncodingConstants; 44 import java.io.IOException ; 45 import java.io.OutputStream ; 46 import java.util.EmptyStackException ; 47 import java.util.Enumeration ; 48 import java.util.Iterator ; 49 import javax.xml.namespace.NamespaceContext ; 50 import javax.xml.stream.XMLStreamException; 51 import javax.xml.stream.XMLStreamWriter; 52 import org.jvnet.fastinfoset.EncodingAlgorithmIndexes; 53 import org.xml.sax.helpers.NamespaceSupport ; 54 import com.sun.xml.fastinfoset.CommonResourceBundle; 55 56 public class StAXDocumentSerializer extends Encoder implements XMLStreamWriter { 57 protected StAXManager _manager; 58 59 protected String _encoding; 60 63 protected String _currentLocalName; 64 65 68 protected String _currentUri; 69 70 73 protected String _currentPrefix; 74 75 78 protected boolean _inStartElement = false; 79 80 83 protected boolean _isEmptyElement = false; 84 85 88 protected String [] _attributesArray = new String [4 * 16]; 89 protected int _attributesArrayIndex = 0; 90 91 94 protected NamespaceSupport _nsSupport = new NamespaceSupport (); 95 96 protected boolean[] _nsSupportContextStack = new boolean[32]; 97 protected int _stackCount = -1; 98 99 protected NamespaceContext _nsContext = new NamespaceContextImpl(); 100 101 104 protected String [] _namespacesArray = new String [2 * 8]; 105 protected int _namespacesArrayIndex = 0; 106 107 public StAXDocumentSerializer() { 108 } 109 110 public StAXDocumentSerializer(OutputStream outputStream) { 111 setOutputStream(outputStream); 112 } 113 114 public StAXDocumentSerializer(OutputStream outputStream, StAXManager manager) { 115 setOutputStream(outputStream); 116 _manager = manager; 117 } 118 119 public void reset() { 120 super.reset(); 121 122 _attributesArrayIndex = 0; 123 _namespacesArrayIndex = 0; 124 _nsSupport.reset(); 125 _stackCount = -1; 126 127 _currentUri = _currentPrefix = null; 128 _currentLocalName = null; 129 130 _inStartElement = _isEmptyElement = false; 131 } 132 133 135 public void writeStartDocument() throws XMLStreamException { 136 writeStartDocument("finf", "1.0"); 137 } 138 139 public void writeStartDocument(String version) throws XMLStreamException { 140 writeStartDocument("finf", version); 141 } 142 143 public void writeStartDocument(String encoding, String version) 144 throws XMLStreamException 145 { 146 reset(); 147 148 try { 149 encodeHeader(false); 150 encodeInitialVocabulary(); 151 } catch (IOException e) { 152 throw new XMLStreamException(e); 153 } 154 } 155 156 public void writeEndDocument() throws XMLStreamException { 157 if (_inStartElement) { 159 } 161 162 try { 163 167 168 encodeDocumentTermination(); 169 } 170 catch (IOException e) { 171 throw new XMLStreamException(e); 172 } 173 } 174 175 public void close() throws XMLStreamException { 176 reset(); 177 } 178 179 public void flush() throws XMLStreamException { 180 try { 181 _s.flush(); 182 } 183 catch (IOException e) { 184 throw new XMLStreamException(e); 185 } 186 } 187 188 public void writeStartElement(String localName) 189 throws XMLStreamException 190 { 191 writeStartElement("", localName, ""); 193 } 194 195 public void writeStartElement(String namespaceURI, String localName) 196 throws XMLStreamException 197 { 198 writeStartElement(getPrefix(namespaceURI), localName, namespaceURI); 199 } 200 201 public void writeStartElement(String prefix, String localName, 202 String namespaceURI) throws XMLStreamException 203 { 204 encodeTerminationAndCurrentElement(false); 205 206 _inStartElement = true; 207 _isEmptyElement = false; 208 209 _currentLocalName = localName; 210 _currentPrefix = prefix; 211 _currentUri = namespaceURI; 212 213 _stackCount++; 214 if (_stackCount == _nsSupportContextStack.length) { 215 boolean[] nsSupportContextStack = new boolean[_stackCount * 2]; 216 System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length); 217 _nsSupportContextStack = nsSupportContextStack; 218 } 219 220 _nsSupportContextStack[_stackCount] = false; 221 } 223 224 public void writeEmptyElement(String localName) 225 throws XMLStreamException 226 { 227 writeEmptyElement("", localName, ""); 228 } 229 230 public void writeEmptyElement(String namespaceURI, String localName) 231 throws XMLStreamException 232 { 233 writeEmptyElement(getPrefix(namespaceURI), localName, namespaceURI); 234 } 235 236 public void writeEmptyElement(String prefix, String localName, 237 String namespaceURI) throws XMLStreamException 238 { 239 encodeTerminationAndCurrentElement(false); 240 241 _isEmptyElement = _inStartElement = true; 242 243 _currentLocalName = localName; 244 _currentPrefix = prefix; 245 _currentUri = namespaceURI; 246 247 _stackCount++; 248 if (_stackCount == _nsSupportContextStack.length) { 249 boolean[] nsSupportContextStack = new boolean[_stackCount * 2]; 250 System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length); 251 _nsSupportContextStack = nsSupportContextStack; 252 } 253 254 _nsSupportContextStack[_stackCount] = false; 255 } 257 258 public void writeEndElement() throws XMLStreamException { 259 if (_inStartElement) { 260 encodeTerminationAndCurrentElement(false); 261 } 262 263 try { 264 encodeElementTermination(); 265 if (_nsSupportContextStack[_stackCount--] == true) { 266 _nsSupport.popContext(); 267 } 268 } 269 catch (IOException e) { 270 throw new XMLStreamException(e); 271 } 272 catch (EmptyStackException e) { 273 throw new XMLStreamException(e); 274 } 275 } 276 277 278 public void writeAttribute(String localName, String value) 279 throws XMLStreamException 280 { 281 writeAttribute("", "", localName, value); 282 } 283 284 public void writeAttribute(String namespaceURI, String localName, 285 String value) throws XMLStreamException 286 { 287 String prefix = ""; 288 289 if (namespaceURI.length() > 0) { 291 prefix = _nsSupport.getPrefix(namespaceURI); 292 293 if (prefix == null || prefix.length() == 0) { 295 if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME || 298 namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) { 299 return; 305 } 306 throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.URIUnbound", new Object []{namespaceURI})); 307 } 308 } 309 writeAttribute(prefix, namespaceURI, localName, value); 310 } 311 312 public void writeAttribute(String prefix, String namespaceURI, 313 String localName, String value) throws XMLStreamException 314 { 315 if (!_inStartElement) { 316 throw new IllegalStateException (CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed")); 317 } 318 319 if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME || 325 namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) { 326 return; 327 } 328 329 if (_attributesArrayIndex == _attributesArray.length) { 330 final String [] attributesArray = new String [_attributesArrayIndex * 2]; 331 System.arraycopy(_attributesArray, 0, attributesArray, 0, _attributesArrayIndex); 332 _attributesArray = attributesArray; 333 } 334 335 _attributesArray[_attributesArrayIndex++] = namespaceURI; 336 _attributesArray[_attributesArrayIndex++] = prefix; 337 _attributesArray[_attributesArrayIndex++] = localName; 338 _attributesArray[_attributesArrayIndex++] = value; 339 } 340 341 public void writeNamespace(String prefix, String namespaceURI) 342 throws XMLStreamException 343 { 344 if (prefix == null || prefix.length() == 0 || prefix.equals(EncodingConstants.XMLNS_NAMESPACE_PREFIX)) { 345 writeDefaultNamespace(namespaceURI); 346 } 347 else { 348 if (!_inStartElement) { 349 throw new IllegalStateException (CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed")); 350 } 351 352 if (_namespacesArrayIndex == _namespacesArray.length) { 353 final String [] namespacesArray = new String [_namespacesArrayIndex * 2]; 354 System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex); 355 _namespacesArray = namespacesArray; 356 } 357 358 _namespacesArray[_namespacesArrayIndex++] = prefix; 359 _namespacesArray[_namespacesArrayIndex++] = namespaceURI; 360 } 361 } 362 363 public void writeDefaultNamespace(String namespaceURI) 364 throws XMLStreamException 365 { 366 if (!_inStartElement) { 367 throw new IllegalStateException (CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed")); 368 } 369 370 if (_namespacesArrayIndex == _namespacesArray.length) { 371 final String [] namespacesArray = new String [_namespacesArrayIndex * 2]; 372 System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex); 373 _namespacesArray = namespacesArray; 374 } 375 376 _namespacesArray[_namespacesArrayIndex++] = ""; 377 _namespacesArray[_namespacesArrayIndex++] = namespaceURI; 378 } 379 380 public void writeComment(String data) throws XMLStreamException { 381 try { 382 encodeTerminationAndCurrentElement(true); 383 384 encodeComment(data.toCharArray(), 0, data.length()); 386 } 387 catch (IOException e) { 388 throw new XMLStreamException(e); 389 } 390 } 391 392 public void writeProcessingInstruction(String target) 393 throws XMLStreamException 394 { 395 writeProcessingInstruction(target, ""); 396 } 397 398 public void writeProcessingInstruction(String target, String data) 399 throws XMLStreamException 400 { 401 try { 402 encodeTerminationAndCurrentElement(true); 403 404 encodeProcessingInstruction(target, data); 405 } 406 catch (IOException e) { 407 throw new XMLStreamException(e); 408 } 409 } 410 411 public void writeCData(String data) throws XMLStreamException { 412 throw new UnsupportedOperationException (CommonResourceBundle.getInstance().getString("message.notImplemented")); 413 } 414 415 public void writeDTD(String dtd) throws XMLStreamException { 416 throw new UnsupportedOperationException (CommonResourceBundle.getInstance().getString("message.notImplemented")); 417 } 418 419 public void writeEntityRef(String name) throws XMLStreamException { 420 throw new UnsupportedOperationException (CommonResourceBundle.getInstance().getString("message.notImplemented")); 421 } 422 423 public void writeCharacters(String text) throws XMLStreamException { 424 try { 425 final int length = text.length(); 426 if (length == 0) { 427 return; 428 } else if (length < _charBuffer.length) { 429 encodeTerminationAndCurrentElement(true); 430 431 text.getChars(0, length, _charBuffer, 0); 432 encodeCharacters(_charBuffer, 0, length); 433 } else { 434 encodeTerminationAndCurrentElement(true); 435 436 final char ch[] = text.toCharArray(); 437 encodeCharactersNoClone(ch, 0, length); 438 } 439 } 440 catch (IOException e) { 441 throw new XMLStreamException(e); 442 } 443 } 444 445 public void writeCharacters(char[] text, int start, int len) 446 throws XMLStreamException 447 { 448 try { 449 if (len == 0) { 450 return; 451 } 452 453 encodeTerminationAndCurrentElement(true); 454 455 encodeCharacters(text, start, len); 456 } 457 catch (IOException e) { 458 throw new XMLStreamException(e); 459 } 460 } 461 462 public String getPrefix(String uri) throws XMLStreamException { 463 return _nsSupport.getPrefix(uri); 464 } 465 466 public void setPrefix(String prefix, String uri) 467 throws XMLStreamException 468 { 469 if (_stackCount > -1 && _nsSupportContextStack[_stackCount] == false) { 470 _nsSupportContextStack[_stackCount] = true; 471 _nsSupport.pushContext(); 472 } 473 474 _nsSupport.declarePrefix(prefix, uri); 475 } 476 477 public void setDefaultNamespace(String uri) throws XMLStreamException { 478 setPrefix("", uri); 479 } 480 481 495 public void setNamespaceContext(NamespaceContext context) 496 throws XMLStreamException 497 { 498 throw new UnsupportedOperationException ("setNamespaceContext"); 499 } 500 501 public NamespaceContext getNamespaceContext() { 502 return _nsContext; 503 } 504 505 public Object getProperty(java.lang.String name) 506 throws IllegalArgumentException 507 { 508 if (_manager != null) { 509 return _manager.getProperty(name); 510 } 511 return null; 512 } 513 514 public void setManager(StAXManager manager) { 515 _manager = manager; 516 } 517 518 public void setEncoding(String encoding) { 519 _encoding = encoding; 520 } 521 522 protected class NamespaceContextImpl implements NamespaceContext { 523 public final String getNamespaceURI(String prefix) { 524 return _nsSupport.getURI(prefix); 525 } 526 527 public final String getPrefix(String namespaceURI) { 528 return _nsSupport.getPrefix(namespaceURI); 529 } 530 531 public final Iterator getPrefixes(String namespaceURI) { 532 final Enumeration e = _nsSupport.getPrefixes(namespaceURI); 533 534 return new Iterator () { 535 public boolean hasNext() { 536 return e.hasMoreElements(); 537 } 538 539 public Object next() { 540 return e.nextElement(); 541 } 542 543 public void remove() { 544 throw new UnsupportedOperationException (); 545 } 546 }; 547 } 548 } 549 550 public void writeOctets(byte[] b, int start, int len) 551 throws XMLStreamException 552 { 553 try { 554 if (len == 0) { 555 return; 556 } 557 558 encodeTerminationAndCurrentElement(true); 559 560 encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, b, start, len); 561 } 562 catch (IOException e) { 563 throw new XMLStreamException(e); 564 } 565 } 566 567 protected void encodeTerminationAndCurrentElement(boolean terminateAfter) throws XMLStreamException { 568 try { 569 encodeTermination(); 570 571 if (_inStartElement) { 572 573 _b = EncodingConstants.ELEMENT; 574 if (_attributesArrayIndex > 0) { 575 _b |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG; 576 } 577 578 if (_namespacesArrayIndex > 0) { 580 write(_b | EncodingConstants.ELEMENT_NAMESPACES_FLAG); 581 for (int i = 0; i < _namespacesArrayIndex;) { 582 encodeNamespaceAttribute(_namespacesArray[i++], _namespacesArray[i++]); 583 } 584 _namespacesArrayIndex = 0; 585 586 write(EncodingConstants.TERMINATOR); 587 588 _b = 0; 589 } 590 591 encodeElementQualifiedNameOnThirdBit(_currentUri, _currentPrefix, _currentLocalName); 593 594 for (int i = 0; i < _attributesArrayIndex;) { 595 encodeAttributeQualifiedNameOnSecondBit( 596 _attributesArray[i++], _attributesArray[i++], _attributesArray[i++]); 597 598 final String value = _attributesArray[i]; 599 _attributesArray[i++] = null; 600 final boolean addToTable = (value.length() < attributeValueSizeConstraint) ? true : false; 601 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable); 602 603 _b = EncodingConstants.TERMINATOR; 604 _terminate = true; 605 } 606 _attributesArrayIndex = 0; 607 _inStartElement = false; 608 609 if (_isEmptyElement) { 610 encodeElementTermination(); 611 if (_nsSupportContextStack[_stackCount--] == true) { 612 _nsSupport.popContext(); 613 } 614 615 _isEmptyElement = false; 616 } 617 618 if (terminateAfter) { 619 encodeTermination(); 620 } 621 } 622 } catch (IOException e) { 623 throw new XMLStreamException(e); 624 } 625 } 626 } | Popular Tags |