package com.panopset;
import java.util.StringTokenizer;
/**
* Convert String representation of a Java method and parameters to a reflection
* execution.
*
* Parameters must be String objects.
*
* @author Karl Dinwiddie
*/
public final class ReflectionInvoker {
/**
* Map provider.
*/
private MapProvider pmapProvider;
/**
* Object.
*/
private Object pobject;
/**
* Class.
*/
private Class<?> pclazz;
/**
* Method.
*/
private String pmethod;
/**
* Parameters.
*/
private String pparms;
/**
* Use reflection to execute the given method.
*
* @return String, empty String if invoked method returns void, otherwise
* results of returned object's toString() function.
* @throws Exception
* Exception.
*/
public String exec() throws Exception {
StringTokenizer st = new StringTokenizer(pparms, ",");
Object[] args = new String[st.countTokens()];
Class<?>[] parmTypes = new Class<?>[st.countTokens()];
int i = 0;
while (st.hasMoreTokens()) {
String key = st.nextToken();
String val = key;
if (pmapProvider != null) {
String s = pmapProvider.get(key);
if (s != null) {
val = s;
}
}
if (val == null) {
val = key;
}
args[i] = val;
parmTypes[i] = String.class;
i++;
}
Object rtn = pclazz.getMethod(pmethod, parmTypes).invoke(pobject, args);
if (rtn == null) {
return "";
}
return rtn.toString();
}
/**
*
* ReflectionInvoker builder.
*
*/
public static final class Builder {
/**
* Object.
*/
private Object bobject;
/**
* Class name.
*/
private String bclassName;
/**
* Class.
*/
private Class<?> bclazz;
/**
* Method.
*/
private String bmethod;
/**
* Parameters.
*/
private String bparms;
/**
* Map provider.
*/
private MapProvider bmapProvider;
/**
* @return Reflection invoker.
* @throws Exception
* Exception.
*/
public ReflectionInvoker construct() throws Exception {
ReflectionInvoker rtn = new ReflectionInvoker();
rtn.pobject = bobject;
if (bobject == null) {
if (bclazz == null) {
rtn.pclazz = Class.forName(bclassName);
} else {
rtn.pclazz = bclazz;
}
} else {
rtn.pclazz = bobject.getClass();
}
rtn.pmethod = bmethod;
rtn.pparms = bparms;
rtn.pmapProvider = bmapProvider;
return rtn;
}
/**
* Optional, if not specified, either className or classMethodAndParms
* must be specified.
*
* @param object
* Object method is to be invoked on.
* @return Builder.
*/
public Builder object(final Object object) {
this.bobject = object;
return this;
}
/**
* Optional, if not specified, either object or classMethodAndParms must
* be specified.
*
* @param className
* className
* @return Builder.
*/
public Builder className(final String className) {
this.bclassName = className;
return this;
}
/**
* If not specified, static methods only may be invoked.
*
* @param clazz
* Class.
* @return Builder.
*/
public Builder clazz(final Class<?> clazz) {
this.bclazz = clazz;
return this;
}
/**
*
* @param method
* methodName
* @return Builder.
*/
public Builder method(final String method) {
this.bmethod = method;
return this;
}
/**
*
* @param parms
* parm1,parm2
* @return Builder
*/
public Builder parms(final String parms) {
this.bparms = parms;
return this;
}
/**
* Optional mapProvider. If specified, the mapProvider will be checked
* for parameter values. If the parameter does not match any of the
* mapProvider's keys, then the parameter is simply used by itself.
*
* @param mapProvider
* Map provider.
* @return Builder.
*/
public Builder mapProvider(final MapProvider mapProvider) {
this.bmapProvider = mapProvider;
return this;
}
/**
*
* @param methodAndParms
* method(parm1,parm2)
* @return Builder.
*/
public Builder methodAndParms(final String methodAndParms) {
int paramsStart = methodAndParms.indexOf("(");
if (paramsStart < 2) {
throw new RuntimeException("Format "
+ "should be function(parms), found:" + methodAndParms);
}
bmethod = methodAndParms.substring(0, paramsStart);
bparms = methodAndParms.substring(paramsStart + 1, methodAndParms
.length() - 1);
return this;
}
/**
* Optional, if not specified either object or className must be
* specified.
*
* @param classMethodAndParms
* com.company.Class.method(parms)
* @return Builder.
*/
public Builder classMethodAndParms(final String classMethodAndParms) {
int methodStart = classMethodAndParms.lastIndexOf(".");
String className = classMethodAndParms.substring(0, methodStart);
String methodAndParms = classMethodAndParms
.substring(methodStart + 1);
return className(className).methodAndParms(methodAndParms);
}
}
/**
* Prevent instantiation.
*/
private ReflectionInvoker() {
}
}
|