001 /* 002 * Copyright 2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * 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/ecl2.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, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.student.common.spring; 017 018 import java.io.Externalizable; 019 import java.io.IOException; 020 import java.io.ObjectInput; 021 import java.io.ObjectOutput; 022 import java.io.Serializable; 023 import java.lang.reflect.InvocationHandler; 024 import java.lang.reflect.Method; 025 026 import javax.xml.namespace.QName; 027 028 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader; 029 import org.springframework.util.ReflectionUtils; 030 031 /** 032 * 033 * A Serializable Proxy Invokation Handler. This handler is serializable and knows how to look up the service using the GlobalResourceLocator. 034 * 035 * @author Kuali Student Team 036 * 037 */ 038 public class SerializableProxyInvokationHandler implements InvocationHandler, Externalizable { 039 040 /** 041 * 042 */ 043 private static final long serialVersionUID = 1L; 044 045 private transient Object serviceDelegate; 046 047 private QName serviceName; 048 049 /** 050 * 051 */ 052 public SerializableProxyInvokationHandler() { 053 } 054 055 056 /** 057 * @param serviceName the serviceName to set 058 */ 059 public void setServiceName(QName serviceName) { 060 this.serviceName = serviceName; 061 } 062 063 064 /* 065 * (non-Javadoc) 066 * 067 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, 068 * java.lang.reflect.Method, java.lang.Object[]) 069 */ 070 @Override 071 public Object invoke(Object proxy, Method method, Object[] args) 072 throws Throwable { 073 074 if (serviceDelegate == null) { 075 // first time or just after reserialization. 076 try { 077 serviceDelegate = GlobalResourceLoader.getService(serviceName); 078 } catch (Exception e) { 079 080 if (method.getName().equals("toString")) { 081 // fake toString 082 // spring has an assertion that expects this to work so we will just fake it 083 // once the delegate is resolved the normal toString method will be used. 084 return getClass().getName() + " (serviceName=" + serviceName + ")"; 085 } 086 else 087 throw e; 088 } 089 } 090 091 // delegate the call to the actual service to fulfill. 092 return ReflectionUtils.invokeMethod(method, serviceDelegate, args); 093 } 094 095 /* (non-Javadoc) 096 * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) 097 */ 098 @Override 099 public void writeExternal(ObjectOutput out) throws IOException { 100 101 QName name = new QName(serviceName.getNamespaceURI(), serviceName.getLocalPart()); 102 103 out.writeObject(name); 104 105 } 106 107 /* (non-Javadoc) 108 * @see java.io.Externalizable#readExternal(java.io.ObjectInput) 109 */ 110 @Override 111 public void readExternal(ObjectInput in) throws IOException, 112 ClassNotFoundException { 113 114 QName name = (QName) in.readObject(); 115 116 this.serviceName = new QName (name.getNamespaceURI(), name.getLocalPart()); 117 118 } 119 120 121 122 }