constructor.setBody("super();");
result.addConstructor(constructor);
CtClass object = pool.get(Object.class.getName());
JBossStringBuilder buffer = new JBossStringBuilder();
// Signature
buffer.append("public Object invoke(Object target, Object[] args) throws Throwable {");
boolean isInstanceMethod = Modifier.isStatic(ctMethod.getModifiers()) == false;
// Check for null target
if (check && isInstanceMethod)
{
buffer.append("if (target == null) throw new IllegalArgumentException(\"Null target for ");
buffer.append(ctMethod.getName()).append(ctMethod.getSignature()).append("\");");
}
// Check the target
CtClass declaring = ctMethod.getDeclaringClass();
boolean needsCast = isInstanceMethod && object.equals(declaring) == false;
if (check && needsCast)
{
buffer.append("if (target instanceof ").append(declaring.getName()).append(" == false) ");
buffer.append("throw new IllegalArgumentException(\"Target \" + target + \"");
buffer.append(" is not an instance of ").append(declaring.getName());
buffer.append(" for ").append(ctMethod.getName()).append(ctMethod.getSignature()).append("\");");
}
// Check the parameters
CtClass[] params = ctMethod.getParameterTypes();
if (check)
{
// Wrong number of args?
if (params.length != 0)
{
buffer.append("if (args == null || args.length != ").append(params.length).append(") ");
buffer.append("throw new IllegalArgumentException(\"Expected ").append(params.length).append(" parameter(s)");
buffer.append(" for ").append(ctMethod.getName()).append(ctMethod.getSignature()).append("\");");
}
else
{
// Didn't expect args
buffer.append("if (args != null && args.length != 0)");
buffer.append("throw new IllegalArgumentException(\"Expected no parameters");
buffer.append(" for ").append(ctMethod.getName()).append(ctMethod.getSignature()).append("\");");
}
for (int i = 0; i < params.length; ++i)
{
if (object.equals(params[i]) == false)
{
String paramType = getBoxedType(params[i]);
// Primitives can't be null
if (params[i].isPrimitive())
{
buffer.append("if (args[").append(i).append("] == null) ");
buffer.append("throw new IllegalArgumentException(\"Parameter ").append(i);
buffer.append(" cannot be null for ").append(params[i].getName());
buffer.append(" for ").append(ctMethod.getName()).append(ctMethod.getSignature()).append("\");");
}
// Check the parameter types
buffer.append("if (args[").append(i).append("] != null && ");
buffer.append("args[").append(i).append("] instanceof ").append(paramType).append(" == false) ");
buffer.append("throw new IllegalArgumentException(\"Parameter ").append(i).append(" \" + args[").append(i).append("] + \"");
buffer.append(" is not an instance of ").append(paramType);
buffer.append(" for ").append(ctMethod.getName()).append(ctMethod.getSignature()).append("\");");
}
}
}
// Add a return and box the return type if necessary
CtClass returnType = ctMethod.getReturnType();
boolean isVoid = CtClass.voidType.equals(returnType);
boolean isPrimitive = returnType.isPrimitive();
if (isVoid == false)
{
buffer.append("return ");
if (isPrimitive)
buffer.append("new ").append(getBoxedType(returnType)).append('(');
}
// Instance method
if (isInstanceMethod)
{
buffer.append('(');
if (needsCast)
buffer.append("(").append(declaring.getName()).append(')');
buffer.append("target).");
}
else
{
// Static method
buffer.append(declaring.getName()).append('.');
}
// Add the method name
buffer.append(ctMethod.getName()).append('(');
// Add the parameters
for (int i = 0; i < params.length; ++i)
{
buffer.append('(');
// Cast the parameters
if (object.equals(params[i]) == false)
buffer.append("(").append(getBoxedType(params[i])).append(')');
buffer.append("args[").append(i).append("])");
// Unbox primitive parameters
if (params[i].isPrimitive())
unbox(buffer, params[i]);
if (i < params.length - 1)
buffer.append(", ");
}
buffer.append(')');
// Complete the boxing of the return value
if (isVoid == false && isPrimitive)
buffer.append(')');
buffer.append(';');
// Add a return null if there is no return value
if (isVoid)
buffer.append("return null;");
buffer.append('}');
// Compile it
String code = buffer.toString();
try
{
CtMethod invoke = CtNewMethod.make(code, result);
result.addMethod(invoke);
}