Updating BeanInspector

This commit is contained in:
Marcel Kronfeld 2011-05-03 12:37:10 +00:00
parent 7938b4e8ac
commit 949de216df

View File

@ -11,6 +11,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.server.go.strategies.GeneticAlgorithm;
import eva2.tools.Pair; import eva2.tools.Pair;
import eva2.tools.SelectedTag; import eva2.tools.SelectedTag;
import eva2.tools.StringTools; import eva2.tools.StringTools;
@ -29,13 +30,13 @@ public class BeanInspector {
/** /**
* Check for equality based on bean properties of two target objects. * Check for equality based on bean properties of two target objects.
*/ */
public static boolean equalProperties(Object Target_1, Object Target_2) { public static boolean equalProperties(Object obj_1, Object obj_2) {
if (Target_1 == null || Target_2 == null) { if (obj_1 == null || obj_2 == null) {
System.out.println(""); System.out.println("");
return false; return false;
} }
System.out.println("equalProperties: " + Target_1.getClass().getName() + " " + Target_2.getClass().getName()); System.out.println("equalProperties: " + obj_1.getClass().getName() + " " + obj_2.getClass().getName());
if (Target_1.getClass().getName().equals(Target_2.getClass().getName()) == false) { if (obj_1.getClass().getName().equals(obj_2.getClass().getName()) == false) {
System.out.println(""); System.out.println("");
return false; return false;
} }
@ -46,8 +47,8 @@ public class BeanInspector {
PropertyDescriptor[] Properties_2 = null; PropertyDescriptor[] Properties_2 = null;
try { try {
Info_1 = Introspector.getBeanInfo(Target_1.getClass()); Info_1 = Introspector.getBeanInfo(obj_1.getClass());
Info_2 = Introspector.getBeanInfo(Target_2.getClass()); Info_2 = Introspector.getBeanInfo(obj_2.getClass());
Properties_1 = Info_1.getPropertyDescriptors(); Properties_1 = Info_1.getPropertyDescriptors();
Properties_2 = Info_2.getPropertyDescriptors(); Properties_2 = Info_2.getPropertyDescriptors();
Info_1.getMethodDescriptors(); Info_1.getMethodDescriptors();
@ -76,8 +77,8 @@ public class BeanInspector {
Object args_2[] = {}; Object args_2[] = {};
//System.out.println("m_Target"+m_Target.toString()); //System.out.println("m_Target"+m_Target.toString());
try { try {
Object value_1 = getter_1.invoke(Target_1, args_1); Object value_1 = getter_1.invoke(obj_1, args_1);
Object value_2 = getter_2.invoke(Target_2, args_2); Object value_2 = getter_2.invoke(obj_2, args_2);
BeansInside = true; BeansInside = true;
if (BeanInspector.equalProperties(value_1, value_2) == false) { if (BeanInspector.equalProperties(value_1, value_2) == false) {
BeansEqual = false; BeansEqual = false;
@ -90,46 +91,78 @@ public class BeanInspector {
return BeansEqual; return BeansEqual;
} }
// here we have Integer or Double ... // here we have Integer or Double ...
if (Target_1 instanceof Integer || if (obj_1 instanceof Integer ||
Target_1 instanceof Boolean || obj_1 instanceof Boolean ||
Target_1 instanceof Float || obj_1 instanceof Float ||
Target_1 instanceof Double || obj_1 instanceof Double ||
Target_1 instanceof Long || obj_1 instanceof Long ||
Target_1 instanceof String) { obj_1 instanceof String) {
return Target_1.equals(Target_2); return obj_1.equals(obj_2);
} }
System.out.println(" Attention no match !!!"); System.err.println(" Attention no match !!!");
return true; return true;
} }
public static String toString(Object Target) { /**
return toString(Target, ';', false); * Produce a String representation of an arbitrary object.
*
* @see #toString(Object, char, boolean, String)
* @param obj
* @return
*/
public static String toString(Object obj) {
return toString(obj, ';', false, "", 1, false);
} }
/**
* Produce a string with newlines and indentation (easier readable for if an object has many properties).
* @param obj
* @return
*/
public static String niceToString(Object obj) {
return toString(obj, ';', false, " ", 1, true);
}
/**
* Collect the accessible properties of an object and their values in a string with indentations.
* Special cases: Arrays and Lists are concatenations of their elements, Population is excepted from lists.
* If the object has its own toString method, this one is preferred. Hidden or expert properties are not
* shown.
*
* @param obj an arbitrary object
* @return a String description of the object
*/
public static String toString(Object obj, char delim, boolean tight, String indentStr) {
return toString(obj, delim, tight, indentStr, 1, false);
}
/** /**
* Collect the accessible properties of an object and their values in a string. * Collect the accessible properties of an object and their values in a string.
* Special cases: Arrays and Lists are concatenations of their elements, Population is excepted from lists. * Special cases: Arrays and Lists are concatenations of their elements, Population is excepted from lists.
* If the object has its own toString method, this one is preferred. Hidden or expert properties are not * If the object has its own toString method, this one is preferred. Hidden or expert properties are not
* shown. * shown.
* *
* @param Target Description of the Parameter * @param obj Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
public static String toString(Object Target, char delim, boolean tight) { private static String toString(Object obj, char delim, boolean tight, String indentStr, int indentDepth, boolean withNewlines) {
String ret = ""; if (obj == null) return "null";
if (Target == null) return "null";
// try the object itself // try the object itself
if (Target instanceof String) return (String)Target; // directly return a string object if (obj instanceof String) return (String)obj; // directly return a string object
Class<? extends Object> type = Target.getClass(); Class<? extends Object> type = obj.getClass();
if (type.isArray()) { // handle the array case if (type.isArray()) { // handle the array case
StringBuffer sbuf = new StringBuffer("["); StringBuffer sbuf = new StringBuffer();
sbuf.append("[");
if (!tight) sbuf.append(" "); if (!tight) sbuf.append(" ");
int len = Array.getLength(Target); int len = Array.getLength(obj);
for (int i=0; i<len; i++) { for (int i=0; i<len; i++) {
sbuf.append(toString(Array.get(Target, i))); // sbuf.append(toString(Array.get(obj, i)));
if (withNewlines) sbuf.append('\n');
sbuf.append(toString(Array.get(obj, i), delim, tight, indentStr, indentDepth, withNewlines));
if (i<len-1) { if (i<len-1) {
sbuf.append(delim); // sbuf.append(delim);
if (!tight) sbuf.append(" "); if (!tight) sbuf.append(" ");
} }
} }
@ -139,13 +172,16 @@ public class BeanInspector {
} }
if (type.isEnum()) { if (type.isEnum()) {
return Target.toString(); return makeIndent(indentStr, indentDepth) + obj.toString();
} }
if (Target instanceof List && !(Target instanceof Population)) { // handle the list case if (obj instanceof List && !(obj instanceof Population)) { // handle the list case
StringBuffer sbuf = new StringBuffer("["); StringBuffer sbuf = new StringBuffer();
if (withNewlines) sbuf.append('\n');
addIndent(sbuf, indentStr, indentDepth);
sbuf.append("[");
if (!tight) sbuf.append(" "); if (!tight) sbuf.append(" ");
List<?> lst = (List<?>)Target; List<?> lst = (List<?>)obj;
for (Object o : lst) { for (Object o : lst) {
sbuf.append(o.toString()); sbuf.append(o.toString());
sbuf.append(delim); sbuf.append(delim);
@ -156,16 +192,15 @@ public class BeanInspector {
return sbuf.toString(); return sbuf.toString();
} }
Method[] methods = obj.getClass().getDeclaredMethods();
Method[] methods = Target.getClass().getDeclaredMethods();
for (int ii = 0; ii < methods.length; ii++) { // check if the object has its own toString method, in this case use it for (int ii = 0; ii < methods.length; ii++) { // check if the object has its own toString method, in this case use it
if ((methods[ii].getName().equals("toString") /*|| (methods[ii].getName().equals("getStringRepresentation"))*/) && (methods[ii].getParameterTypes().length == 0)) { if ((methods[ii].getName().equals("toString") /*|| (methods[ii].getName().equals("getStringRepresentation"))*/) && (methods[ii].getParameterTypes().length == 0)) {
Object[] args = new Object[0]; Object[] args = new Object[0];
//args[0] = Target; //args[0] = obj;
try { try {
ret = (String) methods[ii].invoke(Target, args); String ret = (String) methods[ii].invoke(obj, args);
if (TRACE) System.out.println("toString on "+ Target.getClass() + " gave me " + ret); if (TRACE) System.out.println("toString on "+ obj.getClass() + " gave me " + ret);
return ret; return makeIndent(indentStr, indentDepth) + ret;
} catch (Exception e) { } catch (Exception e) {
System.err.println(" ERROR +"+ e.getMessage()); System.err.println(" ERROR +"+ e.getMessage());
} }
@ -174,15 +209,20 @@ public class BeanInspector {
// otherwise try introspection and collect all public properties as strings // otherwise try introspection and collect all public properties as strings
Pair<String[],Object[]> nameVals = getPublicPropertiesOf(Target, true); Pair<String[],Object[]> nameVals = getPublicPropertiesOf(obj, true, true);
StringBuffer sbuf = new StringBuffer(type.getName()); StringBuffer sbuf = new StringBuffer();
if (withNewlines) sbuf.append('\n');
addIndent(sbuf, indentStr, indentDepth);
sbuf.append(type.getName());
sbuf.append("{"); sbuf.append("{");
for (int i=0; i<nameVals.head.length; i++) { for (int i=0; i<nameVals.head.length; i++) {
if (nameVals.head[i]!=null) { if (nameVals.head[i]!=null) {
if (withNewlines) sbuf.append('\n');
addIndent(sbuf, indentStr, indentDepth);
sbuf.append(nameVals.head[i]); sbuf.append(nameVals.head[i]);
sbuf.append("="); sbuf.append("=");
sbuf.append(toString(nameVals.tail[i])); sbuf.append(toString(nameVals.tail[i], delim, tight, indentStr, indentDepth+1, withNewlines));
sbuf.append(delim); sbuf.append(delim);
if (!tight) sbuf.append(" "); if (!tight) sbuf.append(" ");
} }
@ -192,6 +232,38 @@ public class BeanInspector {
return sbuf.toString(); return sbuf.toString();
} }
private static void addIndent(StringBuffer sbuf, String indentStr, int indentDepth) {
if (indentStr!=null && (indentDepth>0)) {
for (int i=0; i<indentDepth; i++) sbuf.append(indentStr);
}
}
private static String makeIndent(String indentStr, int indentDepth) {
if (indentStr!=null) {
if (indentDepth<1) return "";
else {
StringBuffer sbuf = new StringBuffer(indentStr);
for (int i=2; i<=indentDepth; i++) sbuf.append(indentStr);
return sbuf.toString();
}
} else return "";
}
public static void main(String[] args) {
System.out.println(BeanInspector.toString(new String[]{"asdf", "jdksfl", "werljk"}));
System.out.println(BeanInspector.toString(new Population()));
System.out.println(BeanInspector.toString(new GeneticAlgorithm()));
System.out.println("----");
System.out.println(BeanInspector.niceToString(new Population()));
System.out.println(BeanInspector.niceToString(new GeneticAlgorithm()));
System.out.println("----");
System.out.println(BeanInspector.toString(new Population(), ';', false, ">", 1, false));
System.out.println(BeanInspector.toString(new GeneticAlgorithm(), ';', false, ">", 1, false));
// System.out.println(BeanInspector.toString(new Population(), ',', false, "\t"));
// System.out.println(BeanInspector.toString(new GeneticAlgorithm(), ',', false, "\t"));
}
/** /**
* Retrieve names and values of instance fields which are accessible by getter method, optionally * Retrieve names and values of instance fields which are accessible by getter method, optionally
* by both getter and setter method. The returned arrays may contain null entries. * by both getter and setter method. The returned arrays may contain null entries.
@ -200,7 +272,7 @@ public class BeanInspector {
* @param target * @param target
* @return * @return
*/ */
public static Pair<String[],Object[]> getPublicPropertiesOf(Object target, boolean requireSetter) { public static Pair<String[],Object[]> getPublicPropertiesOf(Object target, boolean requireSetter, boolean showHidden) {
BeanInfo Info = null; BeanInfo Info = null;
PropertyDescriptor[] Properties = null; PropertyDescriptor[] Properties = null;
// MethodDescriptor[] Methods = null; // MethodDescriptor[] Methods = null;
@ -216,7 +288,8 @@ public class BeanInspector {
String[] nameArray = new String[Properties.length]; String[] nameArray = new String[Properties.length];
Object[] valArray = new Object[Properties.length]; Object[] valArray = new Object[Properties.length];
for (int i = 0; i < Properties.length; i++) { for (int i = 0; i < Properties.length; i++) {
if (Properties[i].isHidden() || Properties[i].isExpert()) { if ((Properties[i].isHidden() && !showHidden) || Properties[i].isExpert()) {
// System.err.println(Properties[i].getDisplayName() + " is " + ( (Properties[i].isExpert())? "expert": "hidden"));
continue; continue;
} }
String name = Properties[i].getDisplayName(); String name = Properties[i].getDisplayName();
@ -232,7 +305,7 @@ public class BeanInspector {
//System.out.println("name = "+name ); //System.out.println("name = "+name );
//System.out.println("type = "+type.getName() ); //System.out.println("type = "+type.getName() );
Object args[] = {}; Object args[] = {};
//System.out.println("m_Target"+m_Target.toString()); //System.out.println("m_obj"+m_obj.toString());
try { try {
nameArray[i]=name; nameArray[i]=name;
@ -247,23 +320,23 @@ public class BeanInspector {
/** /**
*@param Target Description of the Parameter *@param obj Description of the Parameter
*/ */
public static void showInfo(Object Target) { public static void showInfo(Object obj) {
System.out.println("Inspecting " + Target.getClass().getName()); System.out.println("Inspecting " + obj.getClass().getName());
// object itself // object itself
try { try {
if (Target instanceof java.lang.Integer) { if (obj instanceof java.lang.Integer) {
System.out.println(" Prop = Integer" + Target.toString()); System.out.println(" Prop = Integer" + obj.toString());
} }
if (Target instanceof java.lang.Boolean) { if (obj instanceof java.lang.Boolean) {
System.out.println(" Prop = Boolean" + Target.toString()); System.out.println(" Prop = Boolean" + obj.toString());
} }
if (Target instanceof java.lang.Long) { if (obj instanceof java.lang.Long) {
System.out.println(" Prop = Long" + Target.toString()); System.out.println(" Prop = Long" + obj.toString());
} }
if (Target instanceof java.lang.Double) { if (obj instanceof java.lang.Double) {
System.out.println(" Prop = Long" + Target.toString()); System.out.println(" Prop = Long" + obj.toString());
} }
} catch (Exception e) { } catch (Exception e) {
//System.out.println(" ERROR +"+ e.getMessage()); //System.out.println(" ERROR +"+ e.getMessage());
@ -273,7 +346,7 @@ public class BeanInspector {
PropertyDescriptor[] Properties = null; PropertyDescriptor[] Properties = null;
// MethodDescriptor[] Methods = null; // MethodDescriptor[] Methods = null;
try { try {
Info = Introspector.getBeanInfo(Target.getClass()); Info = Introspector.getBeanInfo(obj.getClass());
Properties = Info.getPropertyDescriptors(); Properties = Info.getPropertyDescriptors();
Info.getMethodDescriptors(); Info.getMethodDescriptors();
} catch (IntrospectionException ex) { } catch (IntrospectionException ex) {
@ -300,11 +373,11 @@ public class BeanInspector {
Object args[] = {}; Object args[] = {};
//System.out.println("m_Target"+m_Target.toString()); //System.out.println("m_Target"+m_Target.toString());
try { try {
Object value = getter.invoke(Target, args); Object value = getter.invoke(obj, args);
System.out.println("Inspecting name = " + name); System.out.println("Inspecting name = " + name);
if (value instanceof Integer) { if (value instanceof Integer) {
Object args2[] = {new Integer(999)}; Object args2[] = {new Integer(999)};
setter.invoke(Target, args2); setter.invoke(obj, args2);
} }
showInfo(value); showInfo(value);
} catch (Exception e) { } catch (Exception e) {
@ -390,7 +463,7 @@ public class BeanInspector {
if (paramTypes!=null && (methParamTypes.length==paramTypes.length)) { if (paramTypes!=null && (methParamTypes.length==paramTypes.length)) {
boolean mismatch = false; int i=0; boolean mismatch = false; int i=0;
while ((i<methParamTypes.length) && (!mismatch)) { while ((i<methParamTypes.length) && (!mismatch)) {
if (!methParamTypes[i].isAssignableFrom(paramTypes[i])) mismatch=true; if (!methParamTypes[i].isAssignableFrom(paramTypes[i]) && !isBoxableFrom(methParamTypes[i], paramTypes[i])) mismatch=true;
i++; i++;
} }
if (!mismatch) return method; // parameter match, otherwise search on if (!mismatch) return method; // parameter match, otherwise search on
@ -401,6 +474,41 @@ public class BeanInspector {
return null; return null;
} }
/**
* Check if the given first class is a primitive type and can be boxed to match the second class.
*
* @param clz1
* @param clz2
* @return
*/
private static boolean isBoxableFrom(Class clz1, Class clz2) {
Class box = getBoxedType(clz1);
if (box!=null && (clz2.isAssignableFrom(box))) {
return true;
} else return false;
}
/**
* For a primitive type, return the boxed referenced type.
* Return null for any non-primitive type.
*
* @param clz1
* @return
*/
public static Class getBoxedType(Class cls) {
if (cls.isPrimitive()) {
if (cls == double.class) return Double.class;
else if (cls == char.class) return Character.class;
else if (cls == int.class) return Integer.class;
else if (cls == boolean.class) return Boolean.class;
else if (cls == byte.class) return Byte.class;
else if (cls == short.class) return Short.class;
else if (cls == long.class) return Long.class;
else if (cls == float.class) return Float.class;
else return Void.class;
} else return null;
}
/** /**
* Just concatenates getClassDescription(obj) and getMemberDescriptions(obj, withValues). * Just concatenates getClassDescription(obj) and getMemberDescriptions(obj, withValues).
* *
@ -602,14 +710,15 @@ public class BeanInspector {
} }
/** /**
* Checks whether a type belongs to primitive (int, long, double, char etc.) or the Java encapsulations (Integer, Long etc.) * Checks whether a type belongs to primitive (int, long, double, char etc.)
* or the Java encapsulations (Integer, Long etc.)
* *
* @param cls * @param cls
* @return * @return
*/ */
public static boolean isJavaPrimitive(Class<?> cls) { public static boolean isJavaPrimitive(Class<?> cls) {
if (cls.isPrimitive()) return true; if (cls.isPrimitive()) return true;
if ((cls == Double.class) || (cls == Integer.class) || (cls == Boolean.class) if ((cls == Double.class) || (cls == Integer.class) || (cls == Boolean.class) || (cls == Character.class) || (cls == Void.class)
|| (cls == Byte.class) || (cls == Short.class) || (cls == Long.class) || (cls == Float.class)) return true; || (cls == Byte.class) || (cls == Short.class) || (cls == Long.class) || (cls == Float.class)) return true;
return false; return false;
} }