private void buildMutator(EnhancementOperation op, String parameterName,
String propertyName, Class propertyType, String fieldName,
String defaultFieldName, String cachedFieldName, Location location)
{
BodyBuilder builder = new BodyBuilder();
builder.begin();
// The mutator method may be invoked from finishLoad(), in which
// case it changes the default value for the parameter property, if the
// parameter
// is not bound.
builder.addln("if (! isInActiveState())");
builder.begin();
builder.addln("{0} = $1;", defaultFieldName);
builder.addln("return;");
builder.end();
// In the normal state, we update the binding firstm, and it's an error
// if the parameter is not bound.
addBindingReference(builder, "binding", parameterName);
builder.addln("if (binding == null)");
builder
.addln(
" throw new {0}(\"Parameter ''{1}'' is not bound and can not be updated.\");",
ApplicationRuntimeException.class.getName(),
parameterName);
// Always updated the binding first (which may fail with an exception).
builder.addln("binding.setObject(($w) $1);");
// While rendering, we store the updated value for fast
// access again (while the component is still rendering).
// The property value will be reset to default by cleanupAfterRender().
builder.addln("if (isRendering())");
builder.begin();
builder.addln("{0} = $1;", fieldName);
builder.addln("{0} = true;", cachedFieldName);
builder.end();
builder.end();
String mutatorMethodName = EnhanceUtils
.createMutatorMethodName(propertyName);
op.addMethod(Modifier.PUBLIC, new MethodSignature(void.class,
mutatorMethodName, new Class[] { propertyType }, null), builder
.toString(), location);
}