KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dom4j > io > SAXWriter


1 /*
2  * Copyright 2001-2005 (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
8 package org.dom4j.io;
9
10 import java.io.IOException JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.dom4j.Attribute;
17 import org.dom4j.Branch;
18 import org.dom4j.CDATA;
19 import org.dom4j.CharacterData;
20 import org.dom4j.Comment;
21 import org.dom4j.Document;
22 import org.dom4j.DocumentType;
23 import org.dom4j.Element;
24 import org.dom4j.Entity;
25 import org.dom4j.Namespace;
26 import org.dom4j.Node;
27 import org.dom4j.ProcessingInstruction;
28 import org.dom4j.Text;
29 import org.dom4j.tree.NamespaceStack;
30
31 import org.xml.sax.Attributes JavaDoc;
32 import org.xml.sax.ContentHandler JavaDoc;
33 import org.xml.sax.DTDHandler JavaDoc;
34 import org.xml.sax.EntityResolver JavaDoc;
35 import org.xml.sax.ErrorHandler JavaDoc;
36 import org.xml.sax.InputSource JavaDoc;
37 import org.xml.sax.SAXException JavaDoc;
38 import org.xml.sax.SAXNotRecognizedException JavaDoc;
39 import org.xml.sax.SAXNotSupportedException JavaDoc;
40 import org.xml.sax.XMLReader JavaDoc;
41 import org.xml.sax.ext.LexicalHandler JavaDoc;
42 import org.xml.sax.helpers.AttributesImpl JavaDoc;
43 import org.xml.sax.helpers.LocatorImpl JavaDoc;
44
45 /**
46  * <p>
47  * <code>SAXWriter</code> writes a DOM4J tree to a SAX ContentHandler.
48  * </p>
49  *
50  * @author <a HREF="mailto:james.strachan@metastuff.com">James Strachan </a>
51  * @version $Revision: 1.24 $
52  */

53 public class SAXWriter implements XMLReader JavaDoc {
54     protected static final String JavaDoc[] LEXICAL_HANDLER_NAMES = {
55             "http://xml.org/sax/properties/lexical-handler",
56             "http://xml.org/sax/handlers/LexicalHandler" };
57
58     protected static final String JavaDoc FEATURE_NAMESPACE_PREFIXES
59             = "http://xml.org/sax/features/namespace-prefixes";
60
61     protected static final String JavaDoc FEATURE_NAMESPACES
62             = "http://xml.org/sax/features/namespaces";
63
64     /** <code>ContentHandler</code> to which SAX events are raised */
65     private ContentHandler JavaDoc contentHandler;
66
67     /** <code>DTDHandler</code> fired when a document has a DTD */
68     private DTDHandler JavaDoc dtdHandler;
69
70     /** <code>EntityResolver</code> fired when a document has a DTD */
71     private EntityResolver JavaDoc entityResolver;
72
73     private ErrorHandler JavaDoc errorHandler;
74
75     /** <code>LexicalHandler</code> fired on Entity and CDATA sections */
76     private LexicalHandler JavaDoc lexicalHandler;
77
78     /** <code>AttributesImpl</code> used when generating the Attributes */
79     private AttributesImpl JavaDoc attributes = new AttributesImpl JavaDoc();
80
81     /** Stores the features */
82     private Map JavaDoc features = new HashMap JavaDoc();
83
84     /** Stores the properties */
85     private Map JavaDoc properties = new HashMap JavaDoc();
86
87     /** Whether namespace declarations are exported as attributes or not */
88     private boolean declareNamespaceAttributes;
89
90     public SAXWriter() {
91         properties.put(FEATURE_NAMESPACE_PREFIXES, Boolean.FALSE);
92         properties.put(FEATURE_NAMESPACE_PREFIXES, Boolean.TRUE);
93     }
94
95     public SAXWriter(ContentHandler JavaDoc contentHandler) {
96         this();
97         this.contentHandler = contentHandler;
98     }
99
100     public SAXWriter(ContentHandler JavaDoc contentHandler,
101             LexicalHandler JavaDoc lexicalHandler) {
102         this();
103         this.contentHandler = contentHandler;
104         this.lexicalHandler = lexicalHandler;
105     }
106
107     public SAXWriter(ContentHandler JavaDoc contentHandler,
108             LexicalHandler JavaDoc lexicalHandler, EntityResolver JavaDoc entityResolver) {
109         this();
110         this.contentHandler = contentHandler;
111         this.lexicalHandler = lexicalHandler;
112         this.entityResolver = entityResolver;
113     }
114
115     /**
116      * A polymorphic method to write any Node to this SAX stream
117      *
118      * @param node
119      * DOCUMENT ME!
120      *
121      * @throws SAXException
122      * DOCUMENT ME!
123      */

124     public void write(Node node) throws SAXException JavaDoc {
125         int nodeType = node.getNodeType();
126
127         switch (nodeType) {
128             case Node.ELEMENT_NODE:
129                 write((Element) node);
130
131                 break;
132
133             case Node.ATTRIBUTE_NODE:
134                 write((Attribute) node);
135
136                 break;
137
138             case Node.TEXT_NODE:
139                 write(node.getText());
140
141                 break;
142
143             case Node.CDATA_SECTION_NODE:
144                 write((CDATA) node);
145
146                 break;
147
148             case Node.ENTITY_REFERENCE_NODE:
149                 write((Entity) node);
150
151                 break;
152
153             case Node.PROCESSING_INSTRUCTION_NODE:
154                 write((ProcessingInstruction) node);
155
156                 break;
157
158             case Node.COMMENT_NODE:
159                 write((Comment) node);
160
161                 break;
162
163             case Node.DOCUMENT_NODE:
164                 write((Document) node);
165
166                 break;
167
168             case Node.DOCUMENT_TYPE_NODE:
169                 write((DocumentType) node);
170
171                 break;
172
173             case Node.NAMESPACE_NODE:
174
175                 // Will be output with attributes
176
// write((Namespace) node);
177
break;
178
179             default:
180                 throw new SAXException JavaDoc("Invalid node type: " + node);
181         }
182     }
183
184     /**
185      * Generates SAX events for the given Document and all its content
186      *
187      * @param document
188      * is the Document to parse
189      *
190      * @throws SAXException
191      * if there is a SAX error processing the events
192      */

193     public void write(Document document) throws SAXException JavaDoc {
194         if (document != null) {
195             checkForNullHandlers();
196
197             documentLocator(document);
198             startDocument();
199             entityResolver(document);
200             dtdHandler(document);
201
202             writeContent(document, new NamespaceStack());
203             endDocument();
204         }
205     }
206
207     /**
208      * Generates SAX events for the given Element and all its content
209      *
210      * @param element
211      * is the Element to parse
212      *
213      * @throws SAXException
214      * if there is a SAX error processing the events
215      */

216     public void write(Element element) throws SAXException JavaDoc {
217         write(element, new NamespaceStack());
218     }
219
220     /**
221      * <p>
222      * Writes the opening tag of an {@link Element}, including its {@link
223      * Attribute}s but without its content.
224      * </p>
225      *
226      * @param element
227      * <code>Element</code> to output.
228      *
229      * @throws SAXException
230      * DOCUMENT ME!
231      */

232     public void writeOpen(Element element) throws SAXException JavaDoc {
233         startElement(element, null);
234     }
235
236     /**
237      * <p>
238      * Writes the closing tag of an {@link Element}
239      * </p>
240      *
241      * @param element
242      * <code>Element</code> to output.
243      *
244      * @throws SAXException
245      * DOCUMENT ME!
246      */

247     public void writeClose(Element element) throws SAXException JavaDoc {
248         endElement(element);
249     }
250
251     /**
252      * Generates SAX events for the given text
253      *
254      * @param text
255      * is the text to send to the SAX ContentHandler
256      *
257      * @throws SAXException
258      * if there is a SAX error processing the events
259      */

260     public void write(String JavaDoc text) throws SAXException JavaDoc {
261         if (text != null) {
262             char[] chars = text.toCharArray();
263             contentHandler.characters(chars, 0, chars.length);
264         }
265     }
266
267     /**
268      * Generates SAX events for the given CDATA
269      *
270      * @param cdata
271      * is the CDATA to parse
272      *
273      * @throws SAXException
274      * if there is a SAX error processing the events
275      */

276     public void write(CDATA cdata) throws SAXException JavaDoc {
277         String JavaDoc text = cdata.getText();
278
279         if (lexicalHandler != null) {
280             lexicalHandler.startCDATA();
281             write(text);
282             lexicalHandler.endCDATA();
283         } else {
284             write(text);
285         }
286     }
287
288     /**
289      * Generates SAX events for the given Comment
290      *
291      * @param comment
292      * is the Comment to parse
293      *
294      * @throws SAXException
295      * if there is a SAX error processing the events
296      */

297     public void write(Comment comment) throws SAXException JavaDoc {
298         if (lexicalHandler != null) {
299             String JavaDoc text = comment.getText();
300             char[] chars = text.toCharArray();
301             lexicalHandler.comment(chars, 0, chars.length);
302         }
303     }
304
305     /**
306      * Generates SAX events for the given Entity
307      *
308      * @param entity
309      * is the Entity to parse
310      *
311      * @throws SAXException
312      * if there is a SAX error processing the events
313      */

314     public void write(Entity entity) throws SAXException JavaDoc {
315         String JavaDoc text = entity.getText();
316
317         if (lexicalHandler != null) {
318             String JavaDoc name = entity.getName();
319             lexicalHandler.startEntity(name);
320             write(text);
321             lexicalHandler.endEntity(name);
322         } else {
323             write(text);
324         }
325     }
326
327     /**
328      * Generates SAX events for the given ProcessingInstruction
329      *
330      * @param pi
331      * is the ProcessingInstruction to parse
332      *
333      * @throws SAXException
334      * if there is a SAX error processing the events
335      */

336     public void write(ProcessingInstruction pi) throws SAXException JavaDoc {
337         String JavaDoc target = pi.getTarget();
338         String JavaDoc text = pi.getText();
339         contentHandler.processingInstruction(target, text);
340     }
341
342     /**
343      * Should namespace declarations be converted to "xmlns" attributes. This
344      * property defaults to <code>false</code> as per the SAX specification.
345      * This property is set via the SAX feature
346      * "http://xml.org/sax/features/namespace-prefixes"
347      *
348      * @return DOCUMENT ME!
349      */

350     public boolean isDeclareNamespaceAttributes() {
351         return declareNamespaceAttributes;
352     }
353
354     /**
355      * Sets whether namespace declarations should be exported as "xmlns"
356      * attributes or not. This property is set from the SAX feature
357      * "http://xml.org/sax/features/namespace-prefixes"
358      *
359      * @param declareNamespaceAttrs
360      * DOCUMENT ME!
361      */

362     public void setDeclareNamespaceAttributes(boolean declareNamespaceAttrs) {
363         this.declareNamespaceAttributes = declareNamespaceAttrs;
364     }
365
366     // XMLReader methods
367
// -------------------------------------------------------------------------
368

369     /**
370      * DOCUMENT ME!
371      *
372      * @return the <code>ContentHandler</code> called when SAX events are
373      * raised
374      */

375     public ContentHandler JavaDoc getContentHandler() {
376         return contentHandler;
377     }
378
379     /**
380      * Sets the <code>ContentHandler</code> called when SAX events are raised
381      *
382      * @param contentHandler
383      * is the <code>ContentHandler</code> called when SAX events
384      * are raised
385      */

386     public void setContentHandler(ContentHandler JavaDoc contentHandler) {
387         this.contentHandler = contentHandler;
388     }
389
390     /**
391      * DOCUMENT ME!
392      *
393      * @return the <code>DTDHandler</code>
394      */

395     public DTDHandler JavaDoc getDTDHandler() {
396         return dtdHandler;
397     }
398
399     /**
400      * Sets the <code>DTDHandler</code>.
401      *
402      * @param handler
403      * DOCUMENT ME!
404      */

405     public void setDTDHandler(DTDHandler JavaDoc handler) {
406         this.dtdHandler = handler;
407     }
408
409     /**
410      * DOCUMENT ME!
411      *
412      * @return the <code>ErrorHandler</code>
413      */

414     public ErrorHandler JavaDoc getErrorHandler() {
415         return errorHandler;
416     }
417
418     /**
419      * Sets the <code>ErrorHandler</code>.
420      *
421      * @param errorHandler
422      * DOCUMENT ME!
423      */

424     public void setErrorHandler(ErrorHandler JavaDoc errorHandler) {
425         this.errorHandler = errorHandler;
426     }
427
428     /**
429      * DOCUMENT ME!
430      *
431      * @return the <code>EntityResolver</code> used when a Document contains a
432      * DTD
433      */

434     public EntityResolver JavaDoc getEntityResolver() {
435         return entityResolver;
436     }
437
438     /**
439      * Sets the <code>EntityResolver</code>.
440      *
441      * @param entityResolver
442      * is the <code>EntityResolver</code>
443      */

444     public void setEntityResolver(EntityResolver JavaDoc entityResolver) {
445         this.entityResolver = entityResolver;
446     }
447
448     /**
449      * DOCUMENT ME!
450      *
451      * @return the <code>LexicalHandler</code> used when a Document contains a
452      * DTD
453      */

454     public LexicalHandler JavaDoc getLexicalHandler() {
455         return lexicalHandler;
456     }
457
458     /**
459      * Sets the <code>LexicalHandler</code>.
460      *
461      * @param lexicalHandler
462      * is the <code>LexicalHandler</code>
463      */

464     public void setLexicalHandler(LexicalHandler JavaDoc lexicalHandler) {
465         this.lexicalHandler = lexicalHandler;
466     }
467
468     /**
469      * Sets the <code>XMLReader</code> used to write SAX events to
470      *
471      * @param xmlReader
472      * is the <code>XMLReader</code>
473      */

474     public void setXMLReader(XMLReader JavaDoc xmlReader) {
475         setContentHandler(xmlReader.getContentHandler());
476         setDTDHandler(xmlReader.getDTDHandler());
477         setEntityResolver(xmlReader.getEntityResolver());
478         setErrorHandler(xmlReader.getErrorHandler());
479     }
480
481     /**
482      * Looks up the value of a feature.
483      *
484      * @param name
485      * DOCUMENT ME!
486      *
487      * @return DOCUMENT ME!
488      *
489      * @throws SAXNotRecognizedException
490      * DOCUMENT ME!
491      * @throws SAXNotSupportedException
492      * DOCUMENT ME!
493      */

494     public boolean getFeature(String JavaDoc name) throws SAXNotRecognizedException JavaDoc,
495             SAXNotSupportedException JavaDoc {
496         Boolean JavaDoc answer = (Boolean JavaDoc) features.get(name);
497
498         return (answer != null) && answer.booleanValue();
499     }
500
501     /**
502      * This implementation does actually use any features but just stores them
503      * for later retrieval
504      *
505      * @param name
506      * DOCUMENT ME!
507      * @param value
508      * DOCUMENT ME!
509      *
510      * @throws SAXNotRecognizedException
511      * DOCUMENT ME!
512      * @throws SAXNotSupportedException
513      * DOCUMENT ME!
514      */

515     public void setFeature(String JavaDoc name, boolean value)
516             throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
517         if (FEATURE_NAMESPACE_PREFIXES.equals(name)) {
518             setDeclareNamespaceAttributes(value);
519         } else if (FEATURE_NAMESPACE_PREFIXES.equals(name)) {
520             if (!value) {
521                 String JavaDoc msg = "Namespace feature is always supported in dom4j";
522                 throw new SAXNotSupportedException JavaDoc(msg);
523             }
524         }
525
526         features.put(name, (value) ? Boolean.TRUE : Boolean.FALSE);
527     }
528
529     /**
530      * Sets the given SAX property
531      *
532      * @param name
533      * DOCUMENT ME!
534      * @param value
535      * DOCUMENT ME!
536      */

537     public void setProperty(String JavaDoc name, Object JavaDoc value) {
538         for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) {
539             if (LEXICAL_HANDLER_NAMES[i].equals(name)) {
540                 setLexicalHandler((LexicalHandler JavaDoc) value);
541
542                 return;
543             }
544         }
545
546         properties.put(name, value);
547     }
548
549     /**
550      * Gets the given SAX property
551      *
552      * @param name
553      * DOCUMENT ME!
554      *
555      * @return DOCUMENT ME!
556      *
557      * @throws SAXNotRecognizedException
558      * DOCUMENT ME!
559      * @throws SAXNotSupportedException
560      * DOCUMENT ME!
561      */

562     public Object JavaDoc getProperty(String JavaDoc name) throws SAXNotRecognizedException JavaDoc,
563             SAXNotSupportedException JavaDoc {
564         for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) {
565             if (LEXICAL_HANDLER_NAMES[i].equals(name)) {
566                 return getLexicalHandler();
567             }
568         }
569
570         return properties.get(name);
571     }
572
573     /**
574      * This method is not supported.
575      *
576      * @param systemId
577      * DOCUMENT ME!
578      *
579      * @throws SAXNotSupportedException
580      * DOCUMENT ME!
581      */

582     public void parse(String JavaDoc systemId) throws SAXNotSupportedException JavaDoc {
583         throw new SAXNotSupportedException JavaDoc("This XMLReader can only accept"
584                 + " <dom4j> InputSource objects");
585     }
586
587     /**
588      * Parses an XML document. This method can only accept DocumentInputSource
589      * inputs otherwise a {@link SAXNotSupportedException}exception is thrown.
590      *
591      * @param input
592      * DOCUMENT ME!
593      *
594      * @throws SAXException
595      * DOCUMENT ME!
596      * @throws SAXNotSupportedException
597      * if the input source is not wrapping a dom4j document
598      */

599     public void parse(InputSource JavaDoc input) throws SAXException JavaDoc {
600         if (input instanceof DocumentInputSource) {
601             DocumentInputSource documentInput = (DocumentInputSource) input;
602             Document document = documentInput.getDocument();
603             write(document);
604         } else {
605             throw new SAXNotSupportedException JavaDoc(
606                     "This XMLReader can only accept "
607                             + "<dom4j> InputSource objects");
608         }
609     }
610
611     // Implementation methods
612
// -------------------------------------------------------------------------
613
protected void writeContent(Branch branch, NamespaceStack namespaceStack)
614             throws SAXException JavaDoc {
615         for (Iterator JavaDoc iter = branch.nodeIterator(); iter.hasNext();) {
616             Object JavaDoc object = iter.next();
617
618             if (object instanceof Element) {
619                 write((Element) object, namespaceStack);
620             } else if (object instanceof CharacterData) {
621                 if (object instanceof Text) {
622                     Text text = (Text) object;
623                     write(text.getText());
624                 } else if (object instanceof CDATA) {
625                     write((CDATA) object);
626                 } else if (object instanceof Comment) {
627                     write((Comment) object);
628                 } else {
629                     throw new SAXException JavaDoc("Invalid Node in DOM4J content: "
630                             + object + " of type: " + object.getClass());
631                 }
632             } else if (object instanceof String JavaDoc) {
633                 write((String JavaDoc) object);
634             } else if (object instanceof Entity) {
635                 write((Entity) object);
636             } else if (object instanceof ProcessingInstruction) {
637                 write((ProcessingInstruction) object);
638             } else if (object instanceof Namespace) {
639                 write((Namespace) object);
640             } else {
641                 throw new SAXException JavaDoc("Invalid Node in DOM4J content: "
642                         + object);
643             }
644         }
645     }
646
647     /**
648      * The {@link org.xml.sax.Locator}is only really useful when parsing a
649      * textual document as its main purpose is to identify the line and column
650      * number. Since we are processing an in memory tree which will probably
651      * have its line number information removed, we'll just use -1 for the line
652      * and column numbers.
653      *
654      * @param document
655      * DOCUMENT ME!
656      *
657      * @throws SAXException
658      * DOCUMENT ME!
659      */

660     protected void documentLocator(Document document) throws SAXException JavaDoc {
661         LocatorImpl JavaDoc locator = new LocatorImpl JavaDoc();
662
663         String JavaDoc publicID = null;
664         String JavaDoc systemID = null;
665         DocumentType docType = document.getDocType();
666
667         if (docType != null) {
668             publicID = docType.getPublicID();
669             systemID = docType.getSystemID();
670         }
671
672         if (publicID != null) {
673             locator.setPublicId(publicID);
674         }
675
676         if (systemID != null) {
677             locator.setSystemId(systemID);
678         }
679
680         locator.setLineNumber(-1);
681         locator.setColumnNumber(-1);
682
683         contentHandler.setDocumentLocator(locator);
684     }
685
686     protected void entityResolver(Document document) throws SAXException JavaDoc {
687         if (entityResolver != null) {
688             DocumentType docType = document.getDocType();
689
690             if (docType != null) {
691                 String JavaDoc publicID = docType.getPublicID();
692                 String JavaDoc systemID = docType.getSystemID();
693
694                 if ((publicID != null) || (systemID != null)) {
695                     try {
696                         entityResolver.resolveEntity(publicID, systemID);
697                     } catch (IOException JavaDoc e) {
698                         throw new SAXException JavaDoc("Could not resolve publicID: "
699                                 + publicID + " systemID: " + systemID, e);
700                     }
701                 }
702             }
703         }
704     }
705
706     /**
707      * We do not yet support DTD or XML Schemas so this method does nothing
708      * right now.
709      *
710      * @param document
711      * DOCUMENT ME!
712      *
713      * @throws SAXException
714      * DOCUMENT ME!
715      */

716     protected void dtdHandler(Document document) throws SAXException JavaDoc {
717     }
718
719     protected void startDocument() throws SAXException JavaDoc {
720         contentHandler.startDocument();
721     }
722
723     protected void endDocument() throws SAXException JavaDoc {
724         contentHandler.endDocument();
725     }
726
727     protected void write(Element element, NamespaceStack namespaceStack)
728             throws SAXException JavaDoc {
729         int stackSize = namespaceStack.size();
730         AttributesImpl JavaDoc namespaceAttributes = startPrefixMapping(element,
731                 namespaceStack);
732         startElement(element, namespaceAttributes);
733         writeContent(element, namespaceStack);
734         endElement(element);
735         endPrefixMapping(namespaceStack, stackSize);
736     }
737
738     /**
739      * Fires a SAX startPrefixMapping event for all the namespaceStack which
740      * have just come into scope
741      *
742      * @param element
743      * DOCUMENT ME!
744      * @param namespaceStack
745      * DOCUMENT ME!
746      *
747      * @return DOCUMENT ME!
748      *
749      * @throws SAXException
750      * DOCUMENT ME!
751      */

752     protected AttributesImpl JavaDoc startPrefixMapping(Element element,
753             NamespaceStack namespaceStack) throws SAXException JavaDoc {
754         AttributesImpl JavaDoc namespaceAttributes = null;
755
756         // start with the namespace of the element
757
Namespace elementNamespace = element.getNamespace();
758
759         if ((elementNamespace != null)
760                 && !isIgnoreableNamespace(elementNamespace, namespaceStack)) {
761             namespaceStack.push(elementNamespace);
762             contentHandler.startPrefixMapping(elementNamespace.getPrefix(),
763                     elementNamespace.getURI());
764             namespaceAttributes = addNamespaceAttribute(namespaceAttributes,
765                     elementNamespace);
766         }
767
768         List JavaDoc declaredNamespaces = element.declaredNamespaces();
769
770         for (int i = 0, size = declaredNamespaces.size(); i < size; i++) {
771             Namespace namespace = (Namespace) declaredNamespaces.get(i);
772
773             if (!isIgnoreableNamespace(namespace, namespaceStack)) {
774                 namespaceStack.push(namespace);
775                 contentHandler.startPrefixMapping(namespace.getPrefix(),
776                         namespace.getURI());
777                 namespaceAttributes = addNamespaceAttribute(
778                         namespaceAttributes, namespace);
779             }
780         }
781
782         return namespaceAttributes;
783     }
784
785     /**
786      * Fires a SAX endPrefixMapping event for all the namespaceStack which have
787      * gone out of scope
788      *
789      * @param stack
790      * DOCUMENT ME!
791      * @param stackSize
792      * DOCUMENT ME!
793      *
794      * @throws SAXException
795      * DOCUMENT ME!
796      */

797     protected void endPrefixMapping(NamespaceStack stack, int stackSize)
798             throws SAXException JavaDoc {
799         while (stack.size() > stackSize) {
800             Namespace namespace = stack.pop();
801
802             if (namespace != null) {
803                 contentHandler.endPrefixMapping(namespace.getPrefix());
804             }
805         }
806     }
807
808     protected void startElement(Element element,
809             AttributesImpl JavaDoc namespaceAttributes) throws SAXException JavaDoc {
810         contentHandler.startElement(element.getNamespaceURI(), element
811                 .getName(), element.getQualifiedName(), createAttributes(
812                 element, namespaceAttributes));
813     }
814
815     protected void endElement(Element element) throws SAXException JavaDoc {
816         contentHandler.endElement(element.getNamespaceURI(), element.getName(),
817                 element.getQualifiedName());
818     }
819
820     protected Attributes JavaDoc createAttributes(Element element,
821             Attributes JavaDoc namespaceAttributes) throws SAXException JavaDoc {
822         attributes.clear();
823
824         if (namespaceAttributes != null) {
825             attributes.setAttributes(namespaceAttributes);
826         }
827
828         for (Iterator JavaDoc iter = element.attributeIterator(); iter.hasNext();) {
829             Attribute attribute = (Attribute) iter.next();
830             attributes.addAttribute(attribute.getNamespaceURI(), attribute
831                     .getName(), attribute.getQualifiedName(), "CDATA",
832                     attribute.getValue());
833         }
834
835         return attributes;
836     }
837
838     /**
839      * If isDelcareNamespaceAttributes() is enabled then this method will add
840      * the given namespace declaration to the supplied attributes object,
841      * creating one if it does not exist.
842      *
843      * @param attrs
844      * DOCUMENT ME!
845      * @param namespace
846      * DOCUMENT ME!
847      *
848      * @return DOCUMENT ME!
849      */

850     protected AttributesImpl JavaDoc addNamespaceAttribute(AttributesImpl JavaDoc attrs,
851             Namespace namespace) {
852         if (declareNamespaceAttributes) {
853             if (attrs == null) {
854                 attrs = new AttributesImpl JavaDoc();
855             }
856
857             String JavaDoc prefix = namespace.getPrefix();
858             String JavaDoc qualifiedName = "xmlns";
859
860             if ((prefix != null) && (prefix.length() > 0)) {
861                 qualifiedName = "xmlns:" + prefix;
862             }
863
864             String JavaDoc uri = "";
865             String JavaDoc localName = prefix;
866             String JavaDoc type = "CDATA";
867             String JavaDoc value = namespace.getURI();
868
869             attrs.addAttribute(uri, localName, qualifiedName, type, value);
870         }
871
872         return attrs;
873     }
874
875     /**
876      * DOCUMENT ME!
877      *
878      * @param namespace
879      * DOCUMENT ME!
880      * @param namespaceStack
881      * DOCUMENT ME!
882      *
883      * @return true if the given namespace is an ignorable namespace (such as
884      * Namespace.NO_NAMESPACE or Namespace.XML_NAMESPACE) or if the
885      * namespace has already been declared in the current scope
886      */

887     protected boolean isIgnoreableNamespace(Namespace namespace,
888             NamespaceStack namespaceStack) {
889         if (namespace.equals(Namespace.NO_NAMESPACE)
890                 || namespace.equals(Namespace.XML_NAMESPACE)) {
891             return true;
892         }
893
894         String JavaDoc uri = namespace.getURI();
895
896         if ((uri == null) || (uri.length() <= 0)) {
897             return true;
898         }
899
900         return namespaceStack.contains(namespace);
901     }
902
903     /**
904      * Ensures non-null content handlers?
905      */

906     protected void checkForNullHandlers() {
907     }
908 }
909
910 /*
911  * Redistribution and use of this software and associated documentation
912  * ("Software"), with or without modification, are permitted provided that the
913  * following conditions are met:
914  *
915  * 1. Redistributions of source code must retain copyright statements and
916  * notices. Redistributions must also contain a copy of this document.
917  *
918  * 2. Redistributions in binary form must reproduce the above copyright notice,
919  * this list of conditions and the following disclaimer in the documentation
920  * and/or other materials provided with the distribution.
921  *
922  * 3. The name "DOM4J" must not be used to endorse or promote products derived
923  * from this Software without prior written permission of MetaStuff, Ltd. For
924  * written permission, please contact dom4j-info@metastuff.com.
925  *
926  * 4. Products derived from this Software may not be called "DOM4J" nor may
927  * "DOM4J" appear in their names without prior written permission of MetaStuff,
928  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
929  *
930  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
931  *
932  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
933  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
934  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
935  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
936  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
937  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
938  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
939  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
940  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
941  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
942  * POSSIBILITY OF SUCH DAMAGE.
943  *
944  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
945  */

946
Popular Tags