import java.io.ByteArrayOutputStream; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.text.DecimalFormat; import java.util.Dictionary; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.xerces.dom.DocumentImpl; import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.XMLSerializer; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * Prints any object into an XML string. */ public class XMLObjectPrinter { public static final int DEBUG_OFF = 0; public static final int DEBUG_LOW = 1; public static final int DEBUG_HIGH = 2; public static int debugLevel = DEBUG_HIGH; /** * Determines the maximum number of element in an array/list that will be * printed */ //public static final int MAX_LIST_PRINT = 100; /** Determines the depth in which embedded objects will be printed */ public static final int MAX_OBJECT_STACK_DEPTH = 3; // "is" not working currently.... public static final String[] VALID_PREFIXES = new String[] { "get", "is" }; /** * Called from outside this class. */ public static void print(Object object) { print(object, null); } public static void print(Object object, String parentName) { try { System.out.print(getXML(object, parentName)); } catch (Exception ex) { ex.printStackTrace(); } } /** * Called from outside this class. */ public static String getXML(Object object) throws Exception { String s = null; return getXML(object, s); } public static String getXML(Object object, String parentName) throws Exception { //TODO return blank xml if object is null if (object == null) return ""; Document doc = new DocumentImpl(); return getXML(object, doc, parentName).trim(); } private static String getXML(Object object, Document doc, String parentName) throws Exception { //doc.createElement(getClassNameNoPackage(object)); doc.appendChild(createXML(object, doc, parentName)); ByteArrayOutputStream os = new ByteArrayOutputStream(); OutputFormat of = new OutputFormat(); of.setIndent(1); of.setIndenting(true); XMLSerializer serializer = new XMLSerializer(os, of); serializer.asDOMSerializer(); serializer.serialize(doc.getDocumentElement()); os.flush(); String out = os.toString(); os.close(); return out; } private static Element createXML(Object object, Document doc, String parentName) throws Exception { if (object == null) return null; String s; if (parentName == null) { s = getClassNameNoPackage(object); } else { s = parentName; } Element parent = doc.createElement(s); return createXML(object, doc, parent, 0); } private static Element createXML(Object object, Document doc, Element parent, int stackLevel) throws Exception { Node node = null; if (object == null) { return parent; } if (object instanceof Map) { createXML((Map) object, doc, parent, stackLevel); } else if (object instanceof List) { createXML((List) object, doc, parent, stackLevel); } else if (object instanceof ResultSet) { createXML((ResultSet) object, doc, parent, stackLevel); } else if (object.getClass().isArray()) { createXMLFromArray(object, doc, parent, stackLevel); } else if (object.getClass().getName().startsWith("java")) { node = doc.createTextNode(format(object)); parent.appendChild(node); return parent; } else { createXMLFromObject(object, doc, parent, stackLevel); } return parent; } private static void createXMLFromObject(Object object, Document doc, Element parent, int stackLevel) throws Exception { Element element = null; Node node = null; Class objectClass = object.getClass(); Method[] methods = objectClass.getMethods(); Method method; Object returnObject; if (stackLevel == MAX_OBJECT_STACK_DEPTH) { node = doc.createTextNode(object.toString()); parent.appendChild(node); return; } stackLevel++; for (int i = 0; i < methods.length; i++) { method = methods[i]; if (hasValidPrefix(method)) { returnObject = invoke(method, object, null); element = doc.createElementNS(null, getFieldFromMethod(method .getName(), VALID_PREFIXES)); parent.appendChild(createXML(returnObject, doc, element, stackLevel)); } } } private static void createXML(Dictionary dict, Document doc, Element parent, int stackLevel) throws Exception { Element element = null; Enumeration enumer = dict.keys(); Object value; Object key; while (enumer.hasMoreElements()) { key = enumer.nextElement(); value = dict.get(key); element = doc.createElementNS(null, key.toString()); parent.appendChild(createXML(value, doc, element, stackLevel)); } } private static void createXML(Map map, Document doc, Element parent, int stackLevel) throws Exception { Element element = null; Set set = map.keySet(); Object value; Object key; for (Iterator i = set.iterator(); i.hasNext();) { key = i.next(); value = map.get(key); //TODO if key is a number, it throws an Exception. Implement a //better solution to catch illegal xml chars... element = doc.createElementNS(null, "Item_" + key.toString()); parent.appendChild(createXML(value, doc, element, stackLevel)); } } private static void createXML(List list, Document doc, Element parent, int stackLevel) throws Exception { Element element = null; for (int i = 0; i < list.size(); i++) { element = doc.createElementNS(null, getElementName(list.get(i))); parent.appendChild(createXML(list.get(i), doc, element, stackLevel)); } } private static void createXMLFromArray(Object array, Document doc, Element parent, int stackLevel) throws Exception { Element element = null; for (int i = 0; i < Array.getLength(array); i++) { element = doc.createElementNS(null, getElementName(Array.get(array, i))); parent.appendChild(createXML(Array.get(array, i), doc, element, stackLevel)); } } private static void createXML(ResultSet rs, Document doc, Element parent, int stackLevel) throws Exception { Element element = null; Element colElement = null; Node node = null; ResultSetMetaData meta = rs.getMetaData(); int colCount = meta.getColumnCount(); int rowCount = 0; String label; while (rs.next()) { element = doc.createElementNS(null, "Row"); for (int i = 1; i <= colCount; i++) { label = meta.getColumnLabel(i); if (label == null || label.length() == 0) { label = meta.getColumnName(i); if (label == null || label.length() == 0) { label = "Column_" + i; } } colElement = doc.createElementNS(null, label); if (rs.getObject(i) != null) { node = doc.createTextNode(rs.getObject(i).toString()); colElement.appendChild(node); } element.appendChild(colElement); } parent.appendChild(element); rowCount++; } } private static String getElementName(Object object) { return getClassNameNoPackage(object); } private static String getElementName(Element element) { return element.getNodeName(); } private static Object invoke(Method method, Object object, Object[] args) { try { return method.invoke(object, args); } catch (Exception ex) { return new String(); } } private static String getFieldFromMethod(String method, String[] prefixes) { String p = null; for ( int i = 0; i < 9; i++) { } } }