com.ibm.commons.util.print.DumpObject Maven / Gradle / Ivy
The newest version!
/*
* © Copyright IBM Corp. 2012-2013
*
* 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 com.ibm.commons.util.print;
import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.ibm.commons.Platform;
import com.ibm.commons.util.QuickSort;
import com.ibm.commons.util.StringUtil;
import com.ibm.commons.util.io.TextOutputStream;
/**
* Dumping an object.
* @ibm-not-published
*/
public class DumpObject extends TablePrinter {
public interface IFilter {
public boolean acceptField(Field field);
public boolean acceptProperty(String name, Object property);
}
public static DefaultAdapterFactory defaultFactory = new DefaultAdapterFactory();
public static DefaultFilter defaultFilter = new DefaultFilter();
private AdapterFactory adapterFactory = defaultFactory;
private TextOutputStream ps = new TextOutputStream(Platform.getInstance().getOutputStream());
private int depth=10;
private int indent=2;
private boolean printType;
private IFilter filter = defaultFilter;
public DumpObject() {
}
public DumpObject(AdapterFactory adapterFactory) {
this.adapterFactory = adapterFactory;
}
public AdapterFactory getAdapterFactory() {
return adapterFactory;
}
public void setAdapterFactory(AdapterFactory adapterFactory) {
this.adapterFactory = adapterFactory;
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
public TextOutputStream getTextOutputStream() {
return ps;
}
public void setTextOutputStream(TextOutputStream ps) {
this.ps = ps;
}
public IFilter getFilter() {
return filter;
}
public void setFilter(IFilter propertyFilter) {
this.filter = propertyFilter;
}
public boolean isPrintType() {
return printType;
}
public void setPrintType(boolean printType) {
this.printType = printType;
}
public int getIndent() {
return indent;
}
public void setIndent(int indent) {
this.indent = indent;
}
public void dump(Object o) throws IOException {
if(o!=null) {
dump(new HashMap(), new ArrayList(), null, o, depth);
} else {
ps.println("");
}
ps.flush();
}
public static interface AdapterFactory {
public Adapter createAdapter(Object o);
}
public static class FactoryWrapper implements AdapterFactory {
private AdapterFactory wrapped;
public FactoryWrapper(AdapterFactory wrapped) {
this.wrapped = wrapped;
}
public Adapter createAdapter(Object o) {
return wrapped.createAdapter(o);
}
}
public static abstract class Adapter {
public String getTypeAsString() {
return "";
}
public boolean isValue() {
return false;
}
public String getValue() {
return null;
}
public boolean isArray() {
return false;
}
public Iterator arrayIterator() {
return null;
}
public int arrayCount() {
return 0;
}
public boolean isObject() {
return false;
}
public Map getPropertyMap(IFilter filter) {
return null;
}
}
public static class AdapterWrapper extends Adapter {
private Adapter wrapped;
public AdapterWrapper(Adapter wrapped) {
this.wrapped = wrapped;
}
@Override
public String getTypeAsString() {
return wrapped.getTypeAsString();
}
@Override
public boolean isValue() {
return wrapped.isValue();
}
@Override
public String getValue() {
return wrapped.getValue();
}
@Override
public boolean isArray() {
return wrapped.isArray();
}
@Override
public Iterator arrayIterator() {
return wrapped.arrayIterator();
}
@Override
public int arrayCount() {
return wrapped.arrayCount();
}
@Override
public boolean isObject() {
return wrapped.isObject();
}
@Override
public Map getPropertyMap(IFilter filter) {
return wrapped.getPropertyMap(filter);
}
}
public static class DefaultFilter implements IFilter {
public boolean acceptField(Field field) {
return true;
}
public boolean acceptProperty(String name, Object property) {
if(property instanceof PropertyDescriptor) {
if(name.equals("class")) {
return false;
}
return true;
}
return true;
}
}
public static class DefaultAdapterFactory implements AdapterFactory {
private boolean beans;
public DefaultAdapterFactory() {
this.beans = true;
}
public DefaultAdapterFactory(boolean beans) {
this.beans = beans;
}
public Adapter createAdapter(Object o) {
if(o==null) {
return new NullAdapter();
}
Class c = o.getClass();
// Check for a simple value
if(o instanceof String) {
return new PrimitiveAdapter(o);
}
if(o instanceof Number) {
return new PrimitiveAdapter(o);
}
if(o instanceof Boolean) {
return new PrimitiveAdapter(o);
}
if(o instanceof Character) {
return new PrimitiveAdapter(o);
}
if(o instanceof Date) {
return new PrimitiveAdapter(o);
}
if(o instanceof Calendar) {
return new PrimitiveAdapter(new Date(((Calendar)o).getTimeInMillis()));
}
// Check for an array/collection
if( c.isArray() ) {
return new ArrayAdapter(o);
}
if( o instanceof Collection ) {
return new CollectionAdapter(o);
}
if( o instanceof Map ) {
return new MapAdapter(o);
}
// XML document
if(o instanceof Document) {
Node node = (Node)o;
return new XmlAdapter(node);
}
// Try a Java bean
if(beans) {
try {
BeanInfo bi = java.beans.Introspector.getBeanInfo(c);
PropertyDescriptor[] desc = bi.getPropertyDescriptors();
return new JavaBeanAdapter(desc,o);
} catch(Exception ex) {
}
}
// Regular Java class
return new JavaObjectAdapter(o);
}
}
public static class NullAdapter extends Adapter {
public NullAdapter() {
}
public boolean isValue() {
return true;
}
public String getValue() {
return ""; // $NON-NLS-1$
}
}
public static class PrimitiveAdapter extends Adapter {
Object value;
public PrimitiveAdapter(Object value) {
this.value = value;
}
public String getTypeAsString() {
String cName = value.getClass().getName();
return cName;
}
public boolean isValue() {
return true;
}
public String getValue() {
return value.toString();
}
}
public static class JavaBeanAdapter extends Adapter {
PropertyDescriptor[] desc;
Object instance;
public JavaBeanAdapter(PropertyDescriptor[] desc, Object instance) {
this.desc = desc;
this.instance = instance;
}
public boolean isObject() {
return true;
}
public Map getPropertyMap(IFilter filter) {
HashMap map = new HashMap();
for( int i=0; i"); // $NON-NLS-1$
} else {
value = read.invoke(instance,(Object[])null);
}
} catch(Exception e) {
value = StringUtil.format("",e.getMessage()); // $NON-NLS-1$
}
map.put(name, value);
}
return map;
}
}
public static class JavaObjectAdapter extends Adapter {
Field[] fields;
Object instance;
public JavaObjectAdapter(Object instance) {
this.fields = instance.getClass().getFields();
this.instance = instance;
}
public boolean isObject() {
return true;
}
public Map getPropertyMap(IFilter filter) {
HashMap map = new HashMap();
for( int i=0; i",e.getMessage()); // $NON-NLS-1$
}
map.put(name, value);
}
return map;
}
}
public static class ArrayAdapter extends Adapter {
Object instance;
public ArrayAdapter(Object instance) {
this.instance = instance;
}
public boolean isArray() {
return true;
}
public Iterator arrayIterator() {
return new Iterator() {
int current = 0;
int length = Array.getLength(instance);
public boolean hasNext() {
return current",e.getMessage());
}
}
private String writeToString(Node node) {
try {
Transformer serializer = TransformerFactory.newInstance().newTransformer();
StringWriter writer = new StringWriter();
serializer.transform(new DOMSource(node), new StreamResult(writer));
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
private void dump( HashMap map, ArrayList hierarchy, String propertyName, Object v, int depth ) throws IOException {
Adapter adapter = adapterFactory.createAdapter(v);
// Limit the depth...
if(depth<=0) {
return;
}
// Get the children list
// Print the indentation
for( int i=0; i1 ) {
ps.print("+- "); //$NON-NLS-1$
}
// Display the value
if( StringUtil.isNotEmpty(propertyName) ) {
ps.print(propertyName);
ps.print(": "); //$NON-NLS-1$
}
if(adapter.isValue()) {
String vs = valueAndType(adapter.getValue(),adapter.getTypeAsString());
if( !StringUtil.isEmpty(vs) ) {
ps.print(vs);
}
String type = adapter.getTypeAsString();
if(printType && StringUtil.isNotEmpty(type)) {
ps.print(" (");
ps.print(type);
ps.print(")");
}
ps.print("\n"); //$NON-NLS-1$
}
// Display Object's property
if( adapter.isObject() ) {
if(!inHierarchy(hierarchy, v)) {
ps.print(StringUtil.format("{0}\n", valueAndType(adapter.getValue(),adapter.getTypeAsString())));
Map pMap = adapter.getPropertyMap(filter);
ArrayList names = new ArrayList();
for( Iterator it=pMap.keySet().iterator(); it.hasNext(); ) {
String name = (String)it.next();
names.add(name);
}
(new QuickSort.JavaList(names)).sort();
int count = names.size();
for( int i=0; i");
}
if(StringUtil.isNotEmpty(typeAsString) && !typeAsString.equals("java.lang.String")) {
b.append(" (");
b.append(typeAsString);
b.append(")");
}
return b.toString();
}
public void dump(DataInputStream ios) {
dump(ios, Integer.MAX_VALUE);
}
public void dump(DataInputStream ios, int length) {
try {
String s;
String a = "";
for (int i = 0, j = 0; i < length; i++) {
int val = ios.read();
if (val < 0) {
ps.flush();
return;
}
if (j == 0) {
ps.println(" " + a);
a = "";
s = Integer.toHexString(i);
s = s + " ".substring(s.length());
ps.print(s + " ");
}
if (j == 8) ps.print(" ");
s = Integer.toHexString(val);
if (s.length() < 2) s = "0" + s;
ps.print(s + " ");
if ((val > 32) && (val < 128)) a += (char)val; else a += ' ';
if (++j == 16) j = 0;
}
ps.println("");
ps.flush();
return;
} catch(IOException e) {
Platform.getInstance().log(e);
}
}
}