1 /** 2 * 3 * Copyright 2006 The Apache Software Foundation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.geronimo.axis.client; 19 20 import java.lang.reflect.InvocationTargetException; 21 import java.util.Iterator; 22 import java.util.Map; 23 24 import javax.naming.NamingException; 25 26 import net.sf.cglib.proxy.Callback; 27 import net.sf.cglib.proxy.Enhancer; 28 import net.sf.cglib.proxy.MethodInterceptor; 29 import net.sf.cglib.proxy.NoOp; 30 import net.sf.cglib.reflect.FastClass; 31 import net.sf.cglib.reflect.FastConstructor; 32 import org.apache.axis.client.Service; 33 import org.apache.geronimo.naming.reference.ClassLoaderAwareReference; 34 import org.apache.geronimo.naming.reference.SimpleReference; 35 36 /** 37 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $ 38 */ 39 public class AxisServiceReference extends SimpleReference implements ClassLoaderAwareReference { 40 private static final Class[] SERVICE_CONSTRUCTOR_TYPES = new Class[]{Map.class, Map.class}; 41 42 private String serviceInterfaceClassName; 43 private Map seiPortNameToFactoryMap; 44 private Map seiClassNameToFactoryMap; 45 private ClassLoader classLoader; 46 47 public AxisServiceReference(String serviceInterfaceClassName, Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap) { 48 this.serviceInterfaceClassName = serviceInterfaceClassName; 49 this.seiPortNameToFactoryMap = seiPortNameToFactoryMap; 50 this.seiClassNameToFactoryMap = seiClassNameToFactoryMap; 51 } 52 53 public void setClassLoader(ClassLoader classLoader) { 54 this.classLoader = classLoader; 55 } 56 57 public Object getContent() throws NamingException { 58 Class serviceInterface; 59 try { 60 serviceInterface = classLoader.loadClass(serviceInterfaceClassName); 61 } catch (ClassNotFoundException e) { 62 throw new NamingException("Could not load service interface class " + serviceInterfaceClassName); 63 } 64 Object serviceInstance = createServiceInterfaceProxy(serviceInterface, seiPortNameToFactoryMap, seiClassNameToFactoryMap, classLoader); 65 for (Iterator iterator = seiPortNameToFactoryMap.values().iterator(); iterator.hasNext();) { 66 SEIFactoryImpl seiFactory = (SEIFactoryImpl) iterator.next(); 67 try { 68 seiFactory.initialize(serviceInstance, classLoader); 69 } catch (ClassNotFoundException e) { 70 throw new NamingException("Could not load service interface class; " + e.getMessage()); 71 } 72 } 73 74 return serviceInstance; 75 } 76 77 private Object createServiceInterfaceProxy(Class serviceInterface, Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap, ClassLoader classLoader) throws NamingException { 78 79 Callback callback = new ServiceMethodInterceptor(seiPortNameToFactoryMap); 80 Callback[] methodInterceptors = new Callback[]{SerializableNoOp.INSTANCE, callback}; 81 82 Enhancer enhancer = new Enhancer(); 83 enhancer.setClassLoader(classLoader); 84 enhancer.setSuperclass(ServiceImpl.class); 85 enhancer.setInterfaces(new Class[]{serviceInterface}); 86 enhancer.setCallbackFilter(new NoOverrideCallbackFilter(Service.class)); 87 enhancer.setCallbackTypes(new Class[]{NoOp.class, MethodInterceptor.class}); 88 enhancer.setUseFactory(false); 89 enhancer.setUseCache(false); 90 Class serviceClass = enhancer.createClass(); 91 92 Enhancer.registerCallbacks(serviceClass, methodInterceptors); 93 FastConstructor constructor = FastClass.create(serviceClass).getConstructor(SERVICE_CONSTRUCTOR_TYPES); 94 try { 95 return constructor.newInstance(new Object[]{seiPortNameToFactoryMap, seiClassNameToFactoryMap}); 96 } catch (InvocationTargetException e) { 97 throw (NamingException)new NamingException("Could not construct service instance").initCause(e.getTargetException()); 98 } 99 } 100 101 }