ctClass.instrument(
new ExprEditor() {
public void edit(FieldAccess fieldAccess) throws CannotCompileException {
try {
CtBehavior where = null;
try {
where = fieldAccess.where();
}
catch (RuntimeException e) {
// <clinit> access leads to a bug in Javassist
where = ctClass.getClassInitializer();
}
// filter caller context
if (methodFilter(where)) {
return;
}
// get field accessed information
final String fieldName = fieldAccess.getFieldName();
final String fieldSignature = fieldAccess.getField().getType().getName() + ' ' +
fieldName;
FieldMetaData fieldMetaData = JavassistMetaDataMaker.createFieldMetaData(
fieldAccess.getField()
);
// handle GET
if (fieldAccess.isReader() &&
!getFieldFilter(definition, classMetaData, fieldMetaData)) {
// check the declaring class for the field is not the same as target class,
// if that is the case then we have have class loaded and set in the ___AW_clazz already
String declaringClassFieldName = TransformationUtil.STATIC_CLASS_FIELD;
CtClass declaringClass = fieldAccess.getField().getDeclaringClass();
if (!declaringClass.getName().equals(where.getDeclaringClass().getName())) {
declaringClassFieldName =
addFieldAccessDeclaringClassField(declaringClass, fieldAccess.getField());
}
//TODO ALEX might need to review since SET is not handled gracefully that way
StringBuffer body = new StringBuffer();
StringBuffer callBody = new StringBuffer();
callBody.append(TransformationUtil.JOIN_POINT_MANAGER_FIELD);
callBody.append('.');
callBody.append(TransformationUtil.PROCEED_WITH_GET_JOIN_POINT_METHOD);
callBody.append('(');
callBody.append(TransformationUtil.calculateHash(fieldAccess.getField()));
callBody.append(',');
callBody.append(m_joinPointIndex);
if (Modifier.isStatic(fieldAccess.getField().getModifiers())) {
callBody.append(", (Object)null, ");
}
else {
callBody.append(", $0, ");
}
callBody.append(declaringClassFieldName);
callBody.append(",\"");
callBody.append(fieldSignature);
callBody.append("\");");
// handles advice returns null and fiel is primitive type
if (!fieldAccess.getField().getType().isPrimitive()) {
body.append("$_ = ($r)");
body.append(callBody.toString());
}
else {
String localResult = TransformationUtil.ASPECTWERKZ_PREFIX + "res";
body.append("{ Object ").append(localResult).append(" = ");
body.append(callBody.toString());
body.append("if (").append(localResult).append(" != null)");
body.append("$_ = ($r) ").append(localResult).append("; else ");
body.append("$_ = ");
body.append(
JavassistHelper.getDefaultPrimitiveValue(
fieldAccess.getField().getType()
)
);
body.append("; }");
}
fieldAccess.replace(body.toString());
context.markAsAdvised();
m_joinPointIndex++;
}
// handle SET
if (fieldAccess.isWriter() &&
!setFieldFilter(definition, classMetaData, fieldMetaData)) {
// check the declaring class for the field is not the same as target class,
// if that is the case then we have have class loaded and set in the ___AW_clazz already
String declaringClassFieldName = TransformationUtil.STATIC_CLASS_FIELD;
CtClass declaringClass = fieldAccess.getField().getDeclaringClass();
if (!declaringClass.getName().equals(where.getDeclaringClass().getName())) {
declaringClassFieldName =
addFieldAccessDeclaringClassField(declaringClass, fieldAccess.getField());
}
//TODO ALEX think about null advice