001: /*
002: * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.soap.jaxws;
031:
032: import com.caucho.server.util.ScheduledThreadPool;
033: import com.caucho.soap.jaxws.handlerchain.HandlerChains;
034: import com.caucho.soap.reflect.WebServiceIntrospector;
035: import com.caucho.soap.skeleton.Skeleton;
036: import com.caucho.soap.wsdl.WSDLDefinitions;
037: import com.caucho.soap.wsdl.WSDLParser;
038: import com.caucho.util.L10N;
039:
040: import javax.activation.DataSource;
041:
042: import javax.xml.bind.JAXBContext;
043: import javax.xml.bind.JAXBException;
044: import javax.xml.bind.Unmarshaller;
045: import javax.xml.namespace.QName;
046: import static javax.xml.soap.SOAPConstants.*;
047: import javax.xml.soap.SOAPException;
048: import javax.xml.soap.SOAPMessage;
049: import javax.xml.transform.Source;
050:
051: import javax.jws.HandlerChain;
052:
053: import javax.xml.ws.Binding;
054: import javax.xml.ws.BindingProvider;
055: import javax.xml.ws.Dispatch;
056: import javax.xml.ws.Service;
057: import javax.xml.ws.WebServiceException;
058: import javax.xml.ws.handler.HandlerResolver;
059: import javax.xml.ws.http.HTTPBinding;
060: import javax.xml.ws.soap.SOAPBinding;
061: import javax.xml.ws.spi.ServiceDelegate;
062:
063: import java.io.InputStream;
064: import java.lang.annotation.Annotation;
065: import java.lang.reflect.Proxy;
066: import java.net.URL;
067: import java.util.Iterator;
068: import java.util.HashMap;
069: import java.util.Map;
070: import java.util.concurrent.Executor;
071: import java.util.logging.Logger;
072:
073: /**
074: * ServiceDelegate
075: */
076: public class ServiceDelegateImpl extends ServiceDelegate {
077: private final static Logger log = Logger
078: .getLogger(ServiceDelegateImpl.class.getName());
079: private final static L10N L = new L10N(ServiceDelegateImpl.class);
080:
081: private final Map<QName, PortInfoImpl> _portMap = new HashMap<QName, PortInfoImpl>();
082:
083: private final Unmarshaller _handlerUnmarshaller;
084:
085: private final ClassLoader _classLoader;
086:
087: private final URL _wsdl;
088: private final QName _serviceName;
089: private final Class _serviceClass;
090:
091: private HandlerResolver _handlerResolver;
092: private Executor _executor = ScheduledThreadPool.getLocal();
093:
094: ServiceDelegateImpl(URL wsdl, QName serviceName, Class serviceClass) {
095: _classLoader = Thread.currentThread().getContextClassLoader();
096:
097: _wsdl = wsdl;
098: _serviceName = serviceName;
099: _serviceClass = serviceClass;
100:
101: try {
102: JAXBContext context = JAXBContext
103: .newInstance("com.caucho.soap.jaxws.handlerchain");
104: _handlerUnmarshaller = context.createUnmarshaller();
105: } catch (Exception e) {
106: throw new RuntimeException(e);
107: }
108: }
109:
110: public void addPort(QName portName, String bindingId,
111: String endpointAddress) {
112: PortInfoImpl portInfo = new PortInfoImpl(bindingId, portName,
113: _serviceName, endpointAddress);
114:
115: _portMap.put(portName, portInfo);
116: }
117:
118: public <T> Dispatch<T> createDispatch(QName portName,
119: Class<T> type, Service.Mode mode)
120: throws WebServiceException {
121: PortInfoImpl port = _portMap.get(portName);
122: String bindingId = SOAPBinding.SOAP11HTTP_BINDING;
123: String endpointAddress = null;
124:
125: if (port != null) {
126: bindingId = port.getBindingID();
127: endpointAddress = port.getEndpointAddress();
128: }
129:
130: if (endpointAddress == null)
131: endpointAddress = findEndpointAddress();
132:
133: Dispatch<T> dispatch = null;
134: Binding binding = getBinding(bindingId);
135:
136: if (_handlerResolver != null)
137: binding.setHandlerChain(_handlerResolver
138: .getHandlerChain(port));
139:
140: if (Source.class.equals(type)) {
141: dispatch = (Dispatch<T>) new SourceDispatch(bindingId,
142: binding, mode, _executor);
143: } else if (SOAPMessage.class.equals(type)) {
144: dispatch = (Dispatch<T>) new SOAPMessageDispatch(bindingId,
145: binding, mode, _executor);
146: } else if (DataSource.class.equals(type)) {
147: dispatch = (Dispatch<T>) new DataSourceDispatch(bindingId,
148: binding, mode, _executor);
149: }
150:
151: if (dispatch == null) {
152: throw new WebServiceException(L.l(
153: "{0} is an unsupported Dispatch type", type));
154: }
155:
156: if (endpointAddress != null) {
157: Map<String, Object> requestContext = dispatch
158: .getRequestContext();
159: requestContext.put(
160: BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
161: endpointAddress);
162: }
163:
164: return dispatch;
165: }
166:
167: public Dispatch<Object> createDispatch(QName portName,
168: JAXBContext context, Service.Mode mode)
169: throws WebServiceException {
170: PortInfoImpl port = _portMap.get(portName);
171: String bindingId = SOAPBinding.SOAP11HTTP_BINDING;
172: String endpointAddress = null;
173:
174: if (port != null) {
175: bindingId = port.getBindingID();
176: endpointAddress = port.getEndpointAddress();
177: }
178:
179: if (endpointAddress == null)
180: endpointAddress = findEndpointAddress();
181:
182: Binding binding = getBinding(bindingId);
183:
184: if (_handlerResolver != null)
185: binding.setHandlerChain(_handlerResolver
186: .getHandlerChain(port));
187:
188: JAXBDispatch dispatch = new JAXBDispatch(bindingId, binding,
189: mode, _executor, context);
190:
191: if (endpointAddress != null) {
192: Map<String, Object> requestContext = dispatch
193: .getRequestContext();
194: requestContext.put(
195: BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
196: endpointAddress);
197: }
198:
199: return dispatch;
200: }
201:
202: public Executor getExecutor() {
203: return _executor;
204: }
205:
206: public HandlerResolver getHandlerResolver() {
207: return _handlerResolver;
208: }
209:
210: public void setHandlerResolver(HandlerResolver handlerResolver) {
211: _handlerResolver = handlerResolver;
212: }
213:
214: public <T> T getPort(Class<T> serviceEndpointInterface) {
215: return getPort(null, serviceEndpointInterface);
216: }
217:
218: public <T> T getPort(QName portName, Class<T> api)
219: throws WebServiceException {
220: try {
221: WSDLDefinitions definitions = WSDLParser.parse(api);
222:
223: if (definitions == null && _wsdl != null) {
224: try {
225: definitions = WSDLParser.parse(_wsdl);
226: } catch (WebServiceException e) {
227: }
228:
229: /*
230: if (definitions == null)
231: throw new WebServiceException(L.l("Unable to parse WSDL"));*/
232: }
233:
234: String wsdlLocation = null;
235:
236: if (_wsdl != null)
237: wsdlLocation = _wsdl.toString();
238: else
239: wsdlLocation = null;
240:
241: Skeleton skeleton = WebServiceIntrospector.introspect(api,
242: wsdlLocation, definitions);
243:
244: String endpointAddress = findEndpointAddress();
245: String bindingId = SOAPBinding.SOAP11HTTP_BINDING;
246: //definitions.getBindingId(_serviceName, portName);
247:
248: Binding binding = getBinding(bindingId);
249: PortProxyHandler handler = new PortProxyHandler(skeleton,
250: endpointAddress, binding);
251:
252: if (portName == null)
253: portName = new QName(skeleton.getNamespace(), skeleton
254: .getPortName());
255:
256: PortInfoImpl portInfo = new PortInfoImpl(bindingId,
257: portName, _serviceName, endpointAddress);
258:
259: // Check for @HandlerChain on the service API
260: if (_handlerResolver == null) {
261: HandlerChain handlerChain = (HandlerChain) api
262: .getAnnotation(HandlerChain.class);
263:
264: if (handlerChain != null)
265: _handlerResolver = JAXWSUtil.createHandlerResolver(
266: api, handlerChain);
267: }
268:
269: // Check for @HandlerChain on the Service
270: if (_handlerResolver == null) {
271: HandlerChain handlerChain = (HandlerChain) _serviceClass
272: .getAnnotation(HandlerChain.class);
273:
274: if (handlerChain != null)
275: _handlerResolver = JAXWSUtil.createHandlerResolver(
276: api, handlerChain);
277: }
278:
279: if (_handlerResolver != null)
280: binding.setHandlerChain(_handlerResolver
281: .getHandlerChain(portInfo));
282:
283: _portMap.put(portName, portInfo);
284:
285: Class[] interfaces = new Class[] { api,
286: BindingProvider.class };
287:
288: Object proxy = Proxy.newProxyInstance(_classLoader,
289: interfaces, handler);
290:
291: return (T) proxy;
292: } catch (WebServiceException e) {
293: throw e;
294: } catch (Exception e) {
295: throw new WebServiceException(e);
296: }
297: }
298:
299: public Iterator<QName> getPorts() {
300: return _portMap.keySet().iterator();
301: }
302:
303: public QName getServiceName() {
304: return _serviceName;
305: }
306:
307: public URL getWSDLDocumentLocation() {
308: return _wsdl;
309: }
310:
311: public void setExecutor(Executor executor) {
312: _executor = executor;
313: }
314:
315: public String toString() {
316: return ("ServiceDelegateImpl["
317: + getServiceName().getNamespaceURI() + ","
318: + getServiceName().getLocalPart() + "]");
319: }
320:
321: private String findEndpointAddress() {
322: if (getWSDLDocumentLocation() != null) {
323: int p = getWSDLDocumentLocation().toString().lastIndexOf(
324: '?');
325: return getWSDLDocumentLocation().toString().substring(0, p);
326: } else
327: return null;
328:
329: /*
330: WSDLDefinitions definitions = WSDLParser.parse(getWSDLDocumentLocation());
331:
332: if (definitions != null) {
333: endpointAddress =
334: definitions.getEndpointAddress(_serviceName, portName);
335:
336: if (endpointAddress != null && endpointAddress.indexOf(':') < 0) {
337: definitions = WSDLParser.parse(endpointAddress);
338:
339: if (definitions != null) {
340: endpointAddress =
341: definitions.getEndpointAddress(_serviceName, portName);
342: }
343: }
344: }*/
345: }
346:
347: static Binding getBinding(String bindingId)
348: throws WebServiceException {
349: if (bindingId.equals(SOAPBinding.SOAP11HTTP_BINDING)
350: || bindingId
351: .equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
352: || bindingId.equals(SOAPBinding.SOAP12HTTP_BINDING)
353: || bindingId
354: .equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
355: try {
356: return new SOAPBindingImpl(bindingId);
357: } catch (SOAPException e) {
358: throw new WebServiceException(e);
359: }
360: } else if (bindingId.equals(HTTPBinding.HTTP_BINDING))
361: return new HTTPBindingImpl();
362: else
363: throw new WebServiceException(L.l(
364: "Unknown binding id: {0}", bindingId));
365: }
366: }
|