*
* @param context the transformation context
* @param klass the class set.
*/
public void transformCode(final Context context, final Klass klass) {
final ClassGen cg = klass.getClassGen();
ClassMetaData classMetaData = BcelMetaDataMaker.
createClassMetaData(context.getJavaClass(cg));
if (classFilter(classMetaData, cg)) {
return;
}
final Method[] methods = cg.getMethods();
// get the indexes for the <init> methods
List initIndexes = new ArrayList();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals("<init>")) {
initIndexes.add(new Integer(i));
}
}
final ConstantPoolGen cpg = cg.getConstantPool();
final String className = cg.getClassName();
final InstructionFactory factory = new InstructionFactory(cg);
final Set setFieldJoinPoints = new HashSet();
final Set getFieldJoinPoints = new HashSet();
boolean isClassAdvised = false;
for (int i = 0; i < methods.length; i++) {
// filter methods
if (methodFilter(methods[i])) {
continue;
}
MethodGen mg = new MethodGen(methods[i], className, cpg);
// do not modify anything within the hidden system methods
if (mg.getMethod().getName().startsWith(TransformationUtil.ASPECTWERKZ_PREFIX)) {
continue;
}
InstructionList il = mg.getInstructionList();
InstructionHandle ih = il.getStart();
// get the current field instruction
FieldInstruction currentGetFieldIns = null;
// search for all GETFIELD and GETSTATIC instructions and
// inserts the pre and post advices
while (ih != null) {
Instruction ins = ih.getInstruction();
// handle the java.util.Collection classes
if (ins instanceof GETFIELD || ins instanceof GETSTATIC) {
FieldInstruction checkMe = (FieldInstruction)ins;
// if the field is an added join point field => skip it
// needed if a field of type collection is both setField
// and getField advised
if (!checkMe.getFieldName(cpg).startsWith(TransformationUtil.JOIN_POINT_PREFIX)) {
currentGetFieldIns = checkMe;
}
}
if (ins instanceof INVOKEINTERFACE) {
final InvokeInstruction invokeIns = (InvokeInstruction)ins;
// do we have a collection?
if (invokeIns.getClassName(cpg).equals("java.util.Collection") ||
invokeIns.getClassName(cpg).equals("java.util.Enumeration") ||
invokeIns.getClassName(cpg).equals("java.util.Iterator") ||
invokeIns.getClassName(cpg).equals("java.util.List") ||
invokeIns.getClassName(cpg).equals("java.util.Map") ||
invokeIns.getClassName(cpg).equals("java.util.Set") ||
invokeIns.getClassName(cpg).equals("java.util.SortedMap") ||
invokeIns.getClassName(cpg).equals("java.util.SortedSet")) {
String methodName = invokeIns.getName(cpg);
// is the collection modified?
if (methodName.equals("add") ||
methodName.equals("addAll") ||
methodName.equals("set") ||
methodName.equals("remove") ||
methodName.equals("removeAll") ||
methodName.equals("retainAll") ||
methodName.equals("clear") ||
methodName.equals("put") ||
methodName.equals("putAll")) {
if (currentGetFieldIns == null) {
// is not a member field, continue
ih = ih.getNext();
continue;
}
final String fieldName = currentGetFieldIns.getName(cpg);
final String signature = currentGetFieldIns.getFieldType(cpg).
toString() + " " + fieldName;
final Type joinPointType = TransformationUtil.MEMBER_FIELD_SET_JOIN_POINT_TYPE;
FieldMetaData fieldMetaData =
BcelMetaDataMaker.createFieldMetaData(currentGetFieldIns, cpg);
String uuid = setFieldFilter(classMetaData, fieldMetaData);
if (uuid != null) {
final String fieldClassName = currentGetFieldIns.getClassName(cpg);
if (fieldClassName.equals(cg.getClassName())) {
// is NOT in static context
if (!mg.isStatic()) {
isClassAdvised = true;
insertPreAdvice(
il, ih, cg, fieldName,
factory, joinPointType);
insertPostAdvice(
il, ih.getNext(), cg,
fieldName, factory, joinPointType);
// store the join point field data
JoinPointFieldData data = new JoinPointFieldData(
fieldName, signature, joinPointType, uuid);
if (!setFieldJoinPoints.contains(data)) {
setFieldJoinPoints.add(data);
}
}
}
// set the current get field instruction to null
currentGetFieldIns = null;
}
}
}
}
// handle the getField instructions
else if (ins instanceof GETFIELD || ins instanceof GETSTATIC) {
final FieldInstruction gfIns = (FieldInstruction)ins;
String fieldName = gfIns.getName(cpg);
String signature = gfIns.getFieldType(cpg).toString() + " " + fieldName;
Type joinPointType = TransformationUtil.MEMBER_FIELD_GET_JOIN_POINT_TYPE;
FieldMetaData fieldMetaData = BcelMetaDataMaker.createFieldMetaData(gfIns, cpg);
String uuid = getFieldFilter(classMetaData, fieldMetaData);
if (uuid != null) {
final String fieldClassName = gfIns.getClassName(cpg);
if (fieldClassName.equals(cg.getClassName())) {
// is NOT in static context
if (!mg.isStatic()) {
isClassAdvised = true;
insertPreAdvice(
il, ih, cg, fieldName,
factory, joinPointType);
insertPostAdvice(
il, ih.getNext(), cg,
fieldName, factory, joinPointType);
// store the join point field data
JoinPointFieldData data = new JoinPointFieldData(
fieldName, signature, joinPointType, uuid);
if (!getFieldJoinPoints.contains(data)) {
getFieldJoinPoints.add(data);
}
}
}
}
}
// handle the setField instructions
else if (ins instanceof PUTFIELD || ins instanceof PUTSTATIC) {
final FieldInstruction pfIns = (FieldInstruction)ins;
String fieldName = pfIns.getName(cpg);
String signature = pfIns.getFieldType(cpg).toString() + " " + fieldName;
Type joinPointType = TransformationUtil.MEMBER_FIELD_SET_JOIN_POINT_TYPE;
FieldMetaData fieldMetaData =
BcelMetaDataMaker.createFieldMetaData(pfIns, cpg);
String uuid = setFieldFilter(classMetaData, fieldMetaData);
if (uuid != null) {
final String fieldClassName = pfIns.getClassName(cpg);
if (fieldClassName.equals(cg.getClassName())) {
// is NOT in static context
if (!mg.isStatic()) {
isClassAdvised = true;
insertPreAdvice(
il, ih, cg, fieldName,
factory, joinPointType);
insertPostAdvice(
il, ih.getNext(), cg,
fieldName, factory, joinPointType);
// store the join point field data
JoinPointFieldData data = new JoinPointFieldData(
fieldName, signature, joinPointType, uuid);
if (!setFieldJoinPoints.contains(data)) {
setFieldJoinPoints.add(data);
}
}
}
}
}
ih = ih.getNext();
}
if (isClassAdvised) {
mg.setMaxStack();
methods[i] = mg.getMethod();
}
}
// create the set field join point member fields
for (Iterator it = setFieldJoinPoints.iterator(); it.hasNext();) {
JoinPointFieldData data = (JoinPointFieldData)it.next();
addJoinPointMemberField(cpg, cg, data.getName(), data.getType());
// advise all the constructors
for (Iterator it2 = initIndexes.iterator(); it2.hasNext();) {
final int initIndex = ((Integer)it2.next()).intValue();
methods[initIndex] = createJoinPointMemberField(
cpg, cg, methods[initIndex], factory,
data.getName(), data.getSignature(),
data.getType(), data.getUuid());
}
}
// create the get field join point member fields
for (Iterator it = getFieldJoinPoints.iterator(); it.hasNext();) {
JoinPointFieldData data = (JoinPointFieldData)it.next();
addJoinPointMemberField(cpg, cg, data.getName(), data.getType());
// advise all the constructors
for (Iterator it2 = initIndexes.iterator(); it2.hasNext();) {
final int initIndex = ((Integer)it2.next()).intValue();
methods[initIndex] = createJoinPointMemberField(
cpg, cg, methods[initIndex], factory,
data.getName(), data.getSignature(),
data.getType(), data.getUuid());
}
}
cg.setMethods(methods);
}