/*
Pro Spring
By Rob Harrop
Jan Machacek
ISBN: 1-59059-461-4
Publisher: Apress
*/
///////////////////////////////////////////////////////////////////////////////////////
public interface IsModified {
public boolean isModified();
}
///////////////////////////////////////////////////////////////////////////////////////
import org.springframework.aop.support.DefaultIntroductionAdvisor;
public class IsModifiedAdvisor extends DefaultIntroductionAdvisor {
public IsModifiedAdvisor() {
super(new IsModifiedMixin());
}
}
///////////////////////////////////////////////////////////////////////////////////////
public class TargetBean {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
///////////////////////////////////////////////////////////////////////////////////////
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
public class IsModifiedMixin extends DelegatingIntroductionInterceptor
implements IsModified {
private boolean isModified = false;
private Map methodCache = new HashMap();
public boolean isModified() {
return isModified;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
if (!isModified) {
if ((invocation.getMethod().getName().startsWith("set"))
&& (invocation.getArguments().length == 1)) {
// invoke the corresponding get method to see
// if the value has actually changed
Method getter = getGetter(invocation.getMethod());
if (getter != null) {
// modification check is unimportant
// for write only methods
Object newVal = invocation.getArguments()[0];
Object oldVal = getter.invoke(invocation.getThis(), null);
if((newVal == null) && (oldVal == null)) {
isModified = false;
} else if((newVal == null) && (oldVal != null)) {
isModified = true;
} else if((newVal != null) && (oldVal == null)) {
isModified = true;
} else {
isModified = (!newVal.equals(oldVal));
}
}
}
}
return super.invoke(invocation);
}
private Method getGetter(Method setter) {
Method getter = null;
// attempt cache retrieval.
getter = (Method) methodCache.get(setter);
if (getter != null) {
return getter;
}
String getterName = setter.getName().replaceFirst("set", "get");
try {
getter = setter.getDeclaringClass().getMethod(getterName, null);
// cache getter
synchronized (methodCache) {
methodCache.put(setter, getter);
}
return getter;
} catch (NoSuchMethodException ex) {
// must be write only
return null;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.framework.ProxyFactory;
public class IntroductionExample {
public static void main(String[] args) {
// create the target
TargetBean target = new TargetBean();
target.setName("Name");
// create the advisor
IntroductionAdvisor advisor = new IsModifiedAdvisor();
// create the proxy
ProxyFactory pf = new ProxyFactory();
pf.setTarget(target);
pf.addAdvisor(advisor);
pf.setOptimize(true);
TargetBean proxy = (TargetBean)pf.getProxy();
IsModified proxyInterface = (IsModified)proxy;
// test interfaces
System.out.println("Is TargetBean?: " + (proxy instanceof TargetBean));
System.out.println("Is IsModified?: " + (proxy instanceof IsModified));
// test is modified implementation
System.out.println("Has been modified?: " + proxyInterface.isModified());
proxy.setName("Rob Harrop");
System.out.println("Has been modified?: " + proxyInterface.isModified());
proxy.setName("Joe Schmoe");
System.out.println("Has been modified?: " + proxyInterface.isModified());
}
}
|