📄 xmldebugger.java
字号:
/*
* Created on Jun 26, 2005
*/
package org.flexdock.test.xml;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.flexdock.util.Utilities;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
/**
* @author Christopher Butler
*/
public class XMLDebugger {
public static void println(Object obj) {
if(obj==null) {
System.out.println("null");
return;
}
XMLDebugger debugger = new XMLDebugger();
String xml = debugger.getXML(obj);
System.out.println(xml);
}
public String getXML(Object obj) {
if(obj==null)
return null;
Document document = createDocument();
Element rootElem = document.getDocumentElement();
buildXML(obj, document, rootElem);
try {
TransformerFactory factory = TransformerFactory.newInstance();
if(Utilities.JAVA_1_5) {
factory.setAttribute("indent-number", new Integer(4));
}
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
DOMSource src = new DOMSource(document);
transformer.transform(src, result);
return writer.toString();
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
private void buildXML(Object obj, Document document, Element parentElem) {
String elemName = getName(obj);
Element objElem = document.createElement(elemName);
if(isBasic(obj)) {
objElem.setAttribute("value", obj.toString());
parentElem.appendChild(objElem);
return;
}
Field[] fields = getFields(obj);
for(int i=0; i<fields.length; i++) {
String modifiers = Modifier.toString(fields[i].getModifiers());
if(modifiers.indexOf("static")!=-1 || modifiers.indexOf("transient")!=-1)
continue;
Object fieldValue = getValue(fields[i], obj);
String fieldName = fields[i].getName();
if(fieldValue==null) {
objElem.setAttribute(fieldName, "null");
}
else if(isBasic(fieldValue)) {
objElem.setAttribute(fieldName, fieldValue.toString());
}
else if(fieldValue instanceof Collection) {
buildXML((Collection)fieldValue, document, objElem, fieldName);
}
else if(fieldValue instanceof Object[]) {
buildXML((Object[])fieldValue, document, objElem, fieldName);
}
else if(fieldValue instanceof Map) {
buildXML((Map)fieldValue, document, objElem, fieldName);
}
else {
buildXML(fieldValue, document, objElem);
}
}
try {
parentElem.appendChild(objElem);
} catch(NullPointerException e) {
System.out.println();
throw e;
}
}
private void buildXML(Collection collection, Document document, Element parentElem, String fieldName) {
Element objElem = document.createElement(fieldName);
objElem.setAttribute("type", "collection");
for(Iterator it=collection.iterator(); it.hasNext();) {
Object obj = it.next();
buildXML(obj, document, objElem);
}
parentElem.appendChild(objElem);
}
private void buildXML(Map map, Document document, Element parentElem, String fieldName) {
Element objElem = document.createElement(fieldName);
objElem.setAttribute("type", "map");
for(Iterator it=map.keySet().iterator(); it.hasNext();) {
Object key = it.next();
Object value = map.get(key);
Object obj = new MapEntry(key, value);
buildXML(obj, document, objElem);
}
parentElem.appendChild(objElem);
}
private void buildXML(Object[] objects, Document document, Element parentElem, String fieldName) {
Element objElem = document.createElement(fieldName);
objElem.setAttribute("type", "array");
for(int i=0; i<objects.length; i++) {
buildXML(objects[i], document, objElem);
}
parentElem.appendChild(objElem);
}
private static Field[] getFields(Object obj) {
Class c = obj.getClass();
Field[] fields = c.getDeclaredFields();
if(obj instanceof DefaultMutableTreeNode) {
Field children = getField(obj, "children");
if(children!=null) {
Field[] tmp = new Field[fields.length+1];
System.arraycopy(fields, 0, tmp, 0, fields.length);
tmp[tmp.length-1] = children;
fields = tmp;
}
}
return fields;
}
private static Field getField(Object obj, String fieldName) {
Class c = obj.getClass();
while(true) {
try {
return c.getDeclaredField(fieldName);
} catch(Exception e) {
if(c==Object.class)
return null;
c = c.getSuperclass();
}
}
}
private static Object getValue(Field field, Object owner) {
boolean toggle = !field.isAccessible();
if(toggle)
field.setAccessible(true);
Object obj = null;
try {
obj = field.get(owner);
} catch(Throwable t) {
t.printStackTrace();
}
if(toggle)
field.setAccessible(false);
return obj;
}
private static String getName(Object obj) {
Class clazz = obj.getClass();
String name = clazz.getName();
int indx = name.lastIndexOf('.');
if(indx!=-1)
name = name.substring(indx+1, name.length());
indx = name.lastIndexOf('$');
if(indx!=-1)
name = name.substring(indx+1, name.length());
return name;
}
private static boolean isBasic(Object obj) {
return obj.getClass().isPrimitive() || obj.getClass().getName().startsWith("java.lang");
}
private static Document createDocument() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
StringReader reader = new StringReader("<?xml version=\"1.0\"?><ObjectXML></ObjectXML>");
InputSource src = new InputSource(reader);
return builder.parse(src);
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
public static class MapEntry {
private Object key;
private Object value;
public MapEntry(Object key, Object value) {
this.key = key;
this.value = value;
}
}
public static class DataObject {
private Object data;
public DataObject(Object obj) {
data = obj;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -