
src.openwfe.org.xml.XmlCoder Maven / Gradle / Ivy
/*
* Copyright (c) 2001-2006, John Mettraux, OpenWFE.org
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . 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.
*
* . Neither the name of the "OpenWFE" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
*
* $Id: XmlCoder.java 2773 2006-06-09 08:02:08Z jmettraux $
*/
//
// XmlCoder.java
//
// [email protected]
//
// generated with
// jtmpl 1.1.01 2004/05/19 ([email protected])
//
package openwfe.org.xml;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import openwfe.org.Utils;
import openwfe.org.ReflectionUtils;
/**
* XMLEncoder ? la OpenWFE
*
* CVS Info :
*
$Author: jmettraux $
*
$Id: XmlCoder.java 2773 2006-06-09 08:02:08Z jmettraux $
*
* @author [email protected]
*/
public abstract class XmlCoder
{
private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
.getLogger(XmlCoder.class.getName());
//
// CONSTANTS & co
private final static String E_INSTANCE
= "instance";
private final static String E_FIELD
= "field";
private final static String E_ARRAY
= "array";
private final static String E_PRIMITIVE
= "primitive";
private final static String E_MAP
= "map";
private final static String E_COLLECTION
= "collection";
private final static String E_NULL
= "null";
private final static String E_JDOM
= "jdom";
private final static String E_ENTRY
= "entry";
private final static String A_CLASS
= "class";
private final static String A_SIZE
= "size";
private final static String A_NAME
= "name";
//private final static String A_HOMOGENEOUS
// = "homogeneous";
//private final static String GET = "get";
private final static String IS = "is";
private final static String SET = "set";
//
// STATIC METHODS
//
// ENCODING
private static boolean isPrimitive (final Object instance)
{
final Class clazz = instance.getClass();
if (clazz == String.class) return true;
if (clazz == Integer.class) return true;
if (clazz == Long.class) return true;
if (clazz == Short.class) return true;
if (clazz == Float.class) return true;
if (clazz == Double.class) return true;
if (clazz == Boolean.class) return true;
if (clazz == Character.class) return true;
if (clazz == Byte.class) return true;
return false;
}
private static void encodeField
(final Object instance,
final org.jdom.Element container,
final Method getMethod)
throws
Exception
{
final org.jdom.Element eField = new org.jdom.Element(E_FIELD);
final String getMethodName = getMethod.getName();
String rawFieldName = getMethodName.substring(3);
if (getMethodName.startsWith(IS))
rawFieldName = getMethodName.substring(2);
eField.setAttribute(A_NAME, rawFieldName);
final Object[] args = null;
final Object value = getMethod.invoke(instance, args);
eField.addContent(encode(value));
container.addContent(eField);
}
private static org.jdom.Element encodePrimitive (final Object value)
{
final org.jdom.Element result = new org.jdom.Element(E_PRIMITIVE);
result.setAttribute(A_CLASS, value.getClass().getName());
result.addContent(new org.jdom.Text(value.toString()));
return result;
}
private static org.jdom.Element encodeArray (final Object array)
throws Exception
{
final org.jdom.Element result = new org.jdom.Element(E_ARRAY);
Class firstEltClass = null;
boolean isHomogeneous = true;
for (int i=0; ifailed to dumpToString : "+t+"<";
}
}
/**
* Encoding a bean to an XML element
*/
public static org.jdom.Element encode (final Object bean)
throws XmlCodingException
{
/*
if (bean == null)
log.debug("encode() bean is null");
else
log.debug("encode() for "+bean.toString());
*/
if (bean == null) return new org.jdom.Element(E_NULL);
//
// is it not a bean ?
try
{
if (bean.getClass().isArray())
return encodeArray(bean);
if (java.util.Map.class.isInstance(bean))
return encodeMap(bean);
if (java.util.Collection.class.isInstance(bean))
return encodeCollection(bean);
if (isPrimitive(bean))
return encodePrimitive(bean);
if (bean instanceof org.jdom.Element)
return encodeJdomElement(bean);
}
catch (final Exception e)
{
throw new XmlCodingException
("Encoding failure for bean of class '"+
bean.getClass().getName()+"'", e);
}
//
// well, it's a bean then
final org.jdom.Element result = new org.jdom.Element(E_INSTANCE);
result.setAttribute(A_CLASS, bean.getClass().getName());
final java.util.Iterator it = ReflectionUtils
.listReadWriteFields(bean).iterator();
while (it.hasNext())
{
final Method[] methods = (Method[])it.next();
try
{
encodeField(bean, result, methods[0]);
//
// index 0=get, index 1=set
}
catch (final Exception e)
{
throw new XmlCodingException
("Failed to encode field behind getter '"+
methods[0].getName()+"' for bean of class '"+
bean.getClass().getName()+"'", e);
}
}
return result;
}
//
// DECODING
private static Class getClass (final org.jdom.Element elt)
throws ClassNotFoundException
{
final String classname = elt.getAttributeValue(A_CLASS);
return Class.forName(classname);
}
private static int getSize (final org.jdom.Element elt)
{
final String sSize = elt.getAttributeValue(A_SIZE);
try
{
return Integer.parseInt(sSize);
}
catch (final Exception e)
{
return 10;
}
}
private static Object decodeArray (final org.jdom.Element elt)
throws Exception
{
final Object[] result = new Object[getSize(elt)];
int i = 0;
final java.util.Iterator it = elt.getChildren().iterator();
while (it.hasNext())
{
result[i] = decode((org.jdom.Element)it.next());
i++;
}
return result;
}
private static Object decodeMap (final org.jdom.Element elt)
throws Exception
{
final java.util.Map result =
(java.util.Map)getClass(elt).newInstance();
final java.util.Iterator it = elt.getChildren().iterator();
while (it.hasNext())
{
final org.jdom.Element eEntry = (org.jdom.Element)it.next();
final Object key =
decode((org.jdom.Element)eEntry.getChildren().get(0));
final Object value =
decode((org.jdom.Element)eEntry.getChildren().get(1));
result.put(key, value);
}
return result;
}
private static Object decodeCollection (final org.jdom.Element elt)
throws Exception
{
final java.util.Collection result =
(java.util.Collection)getClass(elt).newInstance();
final java.util.Iterator it = elt.getChildren().iterator();
while (it.hasNext())
result.add(decode((org.jdom.Element)it.next()));
return result;
}
private static Object invokeStringConstructor
(final Class primitiveClass, final String value)
throws
Exception
{
final Constructor c = primitiveClass
.getConstructor(new Class[] { String.class });
return c.newInstance(new Object[] { value });
}
private static Object decodePrimitive (final org.jdom.Element elt)
throws Exception
{
final Class clazz = getClass(elt);
if (clazz == Character.class)
return new Character(elt.getText().charAt(0));
return invokeStringConstructor(clazz, elt.getText());
}
private static Object decodeJdomElement (final org.jdom.Element elt)
throws Exception
{
return elt.getChildren().get(0);
}
/**
* Decoding a bean from an XML document.
*/
public static Object decode (final org.jdom.Document doc)
throws XmlCodingException
{
return decode(doc.getRootElement());
}
/**
* Decoding a bean from an XML document.
*/
public static Object decode (final org.jdom.Element elt)
throws XmlCodingException
{
if (elt.getName().equals(E_NULL))
return null;
try
{
if (elt.getName().equals(E_ARRAY))
return decodeArray(elt);
if (elt.getName().equals(E_MAP))
return decodeMap(elt);
if (elt.getName().equals(E_COLLECTION))
return decodeCollection(elt);
if (elt.getName().equals(E_PRIMITIVE))
return decodePrimitive(elt);
if (elt.getName().equals(E_JDOM))
return decodeJdomElement(elt);
//
// else it's a bean instance...
final Class clazz = getClass(elt);
final Object result = clazz.newInstance();
final java.util.Map fieldMap = new java.util.HashMap();
java.util.Iterator it = elt.getChildren(E_FIELD).iterator();
while (it.hasNext())
{
final org.jdom.Element eField = (org.jdom.Element)it.next();
final String rawFieldName = eField.getAttributeValue(A_NAME);
final org.jdom.Element eValue =
(org.jdom.Element)eField.getChildren().get(0);
final Object value = decode(eValue);
fieldMap.put(SET+rawFieldName, value);
//log.debug("decode() will have to use '"+SET+rawFieldName+"'");
}
it = ReflectionUtils
.listReadWriteFields(clazz).iterator();
while (it.hasNext())
{
final Method[] ms = (Method[])it.next();
final Method setMethod = ms[1];
final String setMethodName = setMethod.getName();
final Object value = fieldMap.get(setMethodName);
try
{
setMethod.invoke(result, new Object[] { value });
}
catch (final Throwable t)
{
log.warn
("decode() failed to invoke '"+setMethodName+
"' on bean of class '"+clazz.getName()+
"'. Continuing anyway...",
t);
}
//log.debug("decode() invoked '"+setMethod.getName()+"'");
}
return result;
}
catch (final Throwable t)
{
throw new XmlCodingException
("Failed to decode elt named '"+elt.getName()+"'", t);
}
}
/**
* Loading an object from a file
*/
public static Object load (final String fileName)
throws java.io.IOException, org.jdom.JDOMException, XmlCodingException
{
return decode(XmlUtils.extractXml(fileName, false));
}
/**
* Loading an object from an URL
*/
public static Object load (final java.net.URL fileUrl)
throws java.io.IOException, org.jdom.JDOMException, XmlCodingException
{
return decode(XmlUtils.extractXml(fileUrl, false));
}
/**
* Saving a bean / instance to a file
*/
public static void save (final String fileName, final Object bean)
{
java.io.FileOutputStream fos = null;
try
{
fos = new java.io.FileOutputStream(fileName);
save(fos, bean);
}
catch (final Throwable t)
{
log.error("save() failed to open outputstream to file "+fileName);
}
}
/**
* Saving a bean / instance to a given output stream.
*/
public static void save (final java.io.OutputStream os, final Object bean)
throws java.io.IOException, XmlCodingException
{
try
{
final org.jdom.Document doc = new org.jdom.Document(encode(bean));
XmlUtils.getXMLOutputter().output(doc, os);
os.flush();
}
finally
{
try
{
os.close();
}
catch (final Throwable t)
{
log.error
("save() failed to encode as xml to given outputstream");
}
}
}
//
// TESTING ...
/*
public final static void main (final String[] args)
throws Exception
{
org.apache.log4j.BasicConfigurator.configure();
log.getRootLogger().setLevel(org.apache.log4j.Level.DEBUG);
java.util.List result = new java.util.ArrayList();
result.add("toto");
result.add(new Integer(5));
result.add(new Integer[] { new Integer(1), new Integer(3) });
result.add(new int[] { 1, 3, 5, 7 });
result.add(new Object() {
private String s = null;
public void setNada (String s) { this.s = s;}
public String getNada () { return s; }
});
org.jdom.Element e = new org.jdom.Element("xmlStuff");
e.setText("nada");
e.addContent(new org.jdom.Element("inStuff"));
e.setAttribute("value", "0");
result.add(e);
java.util.Map m = new java.util.HashMap();
m.put("nada", "surf");
m.put("chase", "manhattan");
result.add(m);
System.out.println("result.size() is "+result.size());
//
// encoding
org.jdom.Element elt = encode(result);
System.out.println();
System.out.println(openwfe.org.Utils.toString
(new org.jdom.Document(elt), "ISO-8859-15"));
result = null;
//
// decoding
result = (java.util.List)decode(elt);
System.out.println("result.size() is "+result.size());
//
// re-coding
elt = encode(result);
System.out.println();
System.out.println(openwfe.org.Utils.toString
(new org.jdom.Document(elt), "ISO-8859-1"));
}
*/
}