Is there a way to automatically insert code into a method?
I have the following typical field with a getter and setter and I would like to insert the indicated code into the setter method that records if the field was modified as well to insert the indicated "isFirstNameModified" field to also track if the field was modified or not.
public class Person {
Set<String> updatedFields = new LinkedHashSet<String>();
String firstName;
public String getFirstName(){
return firstName;
}
boolean isFirstNameChanged = false; // This code is inserted later
public void setFirstName(String firstName){
if( !isFirstNameChanged ){ // This code is inserted later
isFirstNameChanged = true; // This code is inserted later
updatedFields.add("firstName"); // This code is inserted later
} // This code is inserted later
this.firstName = firstName;
}
}
I'm also not sure if I can the subset of the method name as a string from inside the method itself as indicated on the line where I add the fieldName as a string into the set of updated fields: updatedFields.add("firstName");
. And I'm not sure how to insert fields into a class where I add the boolean field that tracks if the field has been modified or not before (for efficiency to prevent having to manipulate the Set): boolean isFirstNameChanged = false;
It seems to most obvious answer to this would be to use code templates inside eclipse, but I'm concerned about having to go back and change the code later.
I Should have used this simpler code instead of the example above. All it does is add the name of the field as a string to a set.
public class Person {
Set<String> updatedFields = new LinkedHashSet<String>();
String firstName;
public String getFirstName(){
return firstName;
}
public void setFirstName(String firstName){
updatedFields.add("firstName"); // This code is inserted later
this.firstName = firstName;
}
}
Yes you can, one approach is to use some form of byte code manipulation (e.g. javassist, ASM, BCEL) or a higher level AOP library sit on top of one of these tools, e.g. AspectJ, JBoss AOP.
Note: most JDO libraries do this for handling persistence.
Here is an example using javassist:
public class Person {
private String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
public static void rewritePersonClass() throws NotFoundException, CannotCompileException {
ClassPool pool = ClassPool.getDefault();
CtClass ctPerson = pool.get("Person");
CtClass ctSet = pool.get("java.util.LinkedHashSet");
CtField setField = new CtField(ctSet, "updatedFields", ctPerson);
ctPerson.addField(setField, "new java.util.LinkedHashSet();");
CtMethod method = ctPerson.getDeclaredMethod("setFirstName");
method.insertBefore("updatedFields.add(\"firstName\");");
ctPerson.toClass();
}
public static void main(String[] args) throws Exception {
rewritePersonClass();
Person p = new Person();
p.setFirstName("foo");
Field field = Person.class.getDeclaredField("updatedFields");
field.setAccessible(true);
Set<?> s = (Set<?>) field.get(p);
System.out.println(s);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With