1 17 18 22 23 package org.apache.geronimo.system.configuration; 24 25 import java.io.IOException ; 26 import java.io.OutputStream ; 27 import java.io.Writer ; 28 import java.util.Enumeration ; 29 30 import org.w3c.dom.Attr ; 31 import org.w3c.dom.Element ; 32 import org.w3c.dom.NamedNodeMap ; 33 import org.w3c.dom.Node ; 34 import org.xml.sax.AttributeList ; 35 import org.xml.sax.Attributes ; 36 import org.xml.sax.SAXException ; 37 import org.xml.sax.helpers.AttributesImpl ; 38 39 40 69 public class XMLSerializer extends BaseMarkupSerializer 70 { 71 72 77 public XMLSerializer() 78 { 79 super( new OutputFormat( Method.XML, null, false ) ); 80 } 81 82 83 88 public XMLSerializer( OutputFormat format ) 89 { 90 super( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 91 this.format.setMethod( Method.XML ); 92 } 93 94 95 103 public XMLSerializer( Writer writer, OutputFormat format ) 104 { 105 super( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 106 this.format.setMethod( Method.XML ); 107 setOutputCharStream( writer ); 108 } 109 110 111 119 public XMLSerializer( OutputStream output, OutputFormat format ) 120 { 121 super( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 122 this.format.setMethod( Method.XML ); 123 setOutputByteStream( output ); 124 } 125 126 127 public void setOutputFormat( OutputFormat format ) 128 { 129 super.setOutputFormat( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 130 } 131 132 133 137 138 public void startElement( String namespaceURI, String localName, 139 String rawName, Attributes attrs ) 140 throws SAXException 141 { 142 int i; 143 boolean preserveSpace; 144 ElementState state; 145 String name; 146 String value; 147 148 try { 149 if ( printer == null ) 150 throw new IllegalStateException ( "SER002 No writer supplied for serializer" ); 151 152 state = getElementState(); 153 if ( isDocumentState() ) { 154 if ( ! started ) 159 startDocument( ( localName == null || localName.length() == 0 ) ? rawName : localName ); 160 } else { 161 if ( state.empty ) 165 printer.printText( '>' ); 166 if ( state.inCData ) 168 { 169 printer.printText( "]]>" ); 170 state.inCData = false; 171 } 172 if ( indenting && ! state.preserveSpace && 176 ( state.empty || state.afterElement || state.afterComment) ) 177 printer.breakLine(); 178 } 179 preserveSpace = state.preserveSpace; 180 181 attrs = extractNamespaces(attrs); 184 185 if ( rawName == null || rawName.length() == 0 ) { 188 if ( localName == null ) 189 throw new SAXException ( "No rawName and localName is null" ); 190 if ( namespaceURI != null && ! namespaceURI.equals( "" ) ) { 191 String prefix; 192 prefix = getPrefix( namespaceURI ); 193 if ( prefix != null && prefix.length() > 0 ) 194 rawName = prefix + ":" + localName; 195 else 196 rawName = localName; 197 } else 198 rawName = localName; 199 } 200 201 printer.printText( '<' ); 202 printer.printText( rawName ); 203 printer.indent(); 204 205 if ( attrs != null ) { 209 for ( i = 0 ; i < attrs.getLength() ; ++i ) { 210 printer.printSpace(); 211 212 name = attrs.getQName( i ); 213 if ( name != null && name.length() == 0 ) { 214 String prefix; 215 String attrURI; 216 217 name = attrs.getLocalName( i ); 218 attrURI = attrs.getURI( i ); 219 if ( ( attrURI != null && attrURI.length() != 0 ) && 220 ( namespaceURI == null || namespaceURI.length() == 0 || 221 ! attrURI.equals( namespaceURI ) ) ) { 222 prefix = getPrefix( attrURI ); 223 if ( prefix != null && prefix.length() > 0 ) 224 name = prefix + ":" + name; 225 } 226 } 227 228 value = attrs.getValue( i ); 229 if ( value == null ) 230 value = ""; 231 printer.printText( name ); 232 printer.printText( "=\"" ); 233 printEscaped( value ); 234 printer.printText( '"' ); 235 236 if ( name.equals( "xml:space" ) ) { 240 if ( value.equals( "preserve" ) ) 241 preserveSpace = true; 242 else 243 preserveSpace = format.getPreserveSpace(); 244 } 245 } 246 } 247 248 if ( prefixes != null ) { 249 Enumeration keyEnum; 250 251 keyEnum = prefixes.keys(); 252 while ( keyEnum.hasMoreElements() ) { 253 printer.printSpace(); 254 value = (String ) keyEnum.nextElement(); 255 name = (String ) prefixes.get( value ); 256 if ( name.length() == 0 ) { 257 printer.printText( "xmlns=\"" ); 258 printEscaped( value ); 259 printer.printText( '"' ); 260 } else { 261 printer.printText( "xmlns:" ); 262 printer.printText( name ); 263 printer.printText( "=\"" ); 264 printEscaped( value ); 265 printer.printText( '"' ); 266 } 267 } 268 } 269 270 state = enterElementState( namespaceURI, localName, rawName, preserveSpace ); 274 name = ( localName == null || localName.length() == 0 ) ? rawName : namespaceURI + "^" + localName; 275 state.doCData = format.isCDataElement( name ); 276 state.unescaped = format.isNonEscapingElement( name ); 277 } catch ( IOException except ) { 278 throw new SAXException ( except ); 279 } 280 } 281 282 283 public void endElement( String namespaceURI, String localName, 284 String rawName ) 285 throws SAXException 286 { 287 try { 288 endElementIO( namespaceURI, localName, rawName ); 289 } catch ( IOException except ) { 290 throw new SAXException ( except ); 291 } 292 } 293 294 295 public void endElementIO( String namespaceURI, String localName, 296 String rawName ) 297 throws IOException 298 { 299 ElementState state; 300 301 printer.unindent(); 305 state = getElementState(); 306 if ( state.empty ) { 307 printer.printText( "/>" ); 308 } else { 309 if ( state.inCData ) 311 printer.printText( "]]>" ); 312 if ( indenting && ! state.preserveSpace && (state.afterElement || state.afterComment) ) 316 printer.breakLine(); 317 printer.printText( "</" ); 318 printer.printText( state.rawName ); 319 printer.printText( '>' ); 320 } 321 state = leaveElementState(); 324 state.afterElement = true; 325 state.afterComment = false; 326 state.empty = false; 327 if ( isDocumentState() ) 328 printer.flush(); 329 } 330 331 332 336 337 public void startElement( String tagName, AttributeList attrs ) 338 throws SAXException 339 { 340 int i; 341 boolean preserveSpace; 342 ElementState state; 343 String name; 344 String value; 345 346 try { 347 if ( printer == null ) 348 throw new IllegalStateException ( "SER002 No writer supplied for serializer" ); 349 350 state = getElementState(); 351 if ( isDocumentState() ) { 352 if ( ! started ) 357 startDocument( tagName ); 358 } else { 359 if ( state.empty ) 363 printer.printText( '>' ); 364 if ( state.inCData ) 366 { 367 printer.printText( "]]>" ); 368 state.inCData = false; 369 } 370 if ( indenting && ! state.preserveSpace && 374 ( state.empty || state.afterElement || state.afterComment) ) 375 printer.breakLine(); 376 } 377 preserveSpace = state.preserveSpace; 378 379 382 printer.printText( '<' ); 383 printer.printText( tagName ); 384 printer.indent(); 385 386 if ( attrs != null ) { 390 for ( i = 0 ; i < attrs.getLength() ; ++i ) { 391 printer.printSpace(); 392 name = attrs.getName( i ); 393 value = attrs.getValue( i ); 394 if ( value != null ) { 395 printer.printText( name ); 396 printer.printText( "=\"" ); 397 printEscaped( value ); 398 printer.printText( '"' ); 399 } 400 401 if ( name.equals( "xml:space" ) ) { 405 if ( value.equals( "preserve" ) ) 406 preserveSpace = true; 407 else 408 preserveSpace = format.getPreserveSpace(); 409 } 410 } 411 } 412 state = enterElementState( null, null, tagName, preserveSpace ); 416 state.doCData = format.isCDataElement( tagName ); 417 state.unescaped = format.isNonEscapingElement( tagName ); 418 } catch ( IOException except ) { 419 throw new SAXException ( except ); 420 } 421 422 } 423 424 425 public void endElement( String tagName ) 426 throws SAXException 427 { 428 endElement( null, null, tagName ); 429 } 430 431 432 433 437 438 450 protected void startDocument( String rootTagName ) 451 throws IOException 452 { 453 int i; 454 String dtd; 455 456 dtd = printer.leaveDTD(); 457 if ( ! started ) { 458 459 if ( ! format.getOmitXMLDeclaration() ) { 460 StringBuffer buffer; 461 462 buffer = new StringBuffer ( "<?xml version=\"" ); 465 if ( format.getVersion() != null ) 466 buffer.append( format.getVersion() ); 467 else 468 buffer.append( "1.0" ); 469 buffer.append( '"' ); 470 if ( format.getEncoding() != null ) { 471 buffer.append( " encoding=\"" ); 472 buffer.append( format.getEncoding() ); 473 buffer.append( '"' ); 474 } 475 if ( format.getStandalone() && docTypeSystemId == null && 476 docTypePublicId == null ) 477 buffer.append( " standalone=\"yes\"" ); 478 buffer.append( "?>" ); 479 printer.printText( buffer ); 480 printer.breakLine(); 481 } 482 483 if ( ! format.getOmitDocumentType() ) { 484 if ( docTypeSystemId != null ) { 485 printer.printText( "<!DOCTYPE " ); 489 printer.printText( rootTagName ); 490 if ( docTypePublicId != null ) { 491 printer.printText( " PUBLIC " ); 492 printDoctypeURL( docTypePublicId ); 493 if ( indenting ) { 494 printer.breakLine(); 495 for ( i = 0 ; i < 18 + rootTagName.length() ; ++i ) 496 printer.printText( " " ); 497 } else 498 printer.printText( " " ); 499 printDoctypeURL( docTypeSystemId ); 500 } 501 else { 502 printer.printText( " SYSTEM " ); 503 printDoctypeURL( docTypeSystemId ); 504 } 505 506 if ( dtd != null && dtd.length() > 0 ) { 509 printer.printText( " [" ); 510 printText( dtd, true, true ); 511 printer.printText( ']' ); 512 } 513 514 printer.printText( ">" ); 515 printer.breakLine(); 516 } else if ( dtd != null && dtd.length() > 0 ) { 517 printer.printText( "<!DOCTYPE " ); 518 printer.printText( rootTagName ); 519 printer.printText( " [" ); 520 printText( dtd, true, true ); 521 printer.printText( "]>" ); 522 printer.breakLine(); 523 } 524 } 525 } 526 started = true; 527 serializePreRoot(); 529 } 530 531 532 537 protected void serializeElement( Element elem ) 538 throws IOException 539 { 540 Attr attr; 541 NamedNodeMap attrMap; 542 int i; 543 Node child; 544 ElementState state; 545 boolean preserveSpace; 546 String name; 547 String value; 548 String tagName; 549 550 tagName = elem.getTagName(); 551 state = getElementState(); 552 if ( isDocumentState() ) { 553 if ( ! started ) 558 startDocument( tagName ); 559 } else { 560 if ( state.empty ) 564 printer.printText( '>' ); 565 if ( state.inCData ) 567 { 568 printer.printText( "]]>" ); 569 state.inCData = false; 570 } 571 if ( indenting && ! state.preserveSpace && 575 ( state.empty || state.afterElement || state.afterComment) ) 576 printer.breakLine(); 577 } 578 preserveSpace = state.preserveSpace; 579 580 583 printer.printText( '<' ); 584 printer.printText( tagName ); 585 printer.indent(); 586 587 attrMap = elem.getAttributes(); 593 if ( attrMap != null ) { 594 for ( i = 0 ; i < attrMap.getLength() ; ++i ) { 595 attr = (Attr ) attrMap.item( i ); 596 name = attr.getName(); 597 value = attr.getValue(); 598 if ( value == null ) 599 value = ""; 600 if ( attr.getSpecified() ) { 601 printer.printSpace(); 602 printer.printText( name ); 603 printer.printText( "=\"" ); 604 printEscaped( value ); 605 printer.printText( '"' ); 606 } 607 if ( name.equals( "xml:space" ) ) { 611 if ( value.equals( "preserve" ) ) 612 preserveSpace = true; 613 else 614 preserveSpace = format.getPreserveSpace(); 615 } 616 } 617 } 618 619 if ( elem.hasChildNodes() ) { 622 state = enterElementState( null, null, tagName, preserveSpace ); 625 state.doCData = format.isCDataElement( tagName ); 626 state.unescaped = format.isNonEscapingElement( tagName ); 627 child = elem.getFirstChild(); 628 while ( child != null ) { 629 serializeNode( child ); 630 child = child.getNextSibling(); 631 } 632 endElementIO( null, null, tagName ); 633 } else { 634 printer.unindent(); 635 printer.printText( "/>" ); 636 state.afterElement = true; 638 state.afterComment = false; 639 state.empty = false; 640 if ( isDocumentState() ) 641 printer.flush(); 642 } 643 } 644 645 646 protected String getEntityRef( int ch ) 647 { 648 switch ( ch ) { 651 case '<': 652 return "lt"; 653 case '>': 654 return "gt"; 655 case '"': 656 return "quot"; 657 case '\'': 658 return "apos"; 659 case '&': 660 return "amp"; 661 } 662 return null; 663 } 664 665 666 669 private Attributes extractNamespaces( Attributes attrs ) 670 throws SAXException 671 { 672 AttributesImpl attrsOnly; 673 String rawName; 674 int i; 675 int length; 676 677 length = attrs.getLength(); 678 attrsOnly = new AttributesImpl ( attrs ); 679 680 for ( i = length - 1 ; i >= 0 ; --i ) { 681 rawName = attrsOnly.getQName( i ); 682 683 if ( rawName.startsWith( "xmlns" ) ) { 687 if (rawName.length() == 5) { 688 startPrefixMapping( "", attrs.getValue( i ) ); 689 attrsOnly.removeAttribute( i ); 690 } else if (rawName.charAt(5) == ':') { 691 startPrefixMapping(rawName.substring(6), attrs.getValue(i)); 692 attrsOnly.removeAttribute( i ); 693 } 694 } 695 } 696 return attrsOnly; 697 } 698 } 699 | Popular Tags |