Source Code Cross Referenced for XMLWriter.java in  » XML » xom » nu » xom » tests » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xom » nu.xom.tests 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // XMLWriter.java - serialize an XML document.
0002:        // Written by David Megginson, david@megginson.com
0003:        // NO WARRANTY!  This class is in the public domain.
0004:
0005:        package nu.xom.tests;
0006:
0007:        import java.io.IOException;
0008:        import java.io.OutputStreamWriter;
0009:        import java.io.Writer;
0010:        import java.util.Enumeration;
0011:        import java.util.Hashtable;
0012:
0013:        import org.xml.sax.Attributes;
0014:        import org.xml.sax.SAXException;
0015:        import org.xml.sax.ext.LexicalHandler;
0016:        import org.xml.sax.helpers.AttributesImpl;
0017:        import org.xml.sax.helpers.NamespaceSupport;
0018:        import org.xml.sax.helpers.XMLFilterImpl;
0019:
0020:        /**
0021:         * <p>
0022:         *   The original version of this class was written and placed in the
0023:         *   public domain by David Megginson. Elliotte Rusty Harold added 
0024:         *   <code>LexicalHandler</code> support. It is included here purely
0025:         *   for help with testing the <code>SAXConverter</code> class. It is 
0026:         *   not part of the XOM API; nor is it used internally by XOM anywhere
0027:         *   except in the <code>SAXConverter</code> tests.
0028:         * </p>
0029:         * 
0030:         * <p>
0031:         *   This class does not properly preserve additional namespace
0032:         *   declarations in non-root elements. If you encounter that, the 
0033:         *   bug is here, not in <code>SAXConverter</code>.
0034:         * </p>
0035:         *
0036:         * @author David Megginson, Elliotte Rusty Harold
0037:         * @version 1.0
0038:         */
0039:        class XMLWriter extends XMLFilterImpl implements  LexicalHandler {
0040:
0041:            ///////////////////////////////////////////////////////////////////
0042:            // Constructors.
0043:            ///////////////////////////////////////////////////////////////////
0044:
0045:            /**
0046:             * <p>
0047:             * Create a new XML writer.
0048:             * </p>
0049:             * 
0050:             * <p>Write to standard output.</p>
0051:             */
0052:            public XMLWriter() {
0053:                init(null);
0054:            }
0055:
0056:            /**
0057:             * <p>
0058:             * Create a new XML writer.
0059:             * </p>
0060:             * 
0061:             * <p>Write to the writer provided.</p>
0062:             *
0063:             * @param writer the output destination, or null to use standard
0064:             *        output
0065:             */
0066:            public XMLWriter(Writer writer) {
0067:                init(writer);
0068:            }
0069:
0070:            /**
0071:             * <p>
0072:             * Internal initialization method.
0073:             * </p>
0074:             * 
0075:             * <p>All of the public constructors invoke this method.
0076:             *
0077:             * @param writer the output destination, or null to use
0078:             *        standard output.
0079:             */
0080:            private void init(Writer writer) {
0081:                setOutput(writer);
0082:                nsSupport = new NamespaceSupport();
0083:                prefixTable = new Hashtable();
0084:                forcedDeclTable = new Hashtable();
0085:                doneDeclTable = new Hashtable();
0086:            }
0087:
0088:            ///////////////////////////////////////////////////////////////////
0089:            // Public methods.
0090:            ///////////////////////////////////////////////////////////////////
0091:
0092:            /**
0093:             * <p>
0094:             * Reset the writer.
0095:             * </p>
0096:             * 
0097:             * <p>This method is especially useful if the writer throws an
0098:             * exception before it is finished, and you want to reuse the
0099:             * writer for a new document.  It is usually a good idea to
0100:             * invoke {@link #flush flush} before resetting the writer,
0101:             * to make sure that no output is lost.</p>
0102:             *
0103:             * <p>This method is invoked automatically by the
0104:             * {@link #startDocument startDocument} method before writing
0105:             * a new document.</p>
0106:             *
0107:             * <p><strong>Note:</strong> this method will <em>not</em>
0108:             * clear the prefix or URI information in the writer or
0109:             * the selected output writer.</p>
0110:             *
0111:             * @see #flush
0112:             */
0113:            public void reset() {
0114:                elementLevel = 0;
0115:                prefixCounter = 0;
0116:                nsSupport.reset();
0117:            }
0118:
0119:            /**
0120:             * <p>
0121:             * Flush the output.
0122:             * </p>
0123:             * 
0124:             * <p>This method flushes the output stream.  It is especially useful
0125:             * when you need to make certain that the entire document has
0126:             * been written to output but do not want to close the output
0127:             * stream.</p>
0128:             *
0129:             * <p>This method is invoked automatically by the
0130:             * {@link #endDocument endDocument} method after writing a
0131:             * document.</p>
0132:             *
0133:             * @throws IOException
0134:             *
0135:             * @see #reset
0136:             * 
0137:             */
0138:            public void flush() throws IOException {
0139:                output.flush();
0140:            }
0141:
0142:            /**
0143:             * <p>
0144:             * Set a new output destination for the document.
0145:             * </p>
0146:             * 
0147:             * @param writer the output destination, or null to use
0148:             *        standard output
0149:             * 
0150:             * @return the current output writer
0151:             * 
0152:             * @see #flush
0153:             */
0154:            public void setOutput(Writer writer) {
0155:                if (writer == null) {
0156:                    output = new OutputStreamWriter(System.out);
0157:                } else {
0158:                    output = writer;
0159:                }
0160:            }
0161:
0162:            /**
0163:             * <p>
0164:             * Specify a preferred prefix for a namespace URI.
0165:             * </p>
0166:             * 
0167:             * <p>Note that this method does not actually force the namespace
0168:             * to be declared; to do that, use the {@link 
0169:             * #forceNSDecl(java.lang.String) forceNSDecl} method as well.</p>
0170:             *
0171:             * @param uri the namespace URI
0172:             * @param prefix the preferred prefix, or "" to select
0173:             *        the default namespace
0174:             * 
0175:             * @see #getPrefix
0176:             * @see #forceNSDecl(java.lang.String)
0177:             * @see #forceNSDecl(java.lang.String,java.lang.String)
0178:             */
0179:            public void setPrefix(String uri, String prefix) {
0180:                prefixTable.put(uri, prefix);
0181:            }
0182:
0183:            /**
0184:             * <p>
0185:             * Get the current or preferred prefix for a namespace URI.
0186:             * </p>
0187:             * 
0188:             * @param uri the namespace URI
0189:             * 
0190:             * @return the preferred prefix, or "" for the default namespace
0191:             * 
0192:             * @see #setPrefix
0193:             */
0194:            public String getPrefix(String uri) {
0195:                return (String) prefixTable.get(uri);
0196:            }
0197:
0198:            public void startPrefixMapping(String prefix, String uri) {
0199:                this .forceNSDecl(uri, prefix);
0200:            }
0201:
0202:            /**
0203:             * <p>
0204:             * Force a namespace to be declared on the root element.
0205:             * </p>
0206:             * 
0207:             * <p>By default, the XMLWriter will declare only the namespaces
0208:             * needed for an element; as a result, a namespace may be
0209:             * declared many places in a document if it is not used on the
0210:             * root element.</p>
0211:             *
0212:             * <p>This method forces a namespace to be declared on the root
0213:             * element even if it is not used there, and reduces the number
0214:             * of xmlns attributes in the document.</p>
0215:             *
0216:             * @param uri the namespace URI to declare
0217:             * 
0218:             * @see #forceNSDecl(java.lang.String,java.lang.String)
0219:             * @see #setPrefix
0220:             */
0221:            public void forceNSDecl(String uri) {
0222:                forcedDeclTable.put(uri, Boolean.TRUE);
0223:            }
0224:
0225:            /**
0226:             * <p>
0227:             * Force a namespace declaration with a preferred prefix.
0228:             * </p>
0229:             * 
0230:             * <p>This is a convenience method that invokes {@link
0231:             * #setPrefix setPrefix} then {@link #forceNSDecl(java.lang.String)
0232:             * forceNSDecl}.</p>
0233:             *
0234:             * @param uri the namespace URI to declare on the root element
0235:             * @param prefix the preferred prefix for the namespace, or ""
0236:             *        for the default namespace
0237:             * 
0238:             * @see #setPrefix
0239:             * @see #forceNSDecl(java.lang.String)
0240:             */
0241:            public void forceNSDecl(String uri, String prefix) {
0242:                setPrefix(uri, prefix);
0243:                forceNSDecl(uri);
0244:            }
0245:
0246:            ///////////////////////////////////////////////////////////////////
0247:            // Methods from org.xml.sax.ContentHandler.
0248:            ///////////////////////////////////////////////////////////////////
0249:
0250:            /**
0251:             * <p>
0252:             * Write the XML declaration at the beginning of the document.
0253:             * </p>
0254:             * 
0255:             * <p>
0256:             * Pass the event on down the filter chain for further processing.
0257:             * </p>
0258:             * 
0259:             * @throws org.xml.sax.SAXException if there is an error
0260:             *            writing the XML declaration, or if a handler further 
0261:             *            down the filter chain raises an exception
0262:             * 
0263:             * @see org.xml.sax.ContentHandler#startDocument
0264:             */
0265:            public void startDocument() throws SAXException {
0266:                reset();
0267:                write("<?xml version=\"1.0\" standalone=\"yes\"?>\n\n");
0268:                super .startDocument();
0269:            }
0270:
0271:            /**
0272:             * <p>
0273:             * Write a newline at the end of the document.
0274:             * </p>
0275:             * 
0276:             * <p>
0277:             * Pass the event on down the filter chain for further processing.
0278:             * </p>
0279:             * 
0280:             * @throws org.xml.sax.SAXException if there is an error
0281:             *            writing the newline, or if a handler further down
0282:             *            the filter chain raises an exception
0283:             * 
0284:             * @see org.xml.sax.ContentHandler#endDocument
0285:             */
0286:            public void endDocument() throws SAXException {
0287:                write('\n');
0288:                super .endDocument();
0289:                try {
0290:                    flush();
0291:                } catch (IOException ex) {
0292:                    throw new SAXException(ex);
0293:                }
0294:            }
0295:
0296:            /**
0297:             * <p>
0298:             * Write a start-tag.
0299:             * </p>
0300:             * 
0301:             * <p>
0302:             * Pass the event on down the filter chain for further processing.
0303:             * </p>
0304:             * 
0305:             * @param uri the namespace URI, or the empty string if none
0306:             *        is available
0307:             * @param localName the element's local (unprefixed) name (required)
0308:             * @param qualifiedName the element's qualified (prefixed) name,
0309:             *        or the empty string is none is available.  This method 
0310:             *        will use the qualified name as a template for generating
0311:             *        a prefix if necessary, but it is not guaranteed to use 
0312:             *        the same qualified name.
0313:             * @param atts the element's attribute list (must not be null)
0314:             * 
0315:             * @throws org.xml.sax.SAXException if there is an error
0316:             *            writing the start-tag, or if a handler further down
0317:             *            the filter chain raises an exception
0318:             * 
0319:             * @see org.xml.sax.ContentHandler#startElement
0320:             */
0321:            public void startElement(String uri, String localName,
0322:                    String qualifiedName, Attributes atts) throws SAXException {
0323:                elementLevel++;
0324:                nsSupport.pushContext();
0325:                write('<');
0326:                writeName(uri, localName, qualifiedName, true);
0327:                writeAttributes(atts);
0328:                if (elementLevel == 1) {
0329:                    forceNSDecls();
0330:                }
0331:                writeNSDecls();
0332:                write('>');
0333:                super .startElement(uri, localName, qualifiedName, atts);
0334:            }
0335:
0336:            /**
0337:             * <p>
0338:             * Write an end-tag.
0339:             * </p>
0340:             * 
0341:             * <p>
0342:             * Pass the event on down the filter chain for further processing.
0343:             * </p>
0344:             * 
0345:             * @param uri the namespace URI, or the empty string if none
0346:             *        is available
0347:             * @param localName the element's local (unprefixed) name (required)
0348:             * @param qualifiedName the element's qualified (prefixed) name, or the
0349:             *        empty string is none is available.  This method will
0350:             *        use the qName as a template for generating a prefix
0351:             *        if necessary, but it is not guaranteed to use the
0352:             *        same qualified name.
0353:             * 
0354:             * @throws org.xml.sax.SAXException if there is an error
0355:             *            writing the end-tag, or if a handler further down
0356:             *            the filter chain raises an exception
0357:             * 
0358:             * @see org.xml.sax.ContentHandler#endElement
0359:             */
0360:            public void endElement(String uri, String localName,
0361:                    String qualifiedName) throws SAXException {
0362:                write("</");
0363:                writeName(uri, localName, qualifiedName, true);
0364:                write('>');
0365:                if (elementLevel == 1) {
0366:                    write('\n');
0367:                }
0368:                super .endElement(uri, localName, qualifiedName);
0369:                nsSupport.popContext();
0370:                elementLevel--;
0371:            }
0372:
0373:            /**
0374:             * <p>
0375:             * Write character data.
0376:             * </p>
0377:             * 
0378:             * <p>
0379:             * Pass the event on down the filter chain for further processing.
0380:             * </p>
0381:             * 
0382:             * @param ch the array of characters to write
0383:             * @param start the starting position in the array
0384:             * @param length the number of characters to write
0385:             * 
0386:             * @throws org.xml.sax.SAXException if there is an error
0387:             *            writing the characters, or if a handler further down
0388:             *            the filter chain raises an exception
0389:             * 
0390:             * @see org.xml.sax.ContentHandler#characters
0391:             */
0392:            public void characters(char[] ch, int start, int length)
0393:                    throws SAXException {
0394:                writeEsc(ch, start, length, false);
0395:                super .characters(ch, start, length);
0396:            }
0397:
0398:            /**
0399:             * <p>
0400:             * Write ignorable whitespace.
0401:             * </p>
0402:             * 
0403:             * <p>
0404:             * Pass the event on down the filter chain for further processing.
0405:             * </p>
0406:             * 
0407:             * @param ch the array of characters to write
0408:             * @param start the starting position in the array
0409:             * @param length the number of characters to write
0410:             * 
0411:             * @throws org.xml.sax.SAXException if there is an error
0412:             *            writing the whitespace, or if a handler further down
0413:             *            the filter chain raises an exception
0414:             * 
0415:             * @see org.xml.sax.ContentHandler#ignorableWhitespace
0416:             */
0417:            public void ignorableWhitespace(char[] ch, int start, int length)
0418:                    throws SAXException {
0419:                writeEsc(ch, start, length, false);
0420:                super .ignorableWhitespace(ch, start, length);
0421:            }
0422:
0423:            /**
0424:             * <p>
0425:             * Write a processing instruction.
0426:             * </p>
0427:             * 
0428:             * <p>
0429:             * Pass the event on down the filter chain for further processing.
0430:             * </p>
0431:             * 
0432:             * @param target the processing instruction target
0433:             * @param data the processing instruction data
0434:             * 
0435:             * @throws org.xml.sax.SAXException if there is an error
0436:             *            writing the PI, or if a handler further down
0437:             *            the filter chain raises an exception
0438:             * 
0439:             * @see org.xml.sax.ContentHandler#processingInstruction
0440:             */
0441:            public void processingInstruction(String target, String data)
0442:                    throws SAXException {
0443:                write("<?");
0444:                write(target);
0445:                write(' ');
0446:                write(data);
0447:                write("?>");
0448:                if (elementLevel < 1) {
0449:                    write('\n');
0450:                }
0451:                super .processingInstruction(target, data);
0452:            }
0453:
0454:            ///////////////////////////////////////////////////////////////////
0455:            // Additional markup.
0456:            ///////////////////////////////////////////////////////////////////
0457:
0458:            /**
0459:             * <p>
0460:             * Write an empty element.
0461:             * </p>
0462:             * 
0463:             * <p>
0464:             * This method writes an empty-element tag rather than a start-tag
0465:             * followed by an end-tag.  Both a {@link #startElement
0466:             * startElement} and an {@link #endElement endElement} event will
0467:             * be passed on down the filter chain.
0468:             * </p>
0469:             *
0470:             * @param uri the element's namespace URI, or the empty string
0471:             *        if the element has no namespace or if namespace
0472:             *        processing is not being performed
0473:             * @param localName the element's local name (without prefix).  This
0474:             *        parameter must be provided.
0475:             * @param qualifiedName the element's qualified name (with prefix), or
0476:             *        the empty string if none is available.  This parameter
0477:             *        is strictly advisory: the writer may or may not use
0478:             *        the prefix attached.
0479:             * @param atts the element's attribute list
0480:             * 
0481:             * @throws org.xml.sax.SAXException if there is an error
0482:             *            writing the empty tag, or if a handler further down
0483:             *            the filter chain raises an exception
0484:             * 
0485:             * @see #startElement
0486:             * @see #endElement 
0487:             */
0488:            public void emptyElement(String uri, String localName,
0489:                    String qualifiedName, Attributes atts) throws SAXException {
0490:                nsSupport.pushContext();
0491:                write('<');
0492:                writeName(uri, localName, qualifiedName, true);
0493:                writeAttributes(atts);
0494:                if (elementLevel == 1) {
0495:                    forceNSDecls();
0496:                }
0497:                writeNSDecls();
0498:                write("/>");
0499:                super .startElement(uri, localName, qualifiedName, atts);
0500:                super .endElement(uri, localName, qualifiedName);
0501:            }
0502:
0503:            ///////////////////////////////////////////////////////////////////
0504:            // Convenience methods.
0505:            ///////////////////////////////////////////////////////////////////
0506:
0507:            /**
0508:             * <p>
0509:             * Start a new element without a qualified name or attributes.
0510:             * </p>
0511:             * 
0512:             * <p>This method will provide a default empty attribute
0513:             * list and an empty string for the qualified name.  
0514:             * It invokes {@link 
0515:             * #startElement(String, String, String, Attributes)}
0516:             * directly.</p>
0517:             *
0518:             * @param uri the element's namespace URI
0519:             * @param localName the element's local name
0520:             * 
0521:             * @throws org.xml.sax.SAXException if there is an error
0522:             *            writing the start-tag, or if a handler further down
0523:             *            the filter chain raises an exception
0524:             * 
0525:             * @see #startElement(String, String, String, Attributes)
0526:             */
0527:            public void startElement(String uri, String localName)
0528:                    throws SAXException {
0529:                startElement(uri, localName, "", EMPTY_ATTS);
0530:            }
0531:
0532:            /**
0533:             * <p>
0534:             * Start a new element without a qualified name, 
0535:             * attributes or a namespace URI.</p>
0536:             *
0537:             * <p>This method will provide an empty string for the
0538:             * namespace URI, and empty string for the qualified name,
0539:             * and a default empty attribute list. It invokes
0540:             * #startElement(String, String, String, Attributes)}
0541:             * directly.</p>
0542:             *
0543:             * @param localName the element's local name
0544:             * 
0545:             * @throws org.xml.sax.SAXException if there is an error
0546:             *            writing the start-tag, or if a handler further down
0547:             *            the filter chain raises an exception
0548:             * 
0549:             * @see #startElement(String, String, String, Attributes)
0550:             */
0551:            public void startElement(String localName) throws SAXException {
0552:                startElement("", localName, "", EMPTY_ATTS);
0553:            }
0554:
0555:            /**
0556:             * <p>
0557:             * End an element without a qualfied name.
0558:             * </p>
0559:             * 
0560:             * <p>This method will supply an empty string for the qName.
0561:             * It invokes {@link #endElement(String, String, String)}
0562:             * directly.</p>
0563:             *
0564:             * @param uri the element's namespace URI
0565:             * @param localName the element's local name
0566:             * 
0567:             * @throws org.xml.sax.SAXException if there is an error
0568:             *            writing the end-tag, or if a handler further down
0569:             *            the filter chain raises an exception
0570:             * 
0571:             * @see #endElement(String, String, String)
0572:             */
0573:            public void endElement(String uri, String localName)
0574:                    throws SAXException {
0575:                endElement(uri, localName, "");
0576:            }
0577:
0578:            /**
0579:             * <p>
0580:             * End an element without a namespace URI or qualfiied name.
0581:             * </p>
0582:             * 
0583:             * <p>This method will supply an empty string for the qName
0584:             * and an empty string for the namespace URI.
0585:             * It invokes {@link #endElement(String, String, String)}
0586:             * directly.</p>
0587:             *
0588:             * @param localName the element's local name`
0589:             * 
0590:             * @throws org.xml.sax.SAXException if there is an error
0591:             *            writing the end-tag, or if a handler further down
0592:             *            the filter chain raises an exception
0593:             * 
0594:             * @see #endElement(String, String, String)
0595:             */
0596:            public void endElement(String localName) throws SAXException {
0597:                endElement("", localName, "");
0598:            }
0599:
0600:            /**
0601:             * <p>
0602:             * Add an empty element without a qualified name or attributes.
0603:             * </p>
0604:             * 
0605:             * <p>This method will supply an empty string for the qualified name
0606:             * and an empty attribute list.  It invokes
0607:             * {@link #emptyElement(String, String, String, Attributes)} 
0608:             * directly.</p>
0609:             *
0610:             * @param uri the element's namespace URI
0611:             * @param localName the element's local name
0612:             * 
0613:             * @throws org.xml.sax.SAXException if there is an error
0614:             *            writing the empty tag, or if a handler further down
0615:             *            the filter chain raises an exception
0616:             * 
0617:             * @see #emptyElement(String, String, String, Attributes)
0618:             */
0619:            public void emptyElement(String uri, String localName)
0620:                    throws SAXException {
0621:                emptyElement(uri, localName, "", EMPTY_ATTS);
0622:            }
0623:
0624:            /**
0625:             * <p>
0626:             * Add an empty element without a namespace URI, qualified
0627:             * name or attributes.
0628:             * </p>
0629:             * 
0630:             * <p>This method will supply an empty string for the qualified 
0631:             * name, and empty string for the namespace URI, and an empty
0632:             * attribute list.  It invokes
0633:             * {@link #emptyElement(String, String, String, Attributes)} 
0634:             * directly.</p>
0635:             *
0636:             * @param localName the element's local name
0637:             * 
0638:             * @throws org.xml.sax.SAXException if there is an error
0639:             *            writing the empty tag, or if a handler further down
0640:             *            the filter chain raises an exception
0641:             * 
0642:             * @see #emptyElement(String, String, String, Attributes)
0643:             */
0644:            public void emptyElement(String localName) throws SAXException {
0645:                emptyElement("", localName, "", EMPTY_ATTS);
0646:            }
0647:
0648:            /**
0649:             * <p>
0650:             * Write an element with character data content.
0651:             * </p>
0652:             * 
0653:             * <p>This is a convenience method to write a complete element
0654:             * with character data content, including the start-tag
0655:             * and end-tag.</p>
0656:             *
0657:             * <p>This method invokes
0658:             * {@link #startElement(String, String, String, Attributes)},
0659:             * followed by
0660:             * {@link #characters(String)}, followed by
0661:             * {@link #endElement(String, String, String)}.</p>
0662:             *
0663:             * @param uri the element's namespace URI
0664:             * @param localName the element's local name
0665:             * @param qualifiedName the element's default qualified name
0666:             * @param atts the element's attributes
0667:             * @param content the character data content
0668:             * 
0669:             * @throws org.xml.sax.SAXException if there is an error
0670:             *            writing the empty tag, or if a handler further down
0671:             *            the filter chain raises an exception
0672:             * 
0673:             * @see #startElement(String, String, String, Attributes)
0674:             * @see #characters(String)
0675:             * @see #endElement(String, String, String)
0676:             */
0677:            public void dataElement(String uri, String localName,
0678:                    String qualifiedName, Attributes atts, String content)
0679:                    throws SAXException {
0680:                startElement(uri, localName, qualifiedName, atts);
0681:                characters(content);
0682:                endElement(uri, localName, qualifiedName);
0683:            }
0684:
0685:            /**
0686:             * <p>
0687:             * Write an element with character data content but no attributes.
0688:             * </p>
0689:             * 
0690:             * <p>This is a convenience method to write a complete element
0691:             * with character data content, including the start-tag
0692:             * and end-tag.  This method provides an empty string
0693:             * for the qualified name and an empty attribute list.</p>
0694:             *
0695:             * <p>This method invokes
0696:             * {@link #startElement(String, String, String, Attributes)},
0697:             * followed by
0698:             * {@link #characters(String)}, followed by
0699:             * {@link #endElement(String, String, String)}.</p>
0700:             *
0701:             * @param uri the element's namespace URI
0702:             * @param localName the element's local name
0703:             * @param content the character data content
0704:             * 
0705:             * @throws org.xml.sax.SAXException if there is an error
0706:             *            writing the empty tag, or if a handler further down
0707:             *            the filter chain raises an exception
0708:             * 
0709:             * @see #startElement(String, String, String, Attributes)
0710:             * @see #characters(String)
0711:             * @see #endElement(String, String, String)
0712:             */
0713:            public void dataElement(String uri, String localName, String content)
0714:                    throws SAXException {
0715:                dataElement(uri, localName, "", EMPTY_ATTS, content);
0716:            }
0717:
0718:            /**
0719:             * <p>
0720:             * Write an element with character data content but no attributes 
0721:             * or namespace URI.
0722:             * </p>
0723:             * 
0724:             * <p>This is a convenience method to write a complete element
0725:             * with character data content, including the start-tag
0726:             * and end-tag.  The method provides an empty string for the
0727:             * namespace URI, and empty string for the qualified name,
0728:             * and an empty attribute list.</p>
0729:             *
0730:             * <p>This method invokes
0731:             * {@link #startElement(String, String, String, Attributes)},
0732:             * followed by
0733:             * {@link #characters(String)}, followed by
0734:             * {@link #endElement(String, String, String)}.</p>
0735:             *
0736:             * @param localName the element's local name
0737:             * @param content the character data content
0738:             * 
0739:             * @throws org.xml.sax.SAXException if there is an error
0740:             *            writing the empty tag, or if a handler further down
0741:             *            the filter chain raises an exception
0742:             * 
0743:             * @see #startElement(String, String, String, Attributes)
0744:             * @see #characters(String)
0745:             * @see #endElement(String, String, String)
0746:             */
0747:            public void dataElement(String localName, String content)
0748:                    throws SAXException {
0749:                dataElement("", localName, "", EMPTY_ATTS, content);
0750:            }
0751:
0752:            /**
0753:             * <p>
0754:             * Write a string of character data, with XML escaping.
0755:             * </p>
0756:             * 
0757:             * <p>This is a convenience method that takes an XML
0758:             * String, converts it to a character array, then invokes
0759:             * {@link #characters(char[], int, int)}.</p>
0760:             *
0761:             * @param data the character data
0762:             * @throws org.xml.sax.SAXException if there is an error
0763:             *            writing the string, or if a handler further down
0764:             *            the filter chain raises an exception
0765:             * @see #characters(char[], int, int)
0766:             */
0767:            public void characters(String data) throws SAXException {
0768:                char[] ch = data.toCharArray();
0769:                characters(ch, 0, ch.length);
0770:            }
0771:
0772:            ///////////////////////////////////////////////////////////////////
0773:            // Internal methods.
0774:            ///////////////////////////////////////////////////////////////////
0775:
0776:            /**
0777:             * <p>
0778:             * Force all namespaces to be declared.
0779:             * </p>
0780:             * 
0781:             * <p>
0782:             * This method is used on the root element to ensure that
0783:             * the predeclared namespaces all appear.
0784:             * </p>
0785:             */
0786:            private void forceNSDecls() {
0787:                Enumeration prefixes = forcedDeclTable.keys();
0788:                while (prefixes.hasMoreElements()) {
0789:                    String prefix = (String) prefixes.nextElement();
0790:                    doPrefix(prefix, null, true);
0791:                }
0792:            }
0793:
0794:            /**
0795:             * <p>
0796:             * Determine the prefix for an element or attribute name.
0797:             * </p>
0798:             * 
0799:             * TODO: this method probably needs some cleanup.
0800:             *
0801:             * @param uri the namespace URI
0802:             * @param qName the qualified name (optional); this will be used
0803:             *        to indicate the preferred prefix if none is currently
0804:             *        bound.
0805:             * @param isElement true if this is an element name, false
0806:             *        if it is an attribute name (which cannot use the
0807:             *        default namespace).
0808:             */
0809:            private String doPrefix(String uri, String qName, boolean isElement) {
0810:                String defaultNS = nsSupport.getURI("");
0811:                if ("".equals(uri)) {
0812:                    if (isElement && defaultNS != null)
0813:                        nsSupport.declarePrefix("", "");
0814:                    return null;
0815:                }
0816:                String prefix;
0817:                if (isElement && defaultNS != null && uri.equals(defaultNS)) {
0818:                    prefix = "";
0819:                } else {
0820:                    prefix = nsSupport.getPrefix(uri);
0821:                }
0822:                if (prefix != null) {
0823:                    return prefix;
0824:                }
0825:                prefix = (String) doneDeclTable.get(uri);
0826:                if (prefix != null
0827:                        && ((!isElement || defaultNS != null)
0828:                                && "".equals(prefix) || nsSupport
0829:                                .getURI(prefix) != null)) {
0830:                    prefix = null;
0831:                }
0832:                if (prefix == null) {
0833:                    prefix = (String) prefixTable.get(uri);
0834:                    if (prefix != null
0835:                            && ((!isElement || defaultNS != null)
0836:                                    && "".equals(prefix) || nsSupport
0837:                                    .getURI(prefix) != null)) {
0838:                        prefix = null;
0839:                    }
0840:                }
0841:                if (prefix == null && qName != null && !"".equals(qName)) {
0842:                    int i = qName.indexOf(':');
0843:                    if (i == -1) {
0844:                        if (isElement && defaultNS == null) {
0845:                            prefix = "";
0846:                        }
0847:                    } else {
0848:                        prefix = qName.substring(0, i);
0849:                    }
0850:                }
0851:                for (; prefix == null || nsSupport.getURI(prefix) != null; prefix = "__NS"
0852:                        + ++prefixCounter)
0853:                    ;
0854:                nsSupport.declarePrefix(prefix, uri);
0855:                doneDeclTable.put(uri, prefix);
0856:                return prefix;
0857:            }
0858:
0859:            /**
0860:             * <p>
0861:             * Write a raw character.
0862:             * </p>
0863:             * 
0864:             * @param c the character to write
0865:             * 
0866:             * @throws org.xml.sax.SAXException if there is an error writing
0867:             *            the character, this method will throw an IOException
0868:             *            wrapped in a SAXException
0869:             */
0870:            private void write(char c) throws SAXException {
0871:                try {
0872:                    output.write(c);
0873:                } catch (IOException ex) {
0874:                    throw new SAXException(ex);
0875:                }
0876:            }
0877:
0878:            /**
0879:             * <p>
0880:             * Write a raw string.
0881:             * </p>
0882:             * 
0883:             * @param s
0884:             * 
0885:             * @throws org.xml.sax.SAXException if there is an error writing
0886:             *            the string, this method will throw an IOException
0887:             *            wrapped in a SAXException
0888:             */
0889:            private void write(String s) throws SAXException {
0890:                try {
0891:                    output.write(s);
0892:                } catch (IOException e) {
0893:                    throw new SAXException(e);
0894:                }
0895:            }
0896:
0897:            /**
0898:             * <p>
0899:             * Write out an attribute list, escaping values.
0900:             *</p>
0901:             *
0902:             * <p>
0903:             * The names will have prefixes added to them.
0904:             * </p>
0905:             * 
0906:             * @param atts the attribute list to write
0907:             * 
0908:             * @throws org.xml.SAXException if there is an error writing
0909:             *            the attribute list, this method will throw an
0910:             *            IOException wrapped in a SAXException
0911:             */
0912:            private void writeAttributes(Attributes atts) throws SAXException {
0913:                int len = atts.getLength();
0914:                for (int i = 0; i < len; i++) {
0915:                    char[] ch = atts.getValue(i).toCharArray();
0916:                    write(' ');
0917:                    writeName(atts.getURI(i), atts.getLocalName(i), atts
0918:                            .getQName(i), false);
0919:                    write("=\"");
0920:                    writeEsc(ch, 0, ch.length, true);
0921:                    write('"');
0922:                }
0923:            }
0924:
0925:            /**
0926:             * <p>
0927:             * Write an array of data characters with escaping.
0928:             * </p>
0929:             * 
0930:             * @param ch the array of characters
0931:             * @param start the starting position
0932:             * @param length the number of characters to use
0933:             * @param isAttVal true if this is an attribute value literal
0934:             * 
0935:             * @throws org.xml.SAXException if there is an error writing
0936:             *            the characters, this method will throw an
0937:             *            IOException wrapped in a SAXException
0938:             */
0939:            private void writeEsc(char[] ch, int start, int length,
0940:                    boolean isAttVal) throws SAXException {
0941:                for (int i = start; i < start + length; i++) {
0942:                    switch (ch[i]) {
0943:                    case '&':
0944:                        write("&amp;");
0945:                        break;
0946:                    case '<':
0947:                        write("&lt;");
0948:                        break;
0949:                    case '>':
0950:                        write("&gt;");
0951:                        break;
0952:                    case '\"':
0953:                        if (isAttVal) {
0954:                            write("&quot;");
0955:                        } else {
0956:                            write('\"');
0957:                        }
0958:                        break;
0959:                    default:
0960:                        if (ch[i] > '\u007f') {
0961:                            write("&#");
0962:                            write(Integer.toString(ch[i]));
0963:                            write(';');
0964:                        } else {
0965:                            write(ch[i]);
0966:                        }
0967:                    }
0968:                }
0969:            }
0970:
0971:            /**
0972:             * <p>
0973:             * Write an array of data characters without escaping.
0974:             * </p>
0975:             * 
0976:             * @param ch the array of characters
0977:             * @param start the starting position
0978:             * @param length the number of characters to use
0979:             * 
0980:             * @throws org.xml.SAXException if there is an error writing
0981:             *            the characters, this method will throw an
0982:             *            IOException wrapped in a SAXException.
0983:             */
0984:            private void write(char[] ch, int start, int length)
0985:                    throws SAXException {
0986:
0987:                try {
0988:                    output.write(ch, start, length);
0989:                } catch (IOException e) {
0990:                    throw new SAXException(e);
0991:                }
0992:
0993:            }
0994:
0995:            /**
0996:             * <p>
0997:             * Write out the list of namespace declarations.
0998:             * </p>
0999:             * 
1000:             * @throws org.xml.sax.SAXException This method will throw
1001:             *            an IOException wrapped in a SAXException if
1002:             *            there is an error writing the namespace
1003:             *            declarations
1004:             */
1005:            private void writeNSDecls() throws SAXException {
1006:                Enumeration prefixes = nsSupport.getDeclaredPrefixes();
1007:                while (prefixes.hasMoreElements()) {
1008:                    String prefix = (String) prefixes.nextElement();
1009:                    String uri = nsSupport.getURI(prefix);
1010:                    if (uri == null) {
1011:                        uri = "";
1012:                    }
1013:                    char[] ch = uri.toCharArray();
1014:                    write(' ');
1015:                    if ("".equals(prefix)) {
1016:                        write("xmlns=\"");
1017:                    } else {
1018:                        write("xmlns:");
1019:                        write(prefix);
1020:                        write("=\"");
1021:                    }
1022:                    writeEsc(ch, 0, ch.length, true);
1023:                    write('\"');
1024:                }
1025:            }
1026:
1027:            /**
1028:             * <p>
1029:             * Write an element or attribute name.
1030:             * </p>
1031:             *
1032:             * @param uri the namespace URI
1033:             * @param localName the local name
1034:             * @param qualifiedName the prefixed name, if available, 
1035:             *        or the empty string.
1036:             * @param isElement true if this is an element name, false if it
1037:             *        is an attribute name
1038:             * 
1039:             * @throws org.xml.sax.SAXException this method will throw an
1040:             *            IOException wrapped in a SAXException if there is
1041:             *            an error writing the name
1042:             */
1043:            private void writeName(String uri, String localName,
1044:                    String qualifiedName, boolean isElement)
1045:                    throws SAXException {
1046:                String prefix = doPrefix(uri, qualifiedName, isElement);
1047:                if (prefix != null && !"".equals(prefix)) {
1048:                    write(prefix);
1049:                    write(':');
1050:                }
1051:                write(localName);
1052:            }
1053:
1054:            ////////////////////////////////////////////////////////////////////
1055:            // Constants.
1056:            ////////////////////////////////////////////////////////////////////
1057:
1058:            private final Attributes EMPTY_ATTS = new AttributesImpl();
1059:
1060:            ////////////////////////////////////////////////////////////////////
1061:            // Internal state.
1062:            ////////////////////////////////////////////////////////////////////
1063:
1064:            private Hashtable prefixTable;
1065:            private Hashtable forcedDeclTable;
1066:            private Hashtable doneDeclTable;
1067:            private int elementLevel = 0;
1068:            private Writer output;
1069:            private NamespaceSupport nsSupport;
1070:            private int prefixCounter = 0;
1071:
1072:            ///////////////////////////////////////////////////////////////////
1073:            // LexicalHandler methods.
1074:            ///////////////////////////////////////////////////////////////////
1075:
1076:            public void endCDATA() {
1077:            }
1078:
1079:            public void endDTD() throws SAXException {
1080:                write(">");
1081:            }
1082:
1083:            public void startCDATA() {
1084:            }
1085:
1086:            public void comment(char[] ch, int start, int length)
1087:                    throws SAXException {
1088:                write("<!--");
1089:                write(ch, start, length);
1090:                write("-->");
1091:                if (elementLevel < 1) {
1092:                    write('\n');
1093:                }
1094:            }
1095:
1096:            public void endEntity(String name) {
1097:            }
1098:
1099:            public void startEntity(String name) {
1100:            }
1101:
1102:            public void startDTD(String name, String publicID, String systemID)
1103:                    throws SAXException {
1104:                write("<!DOCTYPE ");
1105:                write(name);
1106:                if (systemID != null) {
1107:                    if (publicID != null) {
1108:                        write(" PUBLIC \"");
1109:                        write(publicID);
1110:                        write("\" \"");
1111:                        write(systemID);
1112:                        write("\"");
1113:                    } else {
1114:                        write(" SYSTEM \"");
1115:                        write(systemID);
1116:                        write("\"");
1117:                    }
1118:                }
1119:
1120:            }
1121:
1122:        }
1123:
1124:        // end of XMLWriter.java
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.