⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlwriter.java

📁 xmlrpc-2.0-src.zip java程序
💻 JAVA
字号:
/* * Copyright 1999,2005 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.xmlrpc;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import java.util.Properties;import java.util.Vector;import org.apache.xmlrpc.util.DateTool;import org.apache.commons.codec.binary.Base64;import org.apache.commons.codec.EncoderException;/** * A XML writer intended for single-thread usage.  If you feed it a * <code>ByteArrayInputStream</code>, it may be necessary to call * <code>writer.flush()</code> before calling * <code>buffer.toByteArray()</code> to get the data written to * your byte buffer. * * @author <a href="mailto:hannes@apache.org">Hannes Wallnoefer</a> * @author Daniel L. Rall * @see <a href="http://www.xml.com/axml/testaxml.htm">Tim Bray's * Annotated XML Spec</a> */class XmlWriter extends OutputStreamWriter{    // Various XML pieces.    protected static final String PROLOG_START = "<?xml version=\"1.0";    protected static final String PROLOG_END = "\"?>";    protected static final String CLOSING_TAG_START = "</";    protected static final String SINGLE_TAG_END = "/>";    protected static final String LESS_THAN_ENTITY = "&lt;";    protected static final String GREATER_THAN_ENTITY = "&gt;";    protected static final String AMPERSAND_ENTITY = "&amp;";    private static final char[] PROLOG =        new char[PROLOG_START.length() + PROLOG_END.length()];    static    {        int len = PROLOG_START.length();        PROLOG_START.getChars(0, len, PROLOG, 0);        PROLOG_END.getChars(0, PROLOG_END.length(), PROLOG, len);    }    /**     * Java's name for the ISO-8859-1 encoding.     */    static final String ISO8859_1 = "ISO8859_1";    /**     * Java's name for the UTF-8 encoding.     */    static final String UTF8 = "UTF8";    /**     * Java's name for the UTF-16 encoding.     */    static final String UTF16 = "UTF-16";        protected static final Base64 base64Codec = new Base64();    /**     * Class to delegate type decoding to.     */    protected static TypeDecoder typeDecoder;    /**     * Mapping between Java encoding names and "real" names used in     * XML prolog.     *     * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/intl/encoding.doc.html">Java character set names</a>     */    private static Properties encodings = new Properties();    static    {        encodings.put(UTF8, "UTF-8");        encodings.put(ISO8859_1, "ISO-8859-1");        typeDecoder = new DefaultTypeDecoder();    }    /**     * Thread-safe wrapper for the <code>DateFormat</code> object used     * to parse date/time values.     */    private static DateTool dateTool = new DateTool();    /**     * Whether the XML prolog has been written.     */    boolean hasWrittenProlog = false;    /**     * Creates a new instance.     *     * @param out The stream to write output to.     * @param enc The encoding to using for outputing XML.  Only UTF-8     * and UTF-16 are supported.  If another encoding is specified,     * UTF-8 will be used instead for widest XML parser     * interoperability.     * @exception UnsupportedEncodingException Since unsupported     * encodings are internally converted to UTF-8, this should only     * be seen as the result of an internal error.     */    public XmlWriter(OutputStream out, String enc)        throws UnsupportedEncodingException    {        // Super-class wants the Java form of the encoding.        super(out, forceUnicode(enc));    }    /**     * @param encoding A caller-specified encoding.     * @return An Unicode encoding.     */    private static String forceUnicode(String encoding)    {        if (encoding == null || !encoding.toUpperCase().startsWith("UTF"))        {            encoding = UTF8;        }        return encoding;    }    /**     * Tranforms a Java encoding to the canonical XML form (if a     * mapping is available).     *     * @param javaEncoding The name of the encoding as known by Java.     * @return The XML encoding (if a mapping is available);     * otherwise, the encoding as provided.     *     * @deprecated This method will not be visible in 2.0.     */    protected static String canonicalizeEncoding(String javaEncoding)    {        return encodings.getProperty(javaEncoding, javaEncoding);    }    /**     * A mostly pass-through implementation wrapping     * <code>OutputStreamWriter.write()</code> which assures that the     * XML prolog is written before any other data.     *     * @see java.io.OutputStreamWriter.write(char[], int, int)     */    public void write(char[] cbuf, int off, int len)        throws IOException    {        if (!hasWrittenProlog)        {            super.write(PROLOG, 0, PROLOG.length);            hasWrittenProlog = true;        }        super.write(cbuf, off, len);    }    /**     * A mostly pass-through implementation wrapping     * <code>OutputStreamWriter.write()</code> which assures that the     * XML prolog is written before any other data.     *     * @see java.io.OutputStreamWriter.write(char)     */    public void write(char c)        throws IOException    {        if (!hasWrittenProlog)        {            super.write(PROLOG, 0, PROLOG.length);            hasWrittenProlog = true;        }        super.write(c);    }    /**     * A mostly pass-through implementation wrapping     * <code>OutputStreamWriter.write()</code> which assures that the     * XML prolog is written before any other data.     *     * @see java.io.OutputStreamWriter.write(String, int, int)     */    public void write(String str, int off, int len)        throws IOException    {        if (!hasWrittenProlog)        {            super.write(PROLOG, 0, PROLOG.length);            hasWrittenProlog = true;        }        super.write(str, off, len);    }    /**     * Writes the XML representation of a supported Java object type.     *     * @param obj The <code>Object</code> to write.     * @exception XmlRpcException Unsupported character data found.     * @exception IOException Problem writing data.     * @throws IllegalArgumentException If a <code>null</code>     * parameter is passed to this method (not supported by the <a     * href="http://xml-rpc.com/spec">XML-RPC specification</a>).     */    public void writeObject(Object obj)        throws XmlRpcException, IOException    {        startElement("value");        if (obj == null)        {            throw new XmlRpcException                (0, "null values not supported by XML-RPC");        }        else if (obj instanceof String)        {            chardata(obj.toString());        }        else if (typeDecoder.isXmlRpcI4(obj))        {            startElement("int");            write(obj.toString());            endElement("int");        }        else if (obj instanceof Boolean)        {            startElement("boolean");            write(((Boolean) obj).booleanValue() ? "1" : "0");            endElement("boolean");        }        else if (typeDecoder.isXmlRpcDouble(obj))        {            startElement("double");            write(obj.toString());            endElement("double");        }        else if (obj instanceof Date)        {            startElement("dateTime.iso8601");            Date d = (Date) obj;            write(dateTool.format(d));            endElement("dateTime.iso8601");        }        else if (obj instanceof byte[])        {            startElement("base64");            try            {                this.write((byte[]) base64Codec.encode(obj));            }            catch (EncoderException e)            {                throw new XmlRpcException                    (0, "Unable to Base 64 encode byte array", e);            }            endElement("base64");        }        else if (obj instanceof Object[])        {            startElement("array");            startElement("data");            Object[] array = (Object []) obj;            for (int i = 0; i < array.length; i++)            {                writeObject(array[i]);            }            endElement("data");            endElement("array");        }        else if (obj instanceof Vector)        {            startElement("array");            startElement("data");            Vector array = (Vector) obj;            int size = array.size();            for (int i = 0; i < size; i++)            {                writeObject(array.elementAt(i));            }            endElement("data");            endElement("array");        }        else if (obj instanceof Hashtable)        {            startElement("struct");            Hashtable struct = (Hashtable) obj;            for (Enumeration e = struct.keys(); e.hasMoreElements(); )            {                String key = (String) e.nextElement();                Object value = struct.get(key);                startElement("member");                startElement("name");                chardata(key);                endElement("name");                writeObject(value);                endElement("member");            }            endElement("struct");        }        else        {            throw new XmlRpcException(0, "Unsupported Java type: "                                       + obj.getClass(), null);        }        endElement("value");    }    /**     * This is used to write out the Base64 output...     */    protected void write(byte[] byteData) throws IOException    {        for (int i = 0; i < byteData.length; i++)        {            write(byteData[i]);        }    }    /**     * Writes characters like '\r' (0xd) as "&amp;#13;".     */    private void writeCharacterReference(char c)        throws IOException    {        write("&#");        write(String.valueOf((int) c));        write(';');    }    /**     *     * @param elem     * @throws IOException     */    protected void startElement(String elem) throws IOException    {        write('<');        write(elem);        write('>');    }    /**     *     * @param elem     * @throws IOException     */    protected void endElement(String elem) throws IOException    {        write(CLOSING_TAG_START);        write(elem);        write('>');    }    /**     *     * @param elem     * @throws IOException     */    protected void emptyElement(String elem) throws IOException    {        write('<');        write(elem);        write(SINGLE_TAG_END);    }    /**     * Writes text as <code>PCDATA</code>.     *     * @param text The data to write.     * @exception XmlRpcException Unsupported character data found.     * @exception IOException Problem writing data.     */    protected void chardata(String text)        throws XmlRpcException, IOException    {        int l = text.length ();        // ### TODO: Use a buffer rather than going character by        // ### character to scale better for large text sizes.        //char[] buf = new char[32];        for (int i = 0; i < l; i++)        {            char c = text.charAt (i);            switch (c)            {            case '\t':            case '\n':                write(c);                break;            case '\r':                // Avoid normalization of CR to LF.                writeCharacterReference(c);                break;            case '<':                write(LESS_THAN_ENTITY);                break;            case '>':                write(GREATER_THAN_ENTITY);                break;            case '&':                write(AMPERSAND_ENTITY);                break;            default:                // Though the XML spec requires XML parsers to support                // Unicode, not all such code points are valid in XML                // documents.  Additionally, previous to 2003-06-30                // the XML-RPC spec only allowed ASCII data (in                // <string> elements).  For interoperability with                // clients rigidly conforming to the pre-2003 version                // of the XML-RPC spec, we entity encode characters                // outside of the valid range for ASCII, too.                if (c > 0x7f || !isValidXMLChar(c))                {                    // Replace the code point with a character reference.                    writeCharacterReference(c);                }                else                {                    write(c);                }            }        }    }    /**     * Section 2.2 of the XML spec describes which Unicode code points     * are valid in XML:     *     * <blockquote><code>#x9 | #xA | #xD | [#x20-#xD7FF] |     * [#xE000-#xFFFD] | [#x10000-#x10FFFF]</code></blockquote>     *     * Code points outside this set must be entity encoded to be     * represented in XML.     *     * @param c The character to inspect.     * @return Whether the specified character is valid in XML.     */    private static final boolean isValidXMLChar(char c)    {        switch (c)        {        case 0x9:        case 0xa:  // line feed, '\n'        case 0xd:  // carriage return, '\r'            return true;        default:            return ( (0x20 < c && c <= 0xd7ff) ||                     (0xe000 < c && c <= 0xfffd) ||                     (0x10000 < c && c <= 0x10ffff) );        }    }    protected static void setTypeDecoder(TypeDecoder newTypeDecoder)    {        typeDecoder = newTypeDecoder;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -