String name = ClassFabUtils.generateClassName("Instantiator");
ClassFab cf = _classFactory.newClass(name, AbstractInstantiator.class);
BodyBuilder constructor = new BodyBuilder();
// This is realy -1 + 2: The first value in _constructorArgs is the InternalComponentResources, which doesn't
// count toward's the Instantiator's constructor ... then we add in the Model and String description.
// It's tricky because there's the constructor parameters for the Instantiator, most of which are stored
// in fields and then used as the constructor parameters for the Component.
Class[] constructorParameterTypes = new Class[_constructorArgs.size() + 1];
Object[] constructorParameterValues = new Object[_constructorArgs.size() + 1];
constructorParameterTypes[0] = ComponentModel.class;
constructorParameterValues[0] = _componentModel;
constructorParameterTypes[1] = String.class;
constructorParameterValues[1] = String.format("Instantiator[%s]", componentClassName);
BodyBuilder newInstance = new BodyBuilder();
newInstance.add("return new %s($1", componentClassName);
constructor.begin();
// Pass the model and description to AbstractInstantiator
constructor.addln("super($1, $2);");
// Again, skip the (implicit) InternalComponentResources field, that's
// supplied to the Instantiator's newInstance() method.
for (int i = 1; i < _constructorArgs.size(); i++)
{
ConstructorArg arg = _constructorArgs.get(i);
CtClass argCtType = arg.getType();
Class argType = toClass(argCtType.getName());
boolean primitive = argCtType.isPrimitive();
Class fieldType = primitive ? ClassFabUtils.getPrimitiveType(argType) : argType;
String fieldName = "_param_" + i;
constructorParameterTypes[i + 1] = argType;
constructorParameterValues[i + 1] = arg.getValue();
cf.addField(fieldName, fieldType);
// $1 is model, $2 is description, to $3 is first dynamic parameter.
constructor.add("%s = $%d", fieldName, i + 2);
if (primitive)
{
String methodName = ClassFabUtils.getUnwrapMethodName(argType);
constructor.add(".%s()", methodName);
}
constructor.addln(";");
newInstance.add(", %s", fieldName);
}
constructor.end();
newInstance.addln(");");
cf.addConstructor(constructorParameterTypes, null, constructor.toString());
cf.addMethod(Modifier.PUBLIC, NEW_INSTANCE_SIGNATURE, newInstance.toString());
Class instantiatorClass = cf.createClass();
try
{