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.jaxws.client;
017:
018: import org.apache.geronimo.naming.reference.SimpleReference;
019: import org.apache.geronimo.naming.reference.ClassLoaderAwareReference;
020: import org.apache.geronimo.naming.reference.KernelAwareReference;
021: import org.apache.geronimo.kernel.Kernel;
022: import org.apache.geronimo.gbean.AbstractName;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025:
026: import javax.naming.NamingException;
027: import javax.xml.ws.Service;
028: import javax.xml.ws.handler.HandlerResolver;
029: import javax.xml.namespace.QName;
030: import java.net.URL;
031: import java.net.MalformedURLException;
032: import java.net.URI;
033: import java.lang.reflect.InvocationTargetException;
034: import java.util.Map;
035:
036: import net.sf.cglib.proxy.Callback;
037: import net.sf.cglib.proxy.NoOp;
038: import net.sf.cglib.proxy.Enhancer;
039: import net.sf.cglib.proxy.MethodInterceptor;
040: import net.sf.cglib.reflect.FastConstructor;
041: import net.sf.cglib.reflect.FastClass;
042:
043: public abstract class JAXWSServiceReference extends SimpleReference
044: implements ClassLoaderAwareReference, KernelAwareReference {
045: private static final Log LOG = LogFactory
046: .getLog(JAXWSServiceReference.class);
047: private static final Class[] URL_SERVICE_NAME_CONSTRUCTOR = new Class[] {
048: URL.class, QName.class };
049:
050: protected String serviceClassName;
051: protected ClassLoader classLoader;
052: protected AbstractName moduleName;
053: protected URI wsdlURI;
054: protected QName serviceQName;
055: private Kernel kernel;
056: protected String handlerChainsXML;
057: protected Map<Object, EndpointInfo> seiInfoMap;
058: protected String referenceClassName;
059:
060: protected Class enhancedServiceClass;
061: protected Callback[] methodInterceptors;
062: protected FastConstructor serviceConstructor;
063:
064: public JAXWSServiceReference(String handlerChainsXML,
065: Map<Object, EndpointInfo> seiInfoMap, AbstractName name,
066: QName serviceQName, URI wsdlURI, String referenceClassName,
067: String serviceClassName) {
068: this .handlerChainsXML = handlerChainsXML;
069: this .seiInfoMap = seiInfoMap;
070: this .moduleName = name;
071: this .serviceQName = serviceQName;
072: this .wsdlURI = wsdlURI;
073: this .referenceClassName = referenceClassName;
074: this .serviceClassName = serviceClassName;
075: }
076:
077: public void setClassLoader(ClassLoader classLoader) {
078: this .classLoader = classLoader;
079: }
080:
081: public void setKernel(Kernel kernel) {
082: this .kernel = kernel;
083: }
084:
085: private Class loadClass(String name) throws NamingException {
086: try {
087: return this .classLoader.loadClass(name);
088: } catch (ClassNotFoundException e) {
089: NamingException exception = new NamingException(
090: "Count not load class " + name);
091: exception.initCause(e);
092: throw exception;
093: }
094: }
095:
096: private URL getWsdlURL() {
097: if (this .wsdlURI == null) {
098: return null;
099: }
100: try {
101: return new URL(this .wsdlURI.toString());
102: } catch (MalformedURLException e1) {
103: // not a URL, assume it's a local reference
104: try {
105: URL moduleBaseUrl = (URL) this .kernel.getAttribute(
106: this .moduleName, "configurationBaseUrl");
107: return new URL(moduleBaseUrl.toString()
108: + this .wsdlURI.toString());
109: } catch (Exception e) {
110: URL wsdlURL = this .classLoader.getResource(this .wsdlURI
111: .toString());
112: if (wsdlURL == null) {
113: LOG
114: .warn("Error obtaining WSDL: "
115: + this .wsdlURI, e);
116: }
117: return wsdlURL;
118: }
119: }
120: }
121:
122: private Class getReferenceClass() throws NamingException {
123: return (this .referenceClassName != null) ? loadClass(this .referenceClassName)
124: : null;
125: }
126:
127: public Object getContent() throws NamingException {
128: Service instance = null;
129: URL wsdlURL = getWsdlURL();
130:
131: Class serviceClass = loadClass(this .serviceClassName);
132: Class referenceClass = getReferenceClass();
133:
134: if (referenceClass != null
135: && Service.class.isAssignableFrom(referenceClass)) {
136: serviceClass = referenceClass;
137: }
138:
139: if (Service.class.equals(serviceClass)) {
140: serviceClass = GenericService.class;
141: }
142:
143: instance = createServiceProxy(serviceClass, this .classLoader,
144: this .serviceQName, wsdlURL);
145:
146: HandlerResolver handlerResolver = getHandlerResolver(serviceClass);
147: if (handlerResolver != null) {
148: instance.setHandlerResolver(handlerResolver);
149: }
150:
151: if (referenceClass != null
152: && !Service.class.isAssignableFrom(referenceClass)) {
153: // do port lookup
154: return instance.getPort(referenceClass);
155: } else {
156: // return service
157: return instance;
158: }
159: }
160:
161: protected abstract HandlerResolver getHandlerResolver(
162: Class serviceClass);
163:
164: protected PortMethodInterceptor getPortMethodInterceptor() {
165: return new PortMethodInterceptor(this .seiInfoMap);
166: }
167:
168: private Service createServiceProxy(Class super Class,
169: ClassLoader classLoader, QName serviceName, URL wsdlLocation)
170: throws NamingException {
171: if (this .serviceConstructor == null) {
172: // create method interceptors
173: Callback callback = getPortMethodInterceptor();
174: this .methodInterceptors = new Callback[] { NoOp.INSTANCE,
175: callback };
176:
177: // create service class
178: Enhancer enhancer = new Enhancer();
179: enhancer.setClassLoader(classLoader);
180: enhancer.setSuperclass(super Class);
181: enhancer.setCallbackFilter(new PortMethodFilter());
182: enhancer.setCallbackTypes(new Class[] { NoOp.class,
183: MethodInterceptor.class });
184: enhancer.setUseFactory(false);
185: enhancer.setUseCache(false);
186: this .enhancedServiceClass = enhancer.createClass();
187:
188: // get constructor
189: this .serviceConstructor = FastClass.create(
190: this .enhancedServiceClass).getConstructor(
191: URL_SERVICE_NAME_CONSTRUCTOR);
192: }
193:
194: LOG.debug("Initializing service with: " + wsdlLocation + " "
195: + serviceName);
196:
197: // associate the method interceptors with the generated service class on the current thread
198: Enhancer.registerCallbacks(this .enhancedServiceClass,
199: this .methodInterceptors);
200:
201: Object[] arguments = new Object[] { wsdlLocation, serviceName };
202:
203: try {
204: return (Service) this .serviceConstructor
205: .newInstance(arguments);
206: } catch (InvocationTargetException e) {
207: NamingException exception = new NamingException(
208: "Could not construct service proxy");
209: exception.initCause(e.getTargetException());
210: throw exception;
211: }
212: }
213: }
|