Bugfix concerning inspection: a method must of course not only match in name but in signature.

This commit is contained in:
Marcel Kronfeld 2010-04-23 08:30:57 +00:00
parent b67213c92d
commit 6ea578615c
7 changed files with 110 additions and 112 deletions

View File

@ -1,20 +1,9 @@
package eva2.gui; package eva2.gui;
/*
* Title: EvA2
* Description:
* Copyright: Copyright (c) 2003
* Company: University of Tuebingen, Computer Architecture
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
* @version: $Revision: 202 $
* $Date: 2007-10-25 16:12:49 +0200 (Thu, 25 Oct 2007) $
* $Author: mkron $
*/
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.beans.BeanInfo; import java.beans.BeanInfo;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import java.beans.Introspector; import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -24,37 +13,19 @@ import java.util.List;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.tools.Pair; import eva2.tools.Pair;
import eva2.tools.SelectedTag; import eva2.tools.SelectedTag;
import eva2.tools.StringTools;
import eva2.tools.Tag; import eva2.tools.Tag;
/* /**
* ==========================================================================* * Some miscellaneous functions to help with Beans, reflection, conversion and generic display.
* CLASS DECLARATION *
* ========================================================================== * @author mkron, Holger Ulmer, Felix Streichert, Hannes Planatscher
*
*/ */
public class BeanInspector { public class BeanInspector {
public static boolean TRACE = false; public static boolean TRACE = false;
// public static int step = 0;
// public static String check(String s) {
// s=s.replace('$','_');
// s=s.replace(';','_');
//// String ret = null;
//// try {
//// RE r = new RE("\\[");
//// ret = r.subst(s,"");
//// //ret.substring();
//// //ret
//// } catch (Exception e) {e.getMessage();};
//// System.out.println("s="+s+" ret"+ret);
// if (s.equals("[D")) return "Double_Array";
// if (s.startsWith("[D")) return s.substring(2);
// if (s.startsWith("[L")) return s.substring(2);
// return s;
// }
/** /**
* Check for equality based on bean properties of two target objects. * Check for equality based on bean properties of two target objects.
*/ */
@ -354,7 +325,7 @@ public class BeanInspector {
* @return the return value of the called method or null * @return the return value of the called method or null
*/ */
public static Object callIfAvailable(Object obj, String mName, Object[] args) { public static Object callIfAvailable(Object obj, String mName, Object[] args) {
Method meth = hasMethod(obj, mName); Method meth = hasMethod(obj, mName, toClassArray(args));
if (meth != null) { if (meth != null) {
try { try {
return meth.invoke(obj, args); return meth.invoke(obj, args);
@ -367,18 +338,63 @@ public class BeanInspector {
} }
/** /**
* Check whether an object has a method by the given name. Return * Produce an array of Class instances matching the types of
* the given object array.
*
* @param o
* @return
*/
public static Class[] toClassArray(Object[] o) {
if (o==null) return null;
Class[] clz = new Class[o.length];
for (int i=0; i<o.length; i++) {
clz[i]=o.getClass();
}
return clz;
}
/**
* Check whether an object has a method by the given name and with
* matching signature considering the arguments. Return
* it if found, or null if not. * it if found, or null if not.
* *
* @param obj * @param obj
* @param mName the method name * @param mName the method name
* @param args the arguments, null allowed if the method takes no parameters
* @return the method or null if it isn't found * @return the method or null if it isn't found
*/ */
public static Method hasMethod(Object obj, String mName) { public static Method hasMethod(Object obj, String mName, Object[] args) {
return hasMethod(obj, mName, toClassArray(args));
}
/**
* Check whether an object has a method by the given name and
* with the given parameter signature. Return
* it if found, or null if not.
*
* @param obj
* @param mName the method name
* @param paramTypes the parameter types, null allowed if no parameters are expected
* @return the method or null if it isn't found
*/
public static Method hasMethod(Object obj, String mName, Class[] paramTypes) {
Class<?> cls = obj.getClass(); Class<?> cls = obj.getClass();
Method[] meths = cls.getMethods(); Method[] meths = cls.getMethods();
for (Method method : meths) { for (Method method : meths) {
if (method.getName().equals(mName)) return method; if (method.getName().equals(mName)) { // name match
Class[] methParamTypes = method.getParameterTypes();
if (paramTypes==null && methParamTypes.length==0) return method; // full match
else {
if (paramTypes!=null && (methParamTypes.length==paramTypes.length)) {
boolean mismatch = false; int i=0;
while ((i<methParamTypes.length) && (!mismatch)) {
if (!methParamTypes[i].equals(paramTypes[i])) mismatch=true;
i++;
}
if (!mismatch) return method; // parameter match, otherwise search on
} // parameter mismatch, search on
}
}
} }
return null; return null;
} }
@ -428,7 +444,7 @@ public class BeanInspector {
/** /**
* Return an info string on the members of the object class, containing name, type, optional * Return an info string on the members of the object class, containing name, type, optional
* value and tool tip text if available. The type is accompagnied by a tag "common" or "restricted", * value and tool tip text if available. The type is accompanied by a tag "common" or "restricted",
* indicating whether the member property is normal or hidden, meaning it may have effect depending * indicating whether the member property is normal or hidden, meaning it may have effect depending
* on settings of other members only, for instance. * on settings of other members only, for instance.
* *
@ -499,7 +515,7 @@ public class BeanInspector {
} }
// now look for a TipText method for this property // now look for a TipText method for this property
Method tipTextMethod = hasMethod(obj, name + "TipText"); Method tipTextMethod = hasMethod(obj, name + "TipText", null);
if (tipTextMethod == null) { if (tipTextMethod == null) {
memberInfoBf.append("\tNo further hint."); memberInfoBf.append("\tNo further hint.");
} else { } else {
@ -720,4 +736,48 @@ public class BeanInspector {
return false; return false;
} }
} }
/** This method simply looks for an appropriate tiptext
* @param name The name of the property
* @param methods A list of methods to search.
* @param target The target object
* @return String for the tooltip.
*/
public static String getToolTipText(String name, MethodDescriptor[] methods, Object target, boolean stripToolTipToFirstPoint, int toHTMLLen) {
String result = "";
String tipName = name + "TipText";
for (int j = 0; j < methods.length; j++) {
String mname = methods[j].getDisplayName();
Method meth = methods[j].getMethod();
if (mname.equals(tipName)) {
if (meth.getReturnType().equals(String.class)) {
try {
Object args[] = { };
String tempTip = (String)(meth.invoke(target, args));
result = tempTip;
if (stripToolTipToFirstPoint) {
int ci = tempTip.indexOf('.');
if (ci > 0) result = tempTip.substring(0, ci);
}
} catch (Exception ex) {
}
break;
}
}
} // end for looking for tiptext
if (toHTMLLen > 0) return StringTools.toHTML(result, toHTMLLen);
else return result;
}
/**
* This method simply looks for an appropriate tool tip text
*
* @param name The name of the property
* @param methods A list of methods to search.
* @param target The target object
* @return String for the tooltip.
*/
public static String getToolTipText(String name, MethodDescriptor[] methods, Object target) {
return getToolTipText(name, methods, target, false, 0);
}
} }

View File

@ -45,7 +45,6 @@ import javax.swing.JTextArea;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import eva2.tools.EVAHELP; import eva2.tools.EVAHELP;
import eva2.tools.StringTools;
/*==========================================================================* /*==========================================================================*
* CLASS DECLARATION * CLASS DECLARATION
*==========================================================================*/ *==========================================================================*/
@ -278,7 +277,7 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
} }
editor.setValue(value); editor.setValue(value);
m_TipTexts[i] = getToolTipText(name, m_Methods, m_Target, tipTextLineLen); m_TipTexts[i] = BeanInspector.getToolTipText(name, m_Methods, m_Target, stripToolTipToFirstPoint, tipTextLineLen);
// System.out.println("PSP editor class: " + editor.getClass()); // System.out.println("PSP editor class: " + editor.getClass());
newView = getView(editor); newView = getView(editor);
@ -923,39 +922,6 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
} }
} }
} }
/** This method simply looks for an appropriate tiptext
* @param name The name of the property
* @param methods A list of methods to search.
* @param target The target object
* @return String for the tooltip.
*/
private String getToolTipText(String name, MethodDescriptor[] methods, Object target, int toHTMLLen) {
String result = "";
String tipName = name + "TipText";
for (int j = 0; j < methods.length; j++) {
String mname = methods[j].getDisplayName();
Method meth = methods[j].getMethod();
if (mname.equals(tipName)) {
if (meth.getReturnType().equals(String.class)) {
try {
Object args[] = { };
String tempTip = (String)(meth.invoke(target, args));
result = tempTip;
if (stripToolTipToFirstPoint) {
int ci = tempTip.indexOf('.');
if (ci > 0) result = tempTip.substring(0, ci);
}
} catch (Exception ex) {
}
break;
}
}
} // end for looking for tiptext
if (toHTMLLen > 0) return StringTools.toHTML(result, toHTMLLen);
else return result;
}
} }

View File

@ -954,7 +954,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
sb.append(b[i].getStringRepresentation()); sb.append(b[i].getStringRepresentation());
if ((i+1) < b.length) sb.append(separator); if ((i+1) < b.length) sb.append(separator);
} }
} else if (BeanInspector.hasMethod(individual, "toString") != null) { } else if (BeanInspector.hasMethod(individual, "toString", null) != null) {
EVAERROR.errorMsgOnce("warning in AbstractEAIndividual::getDefaultDataString: type " + individual.getClass() + " has no default data representation, using toString..."); EVAERROR.errorMsgOnce("warning in AbstractEAIndividual::getDefaultDataString: type " + individual.getClass() + " has no default data representation, using toString...");
return individual.toString(); return individual.toString();
} else { } else {

View File

@ -162,7 +162,7 @@ public class ParameterControlManager implements InterfaceParameterControl, Seria
for (int i=0; i<objs.length; i++) { for (int i=0; i<objs.length; i++) {
if (objs[i]!=null) { if (objs[i]!=null) {
// TODO avoid hasMethod recreate some interface for this?? // TODO avoid hasMethod recreate some interface for this??
if (BeanInspector.hasMethod(objs[i], "getParamControl")!=null) controllables.add(objs[i]); if (BeanInspector.hasMethod(objs[i], "getParamControl", null)!=null) controllables.add(objs[i]);
} }
} }
return controllables.toArray(new Object[controllables.size()]); return controllables.toArray(new Object[controllables.size()]);

View File

@ -27,6 +27,7 @@ public class SimpleProblemWrapper extends AbstractOptimizationProblem {
transient Plot m_plot = null; transient Plot m_plot = null;
transient AbstractEAIndividual bestIndy = null; transient AbstractEAIndividual bestIndy = null;
String plotFunc = "plotBest"; String plotFunc = "plotBest";
transient Class[] plotFuncSig = new Class[]{Plot.class, AbstractEAIndividual.class};
transient private boolean resetTemplate = true; transient private boolean resetTemplate = true;
public SimpleProblemWrapper() { public SimpleProblemWrapper() {
@ -165,7 +166,7 @@ public class SimpleProblemWrapper extends AbstractOptimizationProblem {
initTemplate(); initTemplate();
GenericObjectEditor.setShowProperty(getClass(), "noise", (simProb instanceof SimpleProblemDouble)); GenericObjectEditor.setShowProperty(getClass(), "noise", (simProb instanceof SimpleProblemDouble));
GenericObjectEditor.setShowProperty(getClass(), "defaultRange", (simProb instanceof SimpleProblemDouble)); GenericObjectEditor.setShowProperty(getClass(), "defaultRange", (simProb instanceof SimpleProblemDouble));
if (BeanInspector.hasMethod(simProb, plotFunc) != null) { if (BeanInspector.hasMethod(simProb, plotFunc, plotFuncSig) != null) {
if (m_plot == null) openPlot(); if (m_plot == null) openPlot();
else { else {
if (!m_plot.isValid()) { if (!m_plot.isValid()) {

View File

@ -399,7 +399,7 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
System.out.println("Best bef: " + BeanInspector.toString(m_Optimizer.getPopulation().getBestFitness())); System.out.println("Best bef: " + BeanInspector.toString(m_Optimizer.getPopulation().getBestFitness()));
} }
if (BeanInspector.hasMethod(m_Optimizer, "getLastModelPopulation")!=null) { if (BeanInspector.hasMethod(m_Optimizer, "getLastModelPopulation", null)!=null) {
Object pc = BeanInspector.callIfAvailable(m_Optimizer, "getLastTrainingPatterns", null); Object pc = BeanInspector.callIfAvailable(m_Optimizer, "getLastTrainingPatterns", null);
System.out.println("MAPSO train set bef optSpec: " + BeanInspector.callIfAvailable(pc, "getStringRepresentation", null)); System.out.println("MAPSO train set bef optSpec: " + BeanInspector.callIfAvailable(pc, "getStringRepresentation", null));
} }

View File

@ -220,7 +220,7 @@ public abstract class AbstractObjectEditor implements PropertyEditor, java.beans
result.m_PropertyType = props[i].getPropertyType(); result.m_PropertyType = props[i].getPropertyType();
result.m_Name = props[i].getDisplayName(); result.m_Name = props[i].getDisplayName();
result.m_Label = new JLabel(result.m_Name, SwingConstants.RIGHT); result.m_Label = new JLabel(result.m_Name, SwingConstants.RIGHT);
result.m_TipText = this.getToolTipText(result.m_Name, methods, target); result.m_TipText = BeanInspector.getToolTipText(result.m_Name, methods, target);
try { try {
result.m_Value = result.m_getMethod.invoke(target, args); result.m_Value = result.m_getMethod.invoke(target, args);
// result.m_Editor = PropertyEditorProvider.findEditor(result.m_Value.getClass()); // result.m_Editor = PropertyEditorProvider.findEditor(result.m_Value.getClass());
@ -251,35 +251,6 @@ public abstract class AbstractObjectEditor implements PropertyEditor, java.beans
return result; return result;
} }
/** This method simply looks for an appropriate tiptext
* @param name The name of the property
* @param methods A list of methods to search.
* @param target The target object
* @return String for the tooltip.
*/
public String getToolTipText(String name, MethodDescriptor[] methods, Object target) {
String result = "No tooltip available.";
String tipName = name + "TipText";
for (int j = 0; j < methods.length; j++) {
String mname = methods[j].getDisplayName();
Method meth = methods[j].getMethod();
if (mname.equals(tipName)) {
if (meth.getReturnType().equals(String.class)) {
try {
Object args[] = { };
String tempTip = (String)(meth.invoke(target, args));
int ci = tempTip.indexOf('.');
if (ci < 0) result = tempTip;
else result = tempTip.substring(0, ci);
} catch (Exception ex) {
}
return result;
}
}
} // end for looking for tiptext
return result;
}
/** This method tries to find a suitable view for a given Property /** This method tries to find a suitable view for a given Property
* @param editor The property the select a view for. * @param editor The property the select a view for.
*/ */