You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rpc-dev@xml.apache.org by dl...@apache.org on 2002/08/07 19:44:36 UTC
cvs commit: xml-rpc/src/java/org/apache/xmlrpc XmlWriter.java
dlr 2002/08/07 10:44:36
Added: src/java/org/apache/xmlrpc XmlWriter.java
Log:
This class was originally XmlRpc.XmlWriter. It writes XML, and now
handles much of the associated encoding manipulation previously
handled by XmlRpc.
Revision Changes Path
1.1 xml-rpc/src/java/org/apache/xmlrpc/XmlWriter.java
Index: XmlWriter.java
===================================================================
package org.apache.xmlrpc;
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "XML-RPC" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
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;
/**
* A quick and dirty XML writer. 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 <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
*/
class XmlWriter extends OutputStreamWriter
{
// Various XML pieces.
protected static final String PROLOG_START =
"<?xml version=\"1.0\" encoding=\"";
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 = "<";
protected static final String GREATER_THAN_ENTITY = ">";
protected static final String AMPERSAND_ENTITY = "&";
/**
* Java's name for the the ISO8859_1 encoding.
*/
protected static final String ISO8859_1 = "ISO8859_1";
/**
* Java's name for the the UTF8 encoding.
*/
protected static final String UTF8 = "UTF8";
/**
* Mapping between Java encoding names and "real" names used in
* XML prolog.
*/
private static Properties encodings = new Properties();
static
{
encodings.put(UTF8, "UTF-8");
encodings.put(ISO8859_1, "ISO-8859-1");
}
/**
* Creates a new instance.
*
* @param out The stream to write output to.
* @param enc The encoding to using for outputing XML.
* @throws UnsupportedEncodingException Encoding unrecognized.
* @throws IOException Problem writing.
*/
public XmlWriter(OutputStream out, String enc)
throws UnsupportedEncodingException, IOException
{
// Super-class wants the Java form of the encoding.
super(out, enc);
// Add the XML prolog (including the encoding in XML form).
write(PROLOG_START);
write(canonicalizeEncoding(enc));
write(PROLOG_END);
}
/**
* 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.
*/
protected static String canonicalizeEncoding(String javaEncoding)
{
return encodings.getProperty(javaEncoding, javaEncoding);
}
/**
* Writes the XML representation of a supported Java object type.
*
* @param obj The <code>Object</code> to write.
* @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 IOException
{
startElement("value");
if (obj == null)
{
throw new IllegalArgumentException
("null values not supported by XML-RPC");
}
else if (obj instanceof String)
{
chardata(obj.toString());
}
else if (obj instanceof Integer)
{
startElement("int");
write(obj.toString());
endElement("int");
}
else if (obj instanceof Boolean)
{
startElement("boolean");
write(((Boolean) obj).booleanValue() ? "1" : "0");
endElement("boolean");
}
else if (obj instanceof Double || obj instanceof Float)
{
startElement("double");
write(obj.toString());
endElement("double");
}
else if (obj instanceof Date)
{
startElement("dateTime.iso8601");
Date d = (Date) obj;
// TODO: Stop using package private variable from XmlRpc
write(XmlRpc.dateformat.format(d));
endElement("dateTime.iso8601");
}
else if (obj instanceof byte[])
{
startElement("base64");
this.write(Base64.encode((byte[]) obj));
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 nextkey = (String) e.nextElement();
Object nextval = struct.get(nextkey);
startElement("member");
startElement("name");
write(nextkey);
endElement("name");
writeObject(nextval);
endElement("member");
}
endElement("struct");
}
else
{
throw new RuntimeException("unsupported Java type: "
+ obj.getClass());
}
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]);
}
}
/**
*
* @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);
}
/**
*
* @param text
* @throws IOException
*/
protected void chardata(String text) throws IOException
{
int l = text.length ();
for (int i = 0; i < l; i++)
{
char c = text.charAt (i);
switch (c)
{
case '<':
write(LESS_THAN_ENTITY);
break;
case '>':
write(GREATER_THAN_ENTITY);
break;
case '&':
write(AMPERSAND_ENTITY);
break;
default:
write(c);
}
}
}
}