001/*
002 * Copyright 2012 The Kuali Foundation
003 * 
004 * Licensed under the Educational Community License, Version 1.0 (the
005 * "License"); you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 * http://www.opensource.org/licenses/ecl1.php
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016package org.kuali.student.common.spring;
017
018import java.io.Externalizable;
019import java.io.IOException;
020import java.io.ObjectInput;
021import java.io.ObjectOutput;
022import java.lang.reflect.InvocationHandler;
023import java.lang.reflect.Method;
024
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027import org.springframework.beans.factory.BeanFactory;
028import org.springframework.context.ApplicationContext;
029import org.springframework.context.support.ClassPathXmlApplicationContext;
030import org.springframework.util.ReflectionUtils;
031
032/**
033 * A serializable proxy for a spring bean.
034 * 
035 * It serialized the name of the bean when serialized.
036 * 
037 * This assumes a single application context will be used to find all beans being proxied.
038 * 
039 * @author Kuali Student Team 
040 *
041 */
042public class SerializableSpringBeanProxyInvocationHandler implements
043        InvocationHandler, Externalizable {
044    
045    private static final Logger log = LoggerFactory
046            .getLogger(SerializableSpringBeanProxyInvocationHandler.class);
047
048    private String beanName;
049    
050    private static BeanFactory BEAN_FACTORY;
051    
052    private transient Object beanDelegate;
053   
054
055    /**
056     * 
057     */
058    public SerializableSpringBeanProxyInvocationHandler() {
059        super();
060    }
061    
062    
063
064    /**
065     * @param applicationContext the applicationContext to set
066     */
067    public static void setApplicationContext(BeanFactory applicationContext) {
068        SerializableSpringBeanProxyInvocationHandler.BEAN_FACTORY = applicationContext;
069    }
070
071
072
073    /**
074     * @param beanName the beanName to set
075     */
076    public void setBeanName(String beanName) {
077        this.beanName = beanName;
078    }
079
080
081
082    /* (non-Javadoc)
083     * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
084     */
085    @Override
086    public void writeExternal(ObjectOutput out) throws IOException {
087
088        out.writeObject(beanName);
089        
090    }
091
092    /* (non-Javadoc)
093     * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
094     */
095    @Override
096    public void readExternal(ObjectInput in) throws IOException,
097            ClassNotFoundException {
098
099        this.beanName = (String) in.readObject();
100    }
101
102    /* (non-Javadoc)
103     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
104     */
105    @Override
106    public Object invoke(Object proxy, Method method, Object[] args)
107            throws Throwable {
108        
109        if (this.beanDelegate == null) {
110            
111            this.beanDelegate = BEAN_FACTORY.getBean(beanName);
112        }
113        
114        // delegate the call to the actual service to fulfill.
115        return ReflectionUtils.invokeMethod(method, beanDelegate, args);
116    
117    }
118    
119    
120}