sandbox/src/net/sf/xframe/sax SimpleSAXWriter.java,NONE,1.1
Kurt Riede <[email protected]> Mon, 21 Mar 2005 18:13:24 +0000
| Newsgroups | gmane.text.xml.xframe.xsddoc.devel |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/xframe/sandbox/src/net/sf/xframe/sax In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27005/src/net/sf/xframe/sax Added Files: SimpleSAXWriter.java Log Message: initial upload of classes for working with XSModel classes of Apache XercesJ 2.6.2 --- NEW FILE: SimpleSAXWriter.java --- /* This file is part of the xframe software package hosted at http://xframe.sourceforge.net Copyright (c) 2003 Kurt Riede. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.xframe.sax; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.lang.reflect.Method; import net.sf.xframe.xs.parser.AttributesImpl; import org.xml.sax.Attributes; import org.xml.sax.ErrorHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.DefaultHandler; /** * A simple SAX2 writer. * * @author <a href="mailto:[email protected]">Kurt Riede</a> */ public final class SimpleSAXWriter extends DefaultHandler implements LexicalHandler { /** Print writer. */ private PrintWriter fOut = null; /** Encoding used for writing. */ private String fEncoding = "UTF-8"; /** Canonical output. */ private boolean fCanonical = true; /** Element depth. */ private int fElementDepth = 0; /** Document locator. */ private Locator fLocator = null; /** Processing XML 1.1 document. */ private boolean fXML11 = false; /** In CDATA section. */ private boolean fInCDATA = false; /** Reference to an error handler. */ private ErrorHandler errorHandler = new ConsoleErrorHandler(); /** Default constructor. */ public SimpleSAXWriter() { } /** * Constructor. * @param writer the output writer */ public SimpleSAXWriter(final Writer writer) { setOutput(writer); } /** * Constructor. * @param stream the output stream * @param encoding the output encoding * @throws UnsupportedEncodingException if the requested encoding is not supported */ public SimpleSAXWriter(final OutputStream stream, final String encoding) throws UnsupportedEncodingException { setOutput(stream, encoding); } /** * Sets whether output is canonical. * @param canonical if output shsould be canonical or not. */ public void setCanonical(final boolean canonical) { fCanonical = canonical; } /** * Sets the output stream for printing. * @param stream the output stream * @param encoding the output encoding * @throws UnsupportedEncodingException if the requested encoding is not supported */ public void setOutput(final OutputStream stream, final String encoding) throws UnsupportedEncodingException { final Writer writer = new OutputStreamWriter(stream, encoding == null ? "UTF8" : encoding); fOut = new PrintWriter(writer); fEncoding = encoding; } /** * Sets the output writer for printing. * @param writer the output writer */ public void setOutput(final Writer writer) { fOut = writer instanceof PrintWriter ? (PrintWriter) writer : new PrintWriter(writer); } /** * @see org.xml.sax.DefaultHandler#setDocumentLocator() */ public void setDocumentLocator(final Locator locator) { fLocator = locator; } /** * @see org.xml.sax.ContentHandler#startDocument() */ public void startDocument() throws SAXException { fElementDepth = 0; fXML11 = false; fInCDATA = false; } /** * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String) */ public void processingInstruction(final String target, final String data) throws SAXException { if (fElementDepth > 0) { fOut.print("<?"); fOut.print(target); if (data != null && data.length() > 0) { fOut.print(' '); fOut.print(data); } fOut.print("?>"); fOut.flush(); } } /** * @see org.xml.sax.ContentHandler#startElement(java.lang.String, * java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(final String uri, final String local, final String raw, final Attributes attrsUnsorted) throws SAXException { if (fElementDepth == 0) { if (fLocator != null) { fXML11 = "1.1".equals(getVersion()); fLocator = null; } if (!fCanonical) { if (fXML11) { fOut.println("<?xml version=\"1.1\" encoding=\"" + fEncoding + "\"?>"); } else { fOut.println("<?xml version=\"1.0\" encoding=\"" + fEncoding + "\"?>"); } fOut.flush(); } } fElementDepth++; fOut.print('<'); fOut.print(raw); if (attrsUnsorted != null) { final Attributes attrs = sortAttributes(attrsUnsorted); final int len = attrs.getLength(); for (int i = 0; i < len; i++) { fOut.print(' '); fOut.print(attrs.getQName(i)); fOut.print("=\""); normalizeAndPrint(attrs.getValue(i), true); fOut.print('"'); } } fOut.print('>'); fOut.flush(); } /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(final char[] ch, final int start, final int length) throws SAXException { if (!fInCDATA) { normalizeAndPrint(ch, start, length, false); } else { for (int i = 0; i < length; ++i) { fOut.print(ch[start + i]); } } fOut.flush(); } /** * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int) */ public void ignorableWhitespace(final char[] ch, final int start, final int length) throws SAXException { characters(ch, start, length); fOut.flush(); } /** * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ public void endElement(final String uri, final String local, final String raw) throws SAXException { fElementDepth--; fOut.print("</"); fOut.print(raw); fOut.print('>'); fOut.flush(); } /** * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) */ public void warning(final SAXParseException e) throws SAXException { errorHandler.warning(e); } /** * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) */ public void error(final SAXParseException e) throws SAXException { errorHandler.error(e); } /** * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) */ public void fatalError(final SAXParseException e) throws SAXException { errorHandler.fatalError(e); } /** * @see org.xml.sax.ext.LexicalHandler#startDTD() */ public void startDTD(final String name, final String publicId, final String systemId) throws SAXException { } /** * @see org.xml.sax.ext.LexicalHandler#endDTD() */ public void endDTD() throws SAXException { } /** * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String) */ public void startEntity(final String arg0) throws SAXException { } /** * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)() */ public void endEntity(final String name) throws SAXException { } /** * @see org.xml.sax.ext.LexicalHandler#startCDATA() */ public void startCDATA() throws SAXException { if (!fCanonical) { fOut.print("<![CDATA["); fInCDATA = true; } } /** * @throws SAXException s */ public void endCDATA() throws SAXException { if (!fCanonical) { fInCDATA = false; fOut.print("]]>"); } } /** * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int) */ public void comment(final char[] ch, final int start, final int length) throws SAXException { if (!fCanonical && fElementDepth > 0) { fOut.print("<!--"); for (int i = 0; i < length; ++i) { fOut.print(ch[start + i]); } fOut.print("-->"); fOut.flush(); } } /** Returns a sorted list of attributes. */ private Attributes sortAttributes(final Attributes attrs) { final AttributesImpl attributes = new AttributesImpl(); final int len = (attrs != null) ? attrs.getLength() : 0; for (int i = 0; i < len; i++) { final String name = attrs.getQName(i); final int count = attributes.getLength(); int j = 0; while (j < count) { if (name.compareTo(attributes.getQName(j)) < 0) { break; } j++; } attributes.insertAttributeAt(j, name, attrs.getType(i), attrs.getValue(i)); } return attributes; } /** Normalizes and prints the given string. */ private void normalizeAndPrint(final String s, final boolean isAttValue) { final int len = (s != null) ? s.length() : 0; for (int i = 0; i < len; i++) { normalizeAndPrint(s.charAt(i), isAttValue); } } /** Normalizes and prints the given array of characters. */ private void normalizeAndPrint(final char[] ch, final int offset, final int length, final boolean isAttValue) { for (int i = 0; i < length; i++) { normalizeAndPrint(ch[offset + i], isAttValue); } } /** Normalizes and print the given character. */ private void normalizeAndPrint(final char c, final boolean isAttValue) { switch (c) { case '<': fOut.print("<"); break; case '>': fOut.print(">"); break; case '&': fOut.print("&"); break; case '"': // A '"' that appears in character data // does not need to be escaped. if (isAttValue) { fOut.print("""); } else { fOut.print("\""); } break; case '\r': // If CR is part of the document's content, it // must not be printed as a literal otherwise // it would be normalized to LF when the document // is reparsed. fOut.print("
"); break; case '\n': if (fCanonical) { fOut.print("
"); break; } default: // In XML 1.1, control chars in the ranges [#x1-#x1F, #x7F-#x9F] must be escaped. // // Escape space characters that would be normalized to #x20 in // attribute values when the document is reparsed. // // Escape NEL (0x85) and LSEP (0x2028) that appear in content // if the document is XML 1.1, since they would be normalized to LF // when the document is reparsed. if (fXML11 && ((c >= ASCII.SOH && c <= ASCII.US && c != ASCII.TAB && c != ASCII.LF) || (c >= ASCII.DEL && c <= ASCII.OA) || c == ASCII.LSEP) || isAttValue && (c == ASCII.TAB || c == ASCII.LF)) { fOut.print("&#x"); fOut.print(Integer.toHexString(c).toUpperCase()); fOut.print(";"); } else { fOut.print(c); } } } /** * Some character constants that are relevant for proper encoding. */ private class ASCII { /** Start of heading. */ private static final char SOH = 0x01; /** Unit Seperator. */ private static final char US = 0x1F; /** Tabulator. */ private static final char TAB = 0x09; /** Line Feed. */ private static final char LF = 0x0A; /** Delete. */ private static final char DEL = 0x7F; /** small o with accent egu. */ private static final char OA = 0x9F; /** Unicode line seperator. */ private static final char LSEP = 0x2028; } /** * Console error handler (outputs all errors to the console error stream). */ private class ConsoleErrorHandler implements ErrorHandler { /** * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) */ public void warning(final SAXParseException e) throws SAXException { printError("Warning", e); } /** * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) */ public void error(final SAXParseException e) throws SAXException { printError("Error", e); } /** * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) */ public void fatalError(final SAXParseException e) throws SAXException { printError("Fatal Error", e); throw e; } /** Prints the error message. */ private void printError(final String type, final SAXParseException ex) { System.err.print("["); System.err.print(type); System.err.print("] "); String systemId = ex.getSystemId(); if (systemId != null) { int index = systemId.lastIndexOf('/'); if (index != -1) { systemId = systemId.substring(index + 1); } System.err.print(systemId); } System.err.print(':'); System.err.print(ex.getLineNumber()); System.err.print(':'); System.err.print(ex.getColumnNumber()); System.err.print(": "); System.err.print(ex.getMessage()); System.err.println(); System.err.flush(); } } /** Extracts the XML version from the Locator. */ private String getVersion() { if (fLocator == null) { return null; } try { final Method getXMLVersion = fLocator.getClass().getMethod("getXMLVersion", new Class[] {}); // If Locator implements Locator2, this method will exist. if (getXMLVersion != null) { return (String) getXMLVersion.invoke(fLocator, null); } } catch (Exception e) { return null; // Either this locator object doesn't have // this method, or we're on an old JDK. } return null; } } ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click