}
private Object createProxyInstance(final ObjectCreator creator, final ServiceProxyToken token,
final Class serviceInterface, final Class serviceImplementation, final String description)
{
ClassInstantiator instantiator = proxyFactory.createProxy(serviceInterface, new PlasticClassTransformer()
{
public void transform(final PlasticClass plasticClass)
{
plasticClass.introduceInterface(Serializable.class);
final PlasticField creatorField = plasticClass.introduceField(ObjectCreator.class, "creator").inject(
creator);
final PlasticField tokenField = plasticClass.introduceField(ServiceProxyToken.class, "token").inject(
token);
PlasticMethod delegateMethod = plasticClass.introducePrivateMethod(serviceInterface.getName(),
"delegate", null, null);
// If not concerned with efficiency, this might be done with method advice instead.
delegateMethod.changeImplementation(new InstructionBuilderCallback()
{
public void doBuild(InstructionBuilder builder)
{
builder.loadThis().getField(plasticClass.getClassName(), creatorField.getName(),
ObjectCreator.class);
builder.invoke(ObjectCreator.class, Object.class, "createObject").checkcast(serviceInterface)
.returnResult();
}
});
for (Method m : serviceInterface.getMethods())
{
plasticClass.introduceMethod(m).delegateTo(delegateMethod);
}
plasticClass.introduceMethod(WRITE_REPLACE).changeImplementation(new InstructionBuilderCallback()
{
public void doBuild(InstructionBuilder builder)
{
builder.loadThis()
.getField(plasticClass.getClassName(), tokenField.getName(), ServiceProxyToken.class)
.returnResult();
}
});
plasticClass.addToString(description);
}
});
return instantiator.newInstance();
}