Clover coverage report - dom4j - 1.5
Coverage timestamp: vr sep 3 2004 20:47:03 GMT+01:00
file stats: LOC: 756   Methods: 48
NCLOC: 449   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
SAXWriter.java 65,5% 60,5% 64,6% 62,2%
coverage coverage
 1    /*
 2    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
 3    *
 4    * This software is open source.
 5    * See the bottom of this file for the licence.
 6    *
 7    * $Id: SAXWriter.java,v 1.22 2004/06/25 12:34:47 maartenc Exp $
 8    */
 9   
 10    package org.dom4j.io;
 11   
 12    import java.io.IOException;
 13    import java.util.HashMap;
 14    import java.util.Iterator;
 15    import java.util.List;
 16    import java.util.Map;
 17   
 18    import org.dom4j.Attribute;
 19    import org.dom4j.Branch;
 20    import org.dom4j.CDATA;
 21    import org.dom4j.CharacterData;
 22    import org.dom4j.Comment;
 23    import org.dom4j.Document;
 24    import org.dom4j.DocumentType;
 25    import org.dom4j.Element;
 26    import org.dom4j.Entity;
 27    import org.dom4j.Namespace;
 28    import org.dom4j.Node;
 29    import org.dom4j.ProcessingInstruction;
 30    import org.dom4j.Text;
 31    import org.dom4j.tree.NamespaceStack;
 32    import org.xml.sax.Attributes;
 33    import org.xml.sax.ContentHandler;
 34    import org.xml.sax.DTDHandler;
 35    import org.xml.sax.EntityResolver;
 36    import org.xml.sax.ErrorHandler;
 37    import org.xml.sax.InputSource;
 38    import org.xml.sax.SAXException;
 39    import org.xml.sax.SAXNotRecognizedException;
 40    import org.xml.sax.SAXNotSupportedException;
 41    import org.xml.sax.XMLReader;
 42    import org.xml.sax.ext.LexicalHandler;
 43    import org.xml.sax.helpers.AttributesImpl;
 44    import org.xml.sax.helpers.LocatorImpl;
 45   
 46    /** <p><code>SAXWriter</code> writes a DOM4J tree to a SAX ContentHandler.</p>
 47    *
 48    * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
 49    * @version $Revision: 1.22 $
 50    */
 51    public class SAXWriter implements XMLReader {
 52   
 53    protected static final String[] LEXICAL_HANDLER_NAMES = {
 54    "http://xml.org/sax/properties/lexical-handler",
 55    "http://xml.org/sax/handlers/LexicalHandler"
 56    };
 57   
 58    protected static String FEATURE_NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes";
 59    protected static String FEATURE_NAMESPACES = "http://xml.org/sax/features/namespaces";
 60   
 61    /** <code>ContentHandler</code> to which SAX events are raised */
 62    private ContentHandler contentHandler;
 63   
 64    /** code>DTDHandler</code> fired when a document has a DTD */
 65    private DTDHandler dtdHandler;
 66   
 67    /** code>EntityResolver</code> fired when a document has a DTD */
 68    private EntityResolver entityResolver;
 69   
 70    private ErrorHandler errorHandler;
 71   
 72    /** code>LexicalHandler</code> fired on Entity and CDATA sections */
 73    private LexicalHandler lexicalHandler;
 74   
 75    /** code>AttributesImpl</code> used when generating the Attributes */
 76    private AttributesImpl attributes = new AttributesImpl();
 77   
 78    /** Stores the features */
 79    private Map features = new HashMap();
 80   
 81    /** Stores the properties */
 82    private Map properties = new HashMap();
 83   
 84    /** Whether namespace declarations are exported as attributes or not */
 85    private boolean declareNamespaceAttributes;
 86   
 87   
 88  40 public SAXWriter() {
 89  40 properties.put( FEATURE_NAMESPACE_PREFIXES, Boolean.FALSE );
 90  40 properties.put( FEATURE_NAMESPACE_PREFIXES, Boolean.TRUE );
 91    }
 92   
 93  0 public SAXWriter(ContentHandler contentHandler) {
 94  0 this();
 95  0 this.contentHandler = contentHandler;
 96    }
 97   
 98  0 public SAXWriter(
 99    ContentHandler contentHandler,
 100    LexicalHandler lexicalHandler
 101    ) {
 102  0 this();
 103  0 this.contentHandler = contentHandler;
 104  0 this.lexicalHandler = lexicalHandler;
 105    }
 106   
 107  24 public SAXWriter(
 108    ContentHandler contentHandler,
 109    LexicalHandler lexicalHandler,
 110    EntityResolver entityResolver
 111    ) {
 112  24 this();
 113  24 this.contentHandler = contentHandler;
 114  24 this.lexicalHandler = lexicalHandler;
 115  24 this.entityResolver = entityResolver;
 116    }
 117   
 118   
 119    /**
 120    * A polymorphic method to write any Node to this SAX stream
 121    */
 122  0 public void write(Node node) throws SAXException {
 123  0 int nodeType = node.getNodeType();
 124  0 switch (nodeType) {
 125  0 case Node.ELEMENT_NODE:
 126  0 write((Element) node);
 127  0 break;
 128  0 case Node.ATTRIBUTE_NODE:
 129  0 write((Attribute) node);
 130  0 break;
 131  0 case Node.TEXT_NODE:
 132  0 write(node.getText());
 133  0 break;
 134  0 case Node.CDATA_SECTION_NODE:
 135  0 write((CDATA) node);
 136  0 break;
 137  0 case Node.ENTITY_REFERENCE_NODE:
 138  0 write((Entity) node);
 139  0 break;
 140  0 case Node.PROCESSING_INSTRUCTION_NODE:
 141  0 write((ProcessingInstruction) node);
 142  0 break;
 143  0 case Node.COMMENT_NODE:
 144  0 write((Comment) node);
 145  0 break;
 146  0 case Node.DOCUMENT_NODE:
 147  0 write((Document) node);
 148  0 break;
 149  0 case Node.DOCUMENT_TYPE_NODE:
 150  0 write((DocumentType) node);
 151  0 break;
 152  0 case Node.NAMESPACE_NODE:
 153    // Will be output with attributes
 154    //write((Namespace) node);
 155  0 break;
 156  0 default:
 157  0 throw new SAXException( "Invalid node type: " + node );
 158    }
 159    }
 160   
 161   
 162    /** Generates SAX events for the given Document and all its content
 163    *
 164    * @param document is the Document to parse
 165    * @throws SAXException if there is a SAX error processing the events
 166    */
 167  40 public void write(Document document) throws SAXException {
 168  40 if (document != null) {
 169  40 checkForNullHandlers();
 170   
 171  40 documentLocator(document);
 172  40 startDocument();
 173  40 entityResolver(document);
 174  40 dtdHandler(document);
 175   
 176  40 writeContent( document, new NamespaceStack() );
 177  40 endDocument();
 178    }
 179    }
 180   
 181   
 182   
 183    /** Generates SAX events for the given Element and all its content
 184    *
 185    * @param element is the Element to parse
 186    * @throws SAXException if there is a SAX error processing the events
 187    */
 188  0 public void write( Element element ) throws SAXException {
 189  0 write( element, new NamespaceStack() );
 190    }
 191   
 192   
 193    /** <p>Writes the opening tag of an {@link Element},
 194    * including its {@link Attribute}s
 195    * but without its content.</p>
 196    *
 197    * @param element <code>Element</code> to output.
 198    */
 199  0 public void writeOpen(Element element) throws SAXException {
 200  0 startElement(element, null);
 201    }
 202   
 203    /** <p>Writes the closing tag of an {@link Element}</p>
 204    *
 205    * @param element <code>Element</code> to output.
 206    */
 207  0 public void writeClose(Element element) throws SAXException {
 208  0 endElement(element);
 209    }
 210   
 211    /** Generates SAX events for the given text
 212    *
 213    * @param text is the text to send to the SAX ContentHandler
 214    * @throws SAXException if there is a SAX error processing the events
 215    */
 216  18832 public void write( String text ) throws SAXException {
 217  18832 if ( text != null ) {
 218  18832 char[] chars = text.toCharArray();
 219  18832 contentHandler.characters( chars, 0, chars.length );
 220    }
 221    }
 222   
 223    /** Generates SAX events for the given CDATA
 224    *
 225    * @param cdata is the CDATA to parse
 226    * @throws SAXException if there is a SAX error processing the events
 227    */
 228  60 public void write( CDATA cdata ) throws SAXException {
 229  60 String text = cdata.getText();
 230  60 if ( lexicalHandler != null ) {
 231  60 lexicalHandler.startCDATA();
 232  60 write( text );
 233  60 lexicalHandler.endCDATA();
 234    }
 235    else {
 236  0 write( text );
 237    }
 238    }
 239   
 240    /** Generates SAX events for the given Comment
 241    *
 242    * @param comment is the Comment to parse
 243    * @throws SAXException if there is a SAX error processing the events
 244    */
 245  142 public void write( Comment comment ) throws SAXException {
 246  142 if ( lexicalHandler != null ) {
 247  142 String text = comment.getText();
 248  142 char[] chars = text.toCharArray();
 249  142 lexicalHandler.comment( chars, 0, chars.length );
 250    }
 251    }
 252   
 253    /** Generates SAX events for the given Entity
 254    *
 255    * @param entity is the Entity to parse
 256    * @throws SAXException if there is a SAX error processing the events
 257    */
 258  0 public void write( Entity entity ) throws SAXException {
 259  0 String text = entity.getText();
 260  0 if ( lexicalHandler != null ) {
 261  0 String name = entity.getName();
 262  0 lexicalHandler.startEntity(name);
 263  0 write( text );
 264  0 lexicalHandler.endEntity(name);
 265    }
 266    else {
 267  0 write( text );
 268    }
 269    }
 270   
 271    /** Generates SAX events for the given ProcessingInstruction
 272    *
 273    * @param pi is the ProcessingInstruction to parse
 274    * @throws SAXException if there is a SAX error processing the events
 275    */
 276  4 public void write( ProcessingInstruction pi ) throws SAXException {
 277  4 String target = pi.getTarget();
 278  4 String text = pi.getText();
 279  4 contentHandler.processingInstruction(target, text);
 280    }
 281   
 282   
 283   
 284    /** Should namespace declarations be converted to "xmlns" attributes. This property
 285    * defaults to <code>false</code> as per the SAX specification.
 286    * This property is set via the SAX feature "http://xml.org/sax/features/namespace-prefixes"
 287    */
 288  0 public boolean isDeclareNamespaceAttributes() {
 289  0 return declareNamespaceAttributes;
 290    }
 291   
 292    /** Sets whether namespace declarations should be exported as "xmlns" attributes or not.
 293    * This property is set from the SAX feature "http://xml.org/sax/features/namespace-prefixes"
 294    */
 295  16 public void setDeclareNamespaceAttributes(boolean declareNamespaceAttributes) {
 296  16 this.declareNamespaceAttributes = declareNamespaceAttributes;
 297    }
 298   
 299   
 300   
 301    // XMLReader methods
 302    //-------------------------------------------------------------------------
 303   
 304    /** @return the <code>ContentHandler</code> called when SAX events
 305    * are raised
 306    */
 307  0 public ContentHandler getContentHandler() {
 308  0 return contentHandler;
 309    }
 310   
 311    /** Sets the <code>ContentHandler</code> called when SAX events
 312    * are raised
 313    *
 314    * @param contentHandler is the <code>ContentHandler</code> called when SAX events
 315    * are raised
 316    */
 317  16 public void setContentHandler(ContentHandler contentHandler) {
 318  16 this.contentHandler = contentHandler;
 319    }
 320   
 321   
 322    /** @return the <code>DTDHandler</code>
 323    */
 324  0 public DTDHandler getDTDHandler() {
 325  0 return dtdHandler;
 326    }
 327   
 328    /** Sets the <code>DTDHandler</code>.
 329    */
 330  16 public void setDTDHandler(DTDHandler dtdHandler) {
 331  16 this.dtdHandler = dtdHandler;
 332    }
 333   
 334    /** @return the <code>ErrorHandler</code>
 335    */
 336  2 public ErrorHandler getErrorHandler() {
 337  2 return errorHandler;
 338    }
 339   
 340    /** Sets the <code>ErrorHandler</code>.
 341    */
 342  2 public void setErrorHandler(ErrorHandler errorHandler) {
 343  2 this.errorHandler = errorHandler;
 344    }
 345   
 346    /** @return the <code>EntityResolver</code> used when a Document contains
 347    * a DTD
 348    */
 349  0 public EntityResolver getEntityResolver() {
 350  0 return entityResolver;
 351    }
 352   
 353    /** Sets the <code>EntityResolver</code> .
 354    *
 355    * @param entityResolver is the <code>EntityResolver</code>
 356    */
 357  0 public void setEntityResolver(EntityResolver entityResolver) {
 358  0 this.entityResolver = entityResolver;
 359    }
 360   
 361    /** @return the <code>LexicalHandler</code> used when a Document contains
 362    * a DTD
 363    */
 364  0 public LexicalHandler getLexicalHandler() {
 365  0 return lexicalHandler;
 366    }
 367   
 368    /** Sets the <code>LexicalHandler</code> .
 369    *
 370    * @param lexicalHandler is the <code>LexicalHandler</code>
 371    */
 372  30 public void setLexicalHandler(LexicalHandler lexicalHandler) {
 373  30 this.lexicalHandler = lexicalHandler;
 374    }
 375   
 376   
 377    /** Sets the <code>XMLReader</code> used to write SAX events to
 378    *
 379    * @param xmlReader is the <code>XMLReader</code>
 380    */
 381  0 public void setXMLReader(XMLReader xmlReader) {
 382  0 setContentHandler( xmlReader.getContentHandler() );
 383  0 setDTDHandler( xmlReader.getDTDHandler() );
 384  0 setEntityResolver( xmlReader.getEntityResolver() );
 385  0 setErrorHandler( xmlReader.getErrorHandler() );
 386    }
 387   
 388    /** Looks up the value of a feature.
 389    */
 390  0 public boolean getFeature(String name)
 391    throws SAXNotRecognizedException, SAXNotSupportedException {
 392  0 Boolean answer = (Boolean) features.get(name);
 393  0 return answer != null && answer.booleanValue();
 394    }
 395   
 396    /** This implementation does actually use any features but just
 397    * stores them for later retrieval
 398    */
 399  16 public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
 400  16 if ( FEATURE_NAMESPACE_PREFIXES.equals( name ) ) {
 401  16 setDeclareNamespaceAttributes( value );
 402    }
 403  0 else if ( FEATURE_NAMESPACE_PREFIXES.equals( name ) ) {
 404  0 if ( ! value ) {
 405  0 throw new SAXNotSupportedException(name + ". namespace feature is always supported in dom4j." );
 406    }
 407    }
 408  16 features.put(name, (value) ? Boolean.TRUE : Boolean.FALSE );
 409    }
 410   
 411    /** Sets the given SAX property
 412    */
 413  58 public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
 414  58 for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) {
 415  100 if (LEXICAL_HANDLER_NAMES[i].equals(name)) {
 416  30 setLexicalHandler((LexicalHandler) value);
 417  30 return;
 418    }
 419    }
 420  28 properties.put(name, value);
 421    }
 422   
 423    /** Gets the given SAX property
 424    */
 425  0 public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
 426  0 for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) {
 427  0 if (LEXICAL_HANDLER_NAMES[i].equals(name)) {
 428  0 return getLexicalHandler();
 429    }
 430    }
 431  0 return properties.get(name);
 432    }
 433   
 434   
 435   
 436   
 437    /** This method is not supported.
 438    */
 439  0 public void parse(String systemId) throws SAXNotSupportedException {
 440  0 throw new SAXNotSupportedException(
 441    "This XMLReader can only accept <dom4j> InputSource objects"
 442    );
 443    }
 444   
 445   
 446    /** Parses an XML document.
 447    * This method can only accept DocumentInputSource inputs
 448    * otherwise a {@link SAXNotSupportedException} exception is thrown.
 449    *
 450    * @throws SAXNotSupportedException
 451    * if the input source is not wrapping a dom4j document
 452    */
 453  16 public void parse(InputSource input) throws SAXException {
 454  16 if (input instanceof DocumentInputSource) {
 455  16 DocumentInputSource documentInput = (DocumentInputSource) input;
 456  16 Document document = documentInput.getDocument();
 457  16 write( document );
 458    }
 459    else {
 460  0 throw new SAXNotSupportedException(
 461    "This XMLReader can only accept <dom4j> InputSource objects"
 462    );
 463    }
 464    }
 465   
 466   
 467   
 468    // Implementation methods
 469    //-------------------------------------------------------------------------
 470   
 471  9946 protected void writeContent( Branch branch, NamespaceStack namespaceStack ) throws SAXException {
 472  9946 for ( Iterator iter = branch.nodeIterator(); iter.hasNext(); ) {
 473  28962 Object object = iter.next();
 474  28962 if ( object instanceof Element ) {
 475  9906 write( (Element) object, namespaceStack );
 476    }
 477  19056 else if ( object instanceof CharacterData ) {
 478  18974 if ( object instanceof Text ) {
 479  18772 Text text = (Text) object;
 480  18772 write( text.getText() );
 481    }
 482  202 else if ( object instanceof CDATA ) {
 483  60 write( (CDATA) object );
 484    }
 485  142 else if ( object instanceof Comment ) {
 486  142 write( (Comment) object );
 487    }
 488    else {
 489  0 throw new SAXException( "Invalid Node in DOM4J content: " + object + " of type: " + object.getClass() );
 490    }
 491    }
 492  82 else if ( object instanceof String ) {
 493  0 write( (String) object );
 494    }
 495  82 else if ( object instanceof Entity ) {
 496  0 write( (Entity) object );
 497    }
 498  82 else if ( object instanceof ProcessingInstruction ) {
 499  4 write( (ProcessingInstruction) object );
 500    }
 501  78 else if ( object instanceof Namespace ) {
 502    // namespaceStack are written via write of element
 503    }
 504    else {
 505  0 throw new SAXException( "Invalid Node in DOM4J content: " + object );
 506    }
 507    }
 508    }
 509   
 510    /** The {@link org.xml.sax.Locator} is only really useful when parsing a textual
 511    * document as its main purpose is to identify the line and column number.
 512    * Since we are processing an in memory tree which will probably have
 513    * its line number information removed, we'll just use -1 for the line
 514    * and column numbers.
 515    */
 516  40 protected void documentLocator(Document document) throws SAXException {
 517  40 LocatorImpl locator = new LocatorImpl();
 518   
 519  40 String publicID = null;
 520  40 String systemID = null;
 521  40 DocumentType docType = document.getDocType();
 522  40 if (docType != null) {
 523  0 publicID = docType.getPublicID();
 524  0 systemID = docType.getSystemID();
 525    }
 526  40 if ( publicID != null ) {
 527  0 locator.setPublicId(publicID);
 528    }
 529  40 if ( systemID != null ) {
 530  0 locator.setSystemId(systemID);
 531    }
 532   
 533  40 locator.setLineNumber(-1);
 534  40 locator.setColumnNumber(-1);
 535   
 536  40 contentHandler.setDocumentLocator( locator );
 537    }
 538   
 539  40 protected void entityResolver(Document document) throws SAXException {
 540  40 if (entityResolver != null) {
 541  24 DocumentType docType = document.getDocType();
 542  24 if (docType != null) {
 543  0 String publicID = docType.getPublicID();
 544  0 String systemID = docType.getSystemID();
 545   
 546  0 if ( publicID != null || systemID != null ) {
 547  0 try {
 548  0 entityResolver.resolveEntity( publicID, systemID );
 549    }
 550    catch (IOException e) {
 551  0 throw new SAXException(
 552    "Could not resolve entity publicID: "
 553    + publicID + " systemID: " + systemID, e
 554    );
 555    }
 556    }
 557    }
 558    }
 559    }
 560   
 561   
 562    /** We do not yet support DTD or XML Schemas so this method does nothing
 563    * right now.
 564    */
 565  40 protected void dtdHandler(Document document) throws SAXException {
 566    }
 567   
 568  40 protected void startDocument() throws SAXException {
 569  40 contentHandler.startDocument();
 570    }
 571   
 572  40 protected void endDocument() throws SAXException {
 573  40 contentHandler.endDocument();
 574    }
 575   
 576  9906 protected void write( Element element, NamespaceStack namespaceStack ) throws SAXException {
 577  9906 int stackSize = namespaceStack.size();
 578  9906 AttributesImpl namespaceAttributes = startPrefixMapping(element, namespaceStack);
 579  9906 startElement(element, namespaceAttributes);
 580  9906 writeContent(element, namespaceStack);
 581  9906 endElement(element);
 582  9906 endPrefixMapping(namespaceStack, stackSize);
 583    }
 584   
 585    /** Fires a SAX startPrefixMapping event for all the namespaceStack
 586    * which have just come into scope
 587    */
 588  9906 protected AttributesImpl startPrefixMapping( Element element, NamespaceStack namespaceStack ) throws SAXException {
 589  9906 AttributesImpl namespaceAttributes = null;
 590   
 591    // start with the namespace of the element
 592  9906 Namespace elementNamespace = element.getNamespace();
 593  9906 if ((elementNamespace != null) && !isIgnoreableNamespace(elementNamespace, namespaceStack)) {
 594  72 namespaceStack.push(elementNamespace);
 595  72 contentHandler.startPrefixMapping(
 596    elementNamespace.getPrefix(), elementNamespace.getURI());
 597  72 namespaceAttributes = addNamespaceAttribute(namespaceAttributes, elementNamespace);
 598    }
 599   
 600  9906 List declaredNamespaces = element.declaredNamespaces();
 601  9906 for ( int i = 0, size = declaredNamespaces.size(); i < size ; i++ ) {
 602  78 Namespace namespace = (Namespace) declaredNamespaces.get(i);
 603  78 if ( ! isIgnoreableNamespace( namespace, namespaceStack ) ) {
 604  6 namespaceStack.push( namespace );
 605  6 contentHandler.startPrefixMapping(
 606    namespace.getPrefix(), namespace.getURI()
 607    );
 608  6 namespaceAttributes = addNamespaceAttribute( namespaceAttributes, namespace );
 609    }
 610    }
 611  9906 return namespaceAttributes;
 612    }
 613   
 614    /** Fires a SAX endPrefixMapping event for all the namespaceStack which
 615    * have gone out of scope
 616    */
 617  9906 protected void endPrefixMapping( NamespaceStack namespaceStack, int stackSize ) throws SAXException {
 618  9906 while ( namespaceStack.size() > stackSize ) {
 619  78 Namespace namespace = namespaceStack.pop();
 620  78 if ( namespace != null ) {
 621  78 contentHandler.endPrefixMapping( namespace.getPrefix() );
 622    }
 623    }
 624    }
 625   
 626   
 627  9906 protected void startElement( Element element, AttributesImpl namespaceAttributes ) throws SAXException {
 628  9906 contentHandler.startElement(
 629    element.getNamespaceURI(),
 630    element.getName(),
 631    element.getQualifiedName(),
 632    createAttributes( element, namespaceAttributes )
 633    );
 634    }
 635   
 636  9906 protected void endElement( Element element ) throws SAXException {
 637  9906 contentHandler.endElement(
 638    element.getNamespaceURI(),
 639    element.getName(),
 640    element.getQualifiedName()
 641    );
 642    }
 643   
 644  9906 protected Attributes createAttributes( Element element, Attributes namespaceAttributes ) throws SAXException {
 645  9906 attributes.clear();
 646  9906 if ( namespaceAttributes != null ) {
 647  24 attributes.setAttributes( namespaceAttributes );
 648    }
 649   
 650  9906 for ( Iterator iter = element.attributeIterator(); iter.hasNext(); ) {
 651  5218 Attribute attribute = (Attribute) iter.next();
 652  5218 attributes.addAttribute(
 653    attribute.getNamespaceURI(),
 654    attribute.getName(),
 655    attribute.getQualifiedName(),
 656    "CDATA",
 657    attribute.getValue()
 658    );
 659    }
 660  9906 return attributes;
 661    }
 662   
 663    /** If isDelcareNamespaceAttributes() is enabled then this method will add the
 664    * given namespace declaration to the supplied attributes object, creating one if
 665    * it does not exist.
 666    */
 667  78 protected AttributesImpl addNamespaceAttribute( AttributesImpl namespaceAttributes, Namespace namespace ) {
 668  78 if ( declareNamespaceAttributes ) {
 669  26 if ( namespaceAttributes == null ) {
 670  24 namespaceAttributes = new AttributesImpl();
 671    }
 672  26 String prefix = namespace.getPrefix();
 673  26 String qualifiedName = "xmlns";
 674  26 if ( prefix != null && prefix.length() > 0 ) {
 675  16 qualifiedName = "xmlns:" + prefix;
 676    }
 677  26 String uri = "";
 678  26 String localName = prefix;
 679  26 String type = "CDATA";
 680  26 String value = namespace.getURI();
 681   
 682  26 namespaceAttributes.addAttribute( uri, localName, qualifiedName, type, value );
 683    }
 684  78 return namespaceAttributes;
 685    }
 686   
 687   
 688    /** @return true if the given namespace is an ignorable namespace
 689    * (such as Namespace.NO_NAMESPACE or Namespace.XML_NAMESPACE) or if the
 690    * namespace has already been declared in the current scope
 691    */
 692  9984 protected boolean isIgnoreableNamespace( Namespace namespace, NamespaceStack namespaceStack ) {
 693  9984 if ( namespace.equals( Namespace.NO_NAMESPACE ) || namespace.equals( Namespace.XML_NAMESPACE ) ) {
 694  9522 return true;
 695    }
 696  462 String uri = namespace.getURI();
 697  462 if ( uri == null || uri.length() <= 0 ) {
 698  0 return true;
 699    }
 700  462 return namespaceStack.contains( namespace );
 701    }
 702   
 703    /** Ensures non-null content handlers?
 704    */
 705  40 protected void checkForNullHandlers() {
 706    }
 707   
 708    }
 709   
 710   
 711   
 712   
 713    /*
 714    * Redistribution and use of this software and associated documentation
 715    * ("Software"), with or without modification, are permitted provided
 716    * that the following conditions are met:
 717    *
 718    * 1. Redistributions of source code must retain copyright
 719    * statements and notices. Redistributions must also contain a
 720    * copy of this document.
 721    *
 722    * 2. Redistributions in binary form must reproduce the
 723    * above copyright notice, this list of conditions and the
 724    * following disclaimer in the documentation and/or other
 725    * materials provided with the distribution.
 726    *
 727    * 3. The name "DOM4J" must not be used to endorse or promote
 728    * products derived from this Software without prior written
 729    * permission of MetaStuff, Ltd. For written permission,
 730    * please contact dom4j-info@metastuff.com.
 731    *
 732    * 4. Products derived from this Software may not be called "DOM4J"
 733    * nor may "DOM4J" appear in their names without prior written
 734    * permission of MetaStuff, Ltd. DOM4J is a registered
 735    * trademark of MetaStuff, Ltd.
 736    *
 737    * 5. Due credit should be given to the DOM4J Project -
 738    * http://www.dom4j.org
 739    *
 740    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
 741    * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 742    * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 743    * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 744    * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 745    * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 746    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 747    * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 748    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 749    * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 750    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 751    * OF THE POSSIBILITY OF SUCH DAMAGE.
 752    *
 753    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
 754    *
 755    * $Id: SAXWriter.java,v 1.22 2004/06/25 12:34:47 maartenc Exp $
 756    */