001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.axis.client;
017:
018: import java.lang.reflect.InvocationTargetException;
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: import javax.naming.NamingException;
023:
024: import net.sf.cglib.proxy.Callback;
025: import net.sf.cglib.proxy.Enhancer;
026: import net.sf.cglib.proxy.MethodInterceptor;
027: import net.sf.cglib.proxy.NoOp;
028: import net.sf.cglib.reflect.FastClass;
029: import net.sf.cglib.reflect.FastConstructor;
030: import org.apache.axis.client.Service;
031: import org.apache.geronimo.naming.reference.ClassLoaderAwareReference;
032: import org.apache.geronimo.naming.reference.SimpleReference;
033:
034: /**
035: * @version $Rev: 559321 $ $Date: 2007-07-24 22:52:54 -0700 (Tue, 24 Jul 2007) $
036: */
037: public class AxisServiceReference extends SimpleReference implements
038: ClassLoaderAwareReference {
039: private static final Class[] SERVICE_CONSTRUCTOR_TYPES = new Class[] {
040: Map.class, Map.class };
041:
042: private String serviceInterfaceClassName;
043: private Map seiPortNameToFactoryMap;
044: private Map seiClassNameToFactoryMap;
045: private ClassLoader classLoader;
046:
047: private FastConstructor serviceConstructor;
048: private Callback[] methodInterceptors;
049: private Class enhancedServiceClass;
050:
051: public AxisServiceReference(String serviceInterfaceClassName,
052: Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap) {
053: this .serviceInterfaceClassName = serviceInterfaceClassName;
054: this .seiPortNameToFactoryMap = seiPortNameToFactoryMap;
055: this .seiClassNameToFactoryMap = seiClassNameToFactoryMap;
056: }
057:
058: public void setClassLoader(ClassLoader classLoader) {
059: this .classLoader = classLoader;
060: }
061:
062: public Object getContent() throws NamingException {
063: Object serviceInstance = createServiceInterfaceProxy(
064: serviceInterfaceClassName, seiPortNameToFactoryMap,
065: seiClassNameToFactoryMap, classLoader);
066: return serviceInstance;
067: }
068:
069: private Object createServiceInterfaceProxy(
070: String serviceInterfaceClassName,
071: Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap,
072: ClassLoader classLoader) throws NamingException {
073: boolean initialize = (this .serviceConstructor == null);
074:
075: if (initialize) {
076: Class serviceInterface;
077: try {
078: serviceInterface = classLoader
079: .loadClass(serviceInterfaceClassName);
080: } catch (ClassNotFoundException e) {
081: throw (NamingException) new NamingException(
082: "Could not load service interface class "
083: + serviceInterfaceClassName)
084: .initCause(e);
085: }
086:
087: // create method interceptors
088: Callback callback = new ServiceMethodInterceptor(
089: seiPortNameToFactoryMap);
090: this .methodInterceptors = new Callback[] {
091: SerializableNoOp.INSTANCE, callback };
092:
093: // create service class
094: Enhancer enhancer = new Enhancer();
095: enhancer.setClassLoader(classLoader);
096: enhancer.setSuperclass(ServiceImpl.class);
097: enhancer.setInterfaces(new Class[] { serviceInterface });
098: enhancer.setCallbackFilter(new NoOverrideCallbackFilter(
099: Service.class));
100: enhancer.setCallbackTypes(new Class[] { NoOp.class,
101: MethodInterceptor.class });
102: enhancer.setUseFactory(false);
103: enhancer.setUseCache(false);
104: this .enhancedServiceClass = enhancer.createClass();
105:
106: // get constructor
107: this .serviceConstructor = FastClass.create(
108: this .enhancedServiceClass).getConstructor(
109: SERVICE_CONSTRUCTOR_TYPES);
110: }
111:
112: // associate the method interceptors with the generated service class on the current thread
113: Enhancer.registerCallbacks(this .enhancedServiceClass,
114: this .methodInterceptors);
115:
116: Object[] arguments = new Object[] { seiPortNameToFactoryMap,
117: seiClassNameToFactoryMap };
118:
119: Object serviceInstance = null;
120:
121: try {
122: serviceInstance = this .serviceConstructor
123: .newInstance(arguments);
124: } catch (InvocationTargetException e) {
125: throw (NamingException) new NamingException(
126: "Could not construct service instance").initCause(e
127: .getTargetException());
128: }
129:
130: if (initialize) {
131: for (Iterator iterator = seiPortNameToFactoryMap.values()
132: .iterator(); iterator.hasNext();) {
133: SEIFactoryImpl seiFactory = (SEIFactoryImpl) iterator
134: .next();
135: try {
136: seiFactory.initialize(serviceInstance, classLoader);
137: } catch (ClassNotFoundException e) {
138: throw (NamingException) new NamingException(
139: "Could not load service interface class; "
140: + e.getMessage()).initCause(e);
141: }
142: }
143: }
144:
145: return serviceInstance;
146: }
147:
148: }
|