"environment",
environment);
for (String name : names)
{
Environmental annotation = transformation.getFieldAnnotation(name, Environmental.class);
transformation.claimField(name, annotation);
String typeName = transformation.getFieldType(name);
// TODO: Check for primitives
// TAP5-417: Calls to javassist.runtime.Desc.getType() are showing up as method hot spots.
Class type = null;
try
{
type = classLoader.loadClass(typeName);
}
catch (ClassNotFoundException ex)
{
throw new RuntimeException(ex);
}
// TAP5-417: Changed the code to use EnvironmentalAccess, which encapsulates
// efficient caching.
String injectedTypeFieldName = transformation.addInjectedField(Class.class, "type", type);
// First we need (at page attach) to acquire the closure for the type.
String accessFieldName = transformation.addField(Modifier.PRIVATE, EnvironmentalAccess.class.getName(),
name + "_access");
String attachBody = String.format("%s = %s.getAccess(%s);",
accessFieldName, envField, injectedTypeFieldName);
transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE, attachBody);
// Clear the closure field when the page detaches. We'll get a new one when we next attach.
transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE,
accessFieldName + " = null;");
// Now build a read method that invokes peek() or peekRequired() on the closure. The closure
// is responsible for safe caching of the environmental value.
String methodName = transformation.newMemberName("environment_read", name);
TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, typeName, methodName, null,
null);
String body = String.format(
"return ($r) %s.%s();",
accessFieldName,
annotation.value() ? "peekRequired" : "peek");
transformation.addMethod(sig, body);
transformation.replaceReadAccess(name, methodName);
transformation.makeReadOnly(name);