/* 
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()); 
      
    } 
} 
 
            
       
  |