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.openejb.server.axis.client;
017:
018: import net.sf.cglib.proxy.Callback;
019: import net.sf.cglib.proxy.Enhancer;
020: import net.sf.cglib.proxy.MethodInterceptor;
021: import net.sf.cglib.proxy.NoOp;
022: import net.sf.cglib.reflect.FastClass;
023: import net.sf.cglib.reflect.FastConstructor;
024: import org.apache.axis.client.Service;
025: import org.apache.openejb.core.ivm.naming.Reference;
026:
027: import javax.naming.NamingException;
028: import java.lang.reflect.InvocationTargetException;
029: import java.util.Iterator;
030: import java.util.Map;
031:
032: public class AxisServiceReference extends Reference {
033: private static final Class[] SERVICE_CONSTRUCTOR_TYPES = new Class[] {
034: Map.class, Map.class };
035:
036: private String serviceInterfaceClassName;
037: private Map seiPortNameToFactoryMap;
038: private Map seiClassNameToFactoryMap;
039: private ClassLoader classLoader;
040:
041: private FastConstructor serviceConstructor;
042: private Callback[] methodInterceptors;
043: private Class enhancedServiceClass;
044:
045: public AxisServiceReference(String serviceInterfaceClassName,
046: Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap) {
047: this .serviceInterfaceClassName = serviceInterfaceClassName;
048: this .seiPortNameToFactoryMap = seiPortNameToFactoryMap;
049: this .seiClassNameToFactoryMap = seiClassNameToFactoryMap;
050: }
051:
052: public void setClassLoader(ClassLoader classLoader) {
053: this .classLoader = classLoader;
054: }
055:
056: public Object getObject() throws NamingException {
057: Object serviceInstance = createServiceInterfaceProxy(
058: serviceInterfaceClassName, seiPortNameToFactoryMap,
059: seiClassNameToFactoryMap, classLoader);
060: return serviceInstance;
061: }
062:
063: private Object createServiceInterfaceProxy(
064: String serviceInterfaceClassName,
065: Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap,
066: ClassLoader classLoader) throws NamingException {
067: boolean initialize = (this .serviceConstructor == null);
068:
069: if (initialize) {
070: Class serviceInterface;
071: try {
072: serviceInterface = classLoader
073: .loadClass(serviceInterfaceClassName);
074: } catch (ClassNotFoundException e) {
075: throw (NamingException) new NamingException(
076: "Could not load service interface class "
077: + serviceInterfaceClassName)
078: .initCause(e);
079: }
080:
081: // create method interceptors
082: Callback callback = new ServiceMethodInterceptor(
083: seiPortNameToFactoryMap);
084: this .methodInterceptors = new Callback[] { NoOp.INSTANCE,
085: callback };
086:
087: // create service class
088: Enhancer enhancer = new Enhancer();
089: enhancer.setClassLoader(classLoader);
090: enhancer.setSuperclass(ServiceImpl.class);
091: enhancer.setInterfaces(new Class[] { serviceInterface });
092: enhancer.setCallbackFilter(new NoOverrideCallbackFilter(
093: Service.class));
094: enhancer.setCallbackTypes(new Class[] { NoOp.class,
095: MethodInterceptor.class });
096: enhancer.setUseFactory(false);
097: enhancer.setUseCache(false);
098: this .enhancedServiceClass = enhancer.createClass();
099:
100: // get constructor
101: this .serviceConstructor = FastClass.create(
102: this .enhancedServiceClass).getConstructor(
103: SERVICE_CONSTRUCTOR_TYPES);
104: }
105:
106: // associate the method interceptors with the generated service class on the current thread
107: Enhancer.registerCallbacks(this .enhancedServiceClass,
108: this .methodInterceptors);
109:
110: Object[] arguments = new Object[] { seiPortNameToFactoryMap,
111: seiClassNameToFactoryMap };
112:
113: Object serviceInstance = null;
114:
115: try {
116: serviceInstance = this .serviceConstructor
117: .newInstance(arguments);
118: } catch (InvocationTargetException e) {
119: throw (NamingException) new NamingException(
120: "Could not construct service instance").initCause(e
121: .getTargetException());
122: }
123:
124: if (initialize) {
125: for (Iterator iterator = seiPortNameToFactoryMap.values()
126: .iterator(); iterator.hasNext();) {
127: SeiFactoryImpl seiFactory = (SeiFactoryImpl) iterator
128: .next();
129: try {
130: seiFactory.initialize(serviceInstance, classLoader);
131: } catch (ClassNotFoundException e) {
132: throw (NamingException) new NamingException(
133: "Could not load service interface class; "
134: + e.getMessage()).initCause(e);
135: }
136: }
137: }
138:
139: return serviceInstance;
140: }
141: }
|