001: /*
002: * Portions Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.ws.client.dispatch;
027:
028: import static javax.xml.ws.Service.Mode.MESSAGE;
029: import static javax.xml.ws.Service.Mode.*;
030: import static javax.xml.ws.Service.*;
031:
032: import com.sun.xml.internal.ws.binding.BindingImpl;
033: import com.sun.xml.internal.ws.binding.soap.SOAPBindingImpl;
034: import com.sun.xml.internal.ws.client.*;
035: import com.sun.xml.internal.ws.client.dispatch.impl.DispatchContactInfoList;
036: import com.sun.xml.internal.ws.client.dispatch.impl.DispatchDelegate;
037: import com.sun.xml.internal.ws.encoding.soap.message.SOAPFaultInfo;
038: import com.sun.xml.internal.ws.pept.Delegate;
039: import com.sun.xml.internal.ws.pept.presentation.MessageStruct;
040: import com.sun.xml.internal.ws.spi.runtime.ClientTransportFactory;
041: import com.sun.xml.internal.ws.transport.http.client.HttpClientTransportFactory;
042:
043: import javax.activation.DataSource;
044: import javax.xml.bind.JAXBContext;
045: import javax.xml.bind.JAXBException;
046: import javax.xml.namespace.QName;
047: import javax.xml.soap.MessageFactory;
048: import javax.xml.soap.SOAPConstants;
049: import javax.xml.soap.SOAPException;
050: import javax.xml.soap.SOAPMessage;
051: import javax.xml.transform.Source;
052: import javax.xml.ws.*;
053: import javax.xml.ws.handler.MessageContext;
054: import javax.xml.ws.http.HTTPBinding;
055: import javax.xml.ws.http.HTTPException;
056: import javax.xml.ws.soap.SOAPBinding;
057: import javax.xml.ws.soap.SOAPFaultException;
058: import java.util.Map;
059: import java.util.concurrent.Executor;
060: import java.util.concurrent.Future;
061: import java.util.concurrent.locks.Lock;
062: import java.util.concurrent.locks.ReentrantLock;
063: import java.util.logging.Logger;
064:
065: /**
066: * The <code>javax.xml.ws.Dispatch</code> interface provides support
067: * for the dynamic invocation of a service endpoint operation using XML
068: * constructs or JAXB objects. The <code>javax.xml.ws.Service</code>
069: * interface acts as a factory for the creation of <code>Dispatch</code>
070: * instances.
071: *
072: * @author WS Development Team
073: * @version 1.0
074: */
075:
076: public class DispatchBase implements BindingProvider,
077: InternalBindingProvider, Dispatch {
078:
079: public DispatchBase(PortInfoBase port, Class aClass,
080: Service.Mode mode, WSServiceDelegate service) {
081: this (port, mode, null, aClass, service);
082: }
083:
084: public DispatchBase(PortInfoBase port, JAXBContext jaxbContext,
085: Service.Mode mode, WSServiceDelegate service) {
086: this (port, mode, jaxbContext, null, service);
087: }
088:
089: DispatchBase(PortInfoBase port, Service.Mode mode,
090: JAXBContext context, Class clazz, WSServiceDelegate service) {
091: _delegate = new DispatchDelegate(new DispatchContactInfoList());
092: _mode = mode;
093: _portInfo = port;
094: _jaxbContext = context;
095: _clazz = clazz;
096: _service = service;
097: }
098:
099: /**
100: * Invoke a service operation synchronously.
101: * <p/>
102: * The client is responsible for ensuring that the <code>msg</code> object
103: * is formed according to the requirements of the protocol binding in use.
104: *
105: * @param msg An object that will form the payload of
106: * the message used to invoke the operation. Must be an instance of
107: * either <code>javax.xml.transform.Source</code> or a JAXB object. If
108: * <code>msg</code> is an instance of a JAXB object then the request
109: * context must have the <code>javax.xml.ws.binding.context</code>
110: * property set.
111: * @return The response to the operation invocation. The object is
112: * either an instance of <code>javax.xml.transform.Source</code>
113: * or a JAXB object.
114: * @throws javax.xml.ws.WebServiceException
115: * If there is any error in the configuration of
116: * the <code>Dispatch</code> instance
117: * @throws javax.xml.ws.WebServiceException
118: * If an error occurs when using a supplied
119: * JAXBContext to marshall msg or unmarshall the response. The cause of
120: * the WebServiceException is the original JAXBException.
121: */
122: public Object invoke(Object msg) throws WebServiceException {
123:
124: MessageStruct messageStruct = setupMessageStruct(msg);
125: messageStruct.setMEP(MessageStruct.REQUEST_RESPONSE_MEP);
126: return sendAndReceive(messageStruct);
127: }
128:
129: /**
130: * Invoke a service operation asynchronously. The
131: * method returns without waiting for the response to the operation
132: * invocation, the results of the operation are obtained by polling the
133: * returned <code>Response</code>.
134: * <p/>
135: * The client is responsible for ensuring that the <code>msg</code> object
136: * when marshalled is formed according to the requirements of the protocol
137: * binding in use.
138: *
139: * @param msg An object that, when marshalled, will form the payload of
140: * the message used to invoke the operation. Must be an instance of
141: * either <code>javax.xml.transform.Source</code> or a JAXB object. If
142: * <code>msg</code> is an instance of a JAXB object then the request
143: * context must have the <code>javax.xml.ws.binding.context</code>
144: * property set.
145: * @return The response to the operation invocation. The object
146: * returned by <code>Response.get()</code> is
147: * either an instance of <code>javax.xml.transform.Source</code>
148: * or a JAXB object.
149: * @throws javax.xml.ws.WebServiceException
150: * If there is any error in the configuration of
151: * the <code>Dispatch</code> instance
152: * @throws javax.xml.ws.WebServiceException
153: * If an error occurs when using a supplied
154: * JAXBContext to marshall msg. The cause of
155: * the WebServicException is the original JAXBException.
156: */
157: public Response<Object> invokeAsync(Object msg)
158: throws WebServiceException {
159:
160: MessageStruct messageStruct = setupMessageStruct(msg);
161: messageStruct.setMEP(MessageStruct.ASYNC_POLL_MEP);
162: Object result = sendAsync(messageStruct);
163: if (result instanceof Response)
164: return (Response<Object>) result;
165: else
166: throw (RuntimeException) result;
167: }
168:
169: /**
170: * Invoke a service operation asynchronously. The
171: * method returns without waiting for the response to the operation
172: * invocation, the results of the operation are communicated to the client
173: * via the passed in handler.
174: * <p/>
175: * The client is responsible for ensuring that the <code>msg</code> object
176: * when marshalled is formed according to the requirements of the protocol
177: * binding in use.
178: *
179: * @param msg An object that, when marshalled, will form the payload of
180: * the message used to invoke the operation. Must be an instance of
181: * either <code>javax.xml.transform.Source</code> or a JAXB object. If
182: * <code>msg</code> is an instance of a JAXB object then the request
183: * context must have the <code>javax.xml.ws.binding.context</code>
184: * property set.
185: * @param handler The handler object that will receive the
186: * response to the operation invocation. The object
187: * returned by <code>Response.get()</code> is
188: * either an instance of
189: * <code>javax.xml.transform.Source</code> or a JAXB object.
190: * @return A <code>Future</code> object that may be used to check the status
191: * of the operation invocation. This object must not be used to try to
192: * obtain the results of the operation - the object returned from
193: * <code>Future<?>.get()</code> is implementation dependent
194: * and any use of it will result in non-portable behaviour.
195: * @throws javax.xml.ws.WebServiceException
196: * If there is any error in the configuration of
197: * the <code>Dispatch</code> instance
198: * @throws javax.xml.ws.WebServiceException
199: * If an error occurs when using a supplied
200: * JAXBContext to marshall msg. The cause of
201: * the WebServiceException is the original JAXBException.
202: */
203: public Future<?> invokeAsync(java.lang.Object msg,
204: AsyncHandler handler) {
205:
206: MessageStruct messageStruct = setupMessageStruct(msg);
207: if (handler != null) {
208: messageStruct
209: .setMetaData(
210: BindingProviderProperties.JAXWS_CLIENT_ASYNC_HANDLER,
211: (Object) new AsyncHandlerService(handler,
212: getCurrentExecutor()));
213: } else
214: throw new WebServiceException(
215: "AsyncHandler argument is null. "
216: + "AsyncHandler is required for asynchronous callback invocations ");
217:
218: messageStruct.setMEP(MessageStruct.ASYNC_CALLBACK_MEP);
219: Object result = sendAsync(messageStruct);
220: if (result instanceof WSFuture)
221: return (Future<Object>) result;
222: else
223: throw (RuntimeException) result;
224: }
225:
226: /**
227: * Invokes a service operation using the one-way
228: * interaction mode. The operation invocation is logically non-blocking,
229: * subject to the capabilities of the underlying protocol, no results
230: * are returned. When
231: * the protocol in use is SOAP/HTTP, this method must block until
232: * an HTTP response code has been received or an error occurs.
233: * <p/>
234: * The client is responsible for ensuring that the <code>msg</code> object
235: * when marshalled is formed according to the requirements of the protocol
236: * binding in use.
237: *
238: * @param msg An object that, when marshalled, will form the payload of
239: * the message used to invoke the operation. Must be an instance of
240: * either <code>javax.xml.transform.Source</code> or a JAXB object. If
241: * <code>msg</code> is an instance of a JAXB object then the request
242: * context must have the <code>javax.xml.ws.binding.context</code>
243: * property set.
244: * @throws javax.xml.ws.WebServiceException
245: * If there is any error in the configuration of
246: * the <code>Dispatch</code> instance or if an error occurs during the
247: * invocation.
248: * @throws javax.xml.ws.WebServiceException
249: * If an error occurs when using a supplied
250: * JAXBContext to marshall msg. The cause of
251: * the WebServiceException is the original JAXBException.
252: */
253:
254: public void invokeOneWay(Object msg) {
255:
256: MessageStruct messageStruct = setupMessageStruct(msg);
257: messageStruct.setMEP(MessageStruct.ONE_WAY_MEP);
258: sendOneWay(messageStruct);
259: }
260:
261: private boolean hasJAXBContext(Object msg,
262: MessageStruct messageStruct) {
263: RequestContext requestContext = (RequestContext) getRequestContext();
264: if (_jaxbContext != null) {
265: requestContext.put(
266: BindingProviderProperties.JAXB_CONTEXT_PROPERTY,
267: _jaxbContext);
268: return true;
269: }
270: return false;
271: }
272:
273: public void _setDelegate(Delegate delegate) {
274: _delegate = delegate;
275: }
276:
277: public Delegate _getDelegate() {
278: return _delegate;
279: }
280:
281: public static void setDefaultTransportFactory(
282: ClientTransportFactory factory) {
283: defaultTransportFactory = factory;
284: }
285:
286: public static ClientTransportFactory getDefaultTransportFactory() {
287: if (defaultTransportFactory == null)
288: defaultTransportFactory = new HttpClientTransportFactory();
289: return defaultTransportFactory;
290: }
291:
292: public ClientTransportFactory _getTransportFactory() {
293: _transportFactory = (ClientTransportFactory) getRequestContext()
294: .get(BindingProviderProperties.CLIENT_TRANSPORT_FACTORY);
295:
296: if (_transportFactory == null) {
297: _transportFactory = new HttpClientTransportFactory();
298: }
299: return _transportFactory;
300: }
301:
302: public void _setTransportFactory(
303: com.sun.xml.internal.ws.spi.runtime.ClientTransportFactory f) {
304: getRequestContext().put(
305: BindingProviderProperties.CLIENT_TRANSPORT_FACTORY, f);
306: _transportFactory = (ClientTransportFactory) f;
307: }
308:
309: private Object sendAndReceive(MessageStruct messageStruct) {
310: Object response = null;
311:
312: _delegate.send(messageStruct);
313: response = messageStruct.getResponse();
314: updateResponseContext(messageStruct);
315: //((ContextMap) getRequestContext()).clear();
316: switch (messageStruct.getResponseType()) {
317:
318: case MessageStruct.NORMAL_RESPONSE:
319: //not sure where this belongs yet - but for now-
320: break;
321: case MessageStruct.CHECKED_EXCEPTION_RESPONSE:
322: if (response instanceof SOAPFaultException)
323: throw (SOAPFaultException) response;
324: if (response instanceof SOAPFaultInfo) {
325: SOAPFaultInfo soapFaultInfo = (SOAPFaultInfo) response;
326: JAXBException jbe = null;
327: if (soapFaultInfo.getString()
328: .contains("javax.xml.bind")) {
329: jbe = new JAXBException(soapFaultInfo.getString());
330: //do I need to put this in a webservice exception
331: SOAPFaultException sfe = new SOAPFaultException(
332: soapFaultInfo.getSOAPFault());
333: sfe.initCause(jbe);
334: } else
335: throw new SOAPFaultException(soapFaultInfo
336: .getSOAPFault());
337: } else if (response instanceof HTTPException) {
338: throw (HTTPException) response;
339: } else if (response instanceof RuntimeException)
340: throw (RuntimeException) response;
341: case MessageStruct.UNCHECKED_EXCEPTION_RESPONSE:
342: if (response instanceof SOAPFaultException) {
343: throw (SOAPFaultException) response;
344: } else if (response instanceof HTTPException) {
345: throw (HTTPException) response;
346: } else if (response instanceof RuntimeException) {
347: throw (RuntimeException) response;
348: }
349: break; //just break and return response
350: default:
351: if (response != null) //must be some kind of exception
352: throw new WebServiceException(
353: "Client side exception - examine cause ",
354: (Exception) response);
355: }
356: return response;
357: }
358:
359: private Object sendAsync(MessageStruct messageStruct)
360: throws WebServiceException {
361: Object response = null;
362: _lock = new ReentrantLock();
363: _lock.lock();
364: try {
365: _delegate.send(messageStruct);
366: response = messageStruct.getResponse();
367: } catch (Throwable t) {
368: throw (RuntimeException) t;
369: } finally {
370: _lock.unlock();
371: }
372: return response;
373: }
374:
375: private void sendOneWay(MessageStruct messageStruct) {
376:
377: _delegate.send(messageStruct);
378: Object response = messageStruct.getResponse();
379: //no exceptions should be returned from server but
380: //exceptions may be returned from the client
381: switch (messageStruct.getResponseType()) {
382: case MessageStruct.NORMAL_RESPONSE:
383: break;
384: case MessageStruct.CHECKED_EXCEPTION_RESPONSE:
385: case MessageStruct.UNCHECKED_EXCEPTION_RESPONSE:
386: //before invocation
387: if (response instanceof RuntimeException)
388: throw (RuntimeException) response;
389: default:
390: throw new RuntimeException("Client side Exception ");
391: }
392: }
393:
394: private MessageStruct setupMessageStruct(Object msg)
395: throws WebServiceException {
396: MessageStruct messageStruct = _delegate.getMessageStruct();
397:
398: if (msg != null) {
399: MessageFactory factory = null;
400: if (((msg instanceof Source) && _mode == MESSAGE)
401: && (!_getBindingId().toString().equals(
402: HTTPBinding.HTTP_BINDING))) {
403: try {
404:
405: if (_getBindingId().toString().equals(
406: SOAPBinding.SOAP12HTTP_BINDING))
407: factory = MessageFactory
408: .newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
409: else
410: factory = MessageFactory
411: .newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
412:
413: SOAPMessage message = factory.createMessage();
414: message.getSOAPPart().setContent((Source) msg);
415: message.saveChanges();
416: msg = message;
417: } catch (SOAPException se) {
418: throw new WebServiceException(se);
419: }
420: }
421:
422: //setMessageStruct(messageStruct, msg);
423:
424: } else {
425: //todo - needs to be a get request
426: if (!isValidNullParameter(msg))
427: throw new WebServiceException(
428: "This is not a valid request ");
429: }
430: setMessageStruct(messageStruct, msg);
431: return messageStruct;
432: }
433:
434: private void setMessageStruct(MessageStruct messageStruct,
435: Object msg) {
436: messageStruct.setData(new Object[] { msg });
437: setMetadata(getRequestContext(), msg, messageStruct);
438: //set mtom threshold value to
439: Object mtomThreshold = getRequestContext().get(
440: BindingProviderProperties.MTOM_THRESHOLOD_VALUE);
441: messageStruct.setMetaData(
442: BindingProviderProperties.MTOM_THRESHOLOD_VALUE,
443: mtomThreshold);
444:
445: // Set MTOM processing for XML requests only
446: String bindingId = (getBinding() instanceof SOAPBinding) ? ((SOAPBindingImpl) binding)
447: .getBindingId().toString()
448: : HTTPBinding.HTTP_BINDING;
449: if (bindingId.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
450: || bindingId
451: .equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING))
452: messageStruct.setMetaData(
453: "com.sun.xml.internal.ws.mtom.enabled",
454: ((SOAPBindingImpl) getBinding()).isMTOMEnabled());
455:
456: // Initialize content negotiation property
457: ContentNegotiation.initialize(getRequestContext(),
458: messageStruct);
459: }
460:
461: private void updateResponseContext(MessageStruct messageStruct) {
462: ResponseContext responseContext = (ResponseContext) messageStruct
463: .getMetaData(BindingProviderProperties.JAXWS_RESPONSE_CONTEXT_PROPERTY);
464: setResponseContext(responseContext);
465: }
466:
467: private void setMetadata(Map jaxwsContext, Object obj,
468: MessageStruct messageStruct) {
469:
470: jaxwsContext.put(
471: BindingProviderProperties.JAXWS_CLIENT_HANDLE_PROPERTY,
472: this );
473:
474: if (jaxwsContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY) == null)
475: jaxwsContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
476: _portInfo.getTargetEndpoint());
477:
478: jaxwsContext.put(BindingProviderProperties.BINDING_ID_PROPERTY,
479: _getBindingId().toString());
480: if (_jaxbContext != null)
481: jaxwsContext.put(
482: BindingProviderProperties.JAXB_CONTEXT_PROPERTY,
483: _jaxbContext);
484: messageStruct.setMetaData(
485: BindingProviderProperties.JAXWS_CONTEXT_PROPERTY,
486: jaxwsContext);
487:
488: messageStruct.setMetaData(
489: DispatchContext.DISPATCH_MESSAGE_MODE, _mode);
490: if (_clazz != null)
491: messageStruct.setMetaData(
492: DispatchContext.DISPATCH_MESSAGE_CLASS, _clazz);
493:
494: DispatchContext context = setDispatchContext(jaxwsContext, obj,
495: _mode);
496: messageStruct.setMetaData(
497: BindingProviderProperties.DISPATCH_CONTEXT, context);
498: }
499:
500: public Binding getBinding() {
501: return (Binding) binding;
502: }
503:
504: public void _setBinding(BindingImpl binding) {
505: this .binding = binding;
506: }
507:
508: // default for now is soap binding
509: public String _getBindingId() {
510: _bindingId = _portInfo.getBindingId();
511: if (_bindingId == null) {
512: _bindingId = SOAPBinding.SOAP11HTTP_BINDING;
513: }
514: return _bindingId;
515: }
516:
517: /**
518: * Get the jaxwsContext that is used in processing request messages.
519: * <p/>
520: * Modifications to the request context do not affect asynchronous
521: * operations that have already been started.
522: *
523: * @return The jaxwsContext that is used in processing request messages.
524: */
525: public Map getRequestContext() {
526: if (_requestContext == null)
527: _requestContext = new RequestContext(this );
528:
529: return _requestContext;
530: }
531:
532: private void setResponseContext(ResponseContext context) {
533: _responseContext = context;
534: }
535:
536: /**
537: * Get the jaxwsContext that resulted from processing a response message.
538: * <p/>
539: * The returned context is for the most recently completed synchronous
540: * operation. Subsequent synchronous operation invocations overwrite the
541: * response context. Asynchronous operations return their response context
542: * via the Response interface.
543: *
544: * @return The jaxwsContext that is used in processing request messages.
545: */
546: public Map getResponseContext() {
547: if (_responseContext == null)
548: _responseContext = new ResponseContext(this );
549: return _responseContext;
550: }
551:
552: public DispatchContext setDispatchContext(Map jaxwsContext,
553: Object obj, Service.Mode mode) {
554:
555: DispatchContext context = new DispatchContext();
556: context
557: .setProperty(DispatchContext.DISPATCH_MESSAGE_MODE,
558: mode);
559:
560: if (obj != null) {
561: if (obj instanceof Source) {
562: context.setProperty(
563: DispatchContext.DISPATCH_MESSAGE_CLASS,
564: DispatchContext.MessageClass.SOURCE);
565: } else if (obj instanceof SOAPMessage) {
566: context.setProperty(
567: DispatchContext.DISPATCH_MESSAGE_CLASS,
568: DispatchContext.MessageClass.SOAPMESSAGE);
569: } else if ((obj instanceof DataSource)
570: && _getBindingId().toString().equals(
571: HTTPBinding.HTTP_BINDING)) {
572: context.setProperty(
573: DispatchContext.DISPATCH_MESSAGE_CLASS,
574: DispatchContext.MessageClass.DATASOURCE);
575:
576: } else if (_jaxbContext != null) {
577: context.setProperty(
578: DispatchContext.DISPATCH_MESSAGE_CLASS,
579: DispatchContext.MessageClass.JAXBOBJECT);
580: } else {
581: if (!_getBindingId().toString().equals(
582: HTTPBinding.HTTP_BINDING))
583: throw new WebServiceException(
584: "Object is not a javax.xml.transform.Source or there is no JAXB Context");
585: }
586: }
587:
588: if (_clazz != null) {
589: if (_clazz.isAssignableFrom(Source.class)) {
590: if (mode == PAYLOAD) {
591: if (_getBindingId().toString().equals(
592: HTTPBinding.HTTP_BINDING))
593: context
594: .setProperty(
595: DispatchContext.DISPATCH_MESSAGE,
596: DispatchContext.MessageType.HTTP_SOURCE_PAYLOAD);
597: else
598: context
599: .setProperty(
600: DispatchContext.DISPATCH_MESSAGE,
601: DispatchContext.MessageType.SOURCE_PAYLOAD);
602: } else if (mode == MESSAGE) {
603: if (_getBindingId().toString().equals(
604: HTTPBinding.HTTP_BINDING))
605: context
606: .setProperty(
607: DispatchContext.DISPATCH_MESSAGE,
608: DispatchContext.MessageType.HTTP_SOURCE_MESSAGE);
609: else
610: context
611: .setProperty(
612: DispatchContext.DISPATCH_MESSAGE,
613: DispatchContext.MessageType.SOURCE_MESSAGE);
614: }
615: } else if (_clazz.isAssignableFrom(SOAPMessage.class)) {
616: if (mode == PAYLOAD) {
617: throw new WebServiceException(
618: "SOAPMessages must be Service.Mode.MESSAGE. ");
619: } else if (mode == MESSAGE)
620: context
621: .setProperty(
622: DispatchContext.DISPATCH_MESSAGE,
623: DispatchContext.MessageType.SOAPMESSAGE_MESSAGE);
624: } else if (_clazz.isAssignableFrom(DataSource.class)) {
625: if (mode == PAYLOAD)
626: throw new WebServiceException(
627: "Can not have a Datahandler class with mode PAYLOAD");
628: //context.setProperty(DispatchContext.DISPATCH_MESSAGE, DispatchContext.MessageType.HTTP_DATASOURCE_PAYLOAD);
629: else if (mode == MESSAGE)
630: context
631: .setProperty(
632: DispatchContext.DISPATCH_MESSAGE,
633: DispatchContext.MessageType.HTTP_DATASOURCE_MESSAGE);
634: } else {
635: context.setProperty(
636: DispatchContext.DISPATCH_MESSAGE_CLASS, _clazz);
637: }
638: } else if (hasJAXBContext(obj, null)) {
639: if (mode == PAYLOAD) {
640: if (_getBindingId().toString().equals(
641: HTTPBinding.HTTP_BINDING))
642: context
643: .setProperty(
644: DispatchContext.DISPATCH_MESSAGE,
645: DispatchContext.MessageType.HTTP_JAXB_PAYLOAD);
646: else
647: context.setProperty(
648: DispatchContext.DISPATCH_MESSAGE,
649: DispatchContext.MessageType.JAXB_PAYLOAD);
650: } else if (mode == MESSAGE) {
651: if (_getBindingId().toString().equals(
652: HTTPBinding.HTTP_BINDING))
653: throw new WebServiceException(
654: " Can not have a JAXB object with mode MESSAGE");
655: //context.setProperty(DispatchContext.DISPATCH_MESSAGE, DispatchContext.MessageType.HTTP_JAXB_MESSAGE);
656: else
657: context.setProperty(
658: DispatchContext.DISPATCH_MESSAGE,
659: DispatchContext.MessageType.JAXB_MESSAGE);
660: }
661: }
662:
663: return context;
664: }
665:
666: Executor getCurrentExecutor() {
667: return _service.getExecutor();
668: }
669:
670: public QName getServiceName() {
671: if (_service != null)
672: return _service.getServiceName();
673: return null;
674: }
675:
676: public QName getPortName() {
677: if (_portInfo != null)
678: return _portInfo.getName();
679: return null;
680: }
681:
682: private boolean isValidNullParameter(Object msg) {
683: if (msg != null)
684: return true;
685:
686: String method = (String) getRequestContext().get(
687: MessageContext.HTTP_REQUEST_METHOD);
688: if (method == null)
689: method = "POST";
690:
691: String bindingId = _getBindingId().toString();
692: if (("POST".equalsIgnoreCase(method))) {
693:
694: if (SOAPBinding.SOAP11HTTP_BINDING.equals(bindingId)
695: || SOAPBinding.SOAP11HTTP_MTOM_BINDING
696: .equals(bindingId)) {
697: switch (_mode) {
698: case MESSAGE:
699: throw new WebServiceException(
700: "SOAP 1.1 Binding with null invocation parameter is not allowed with HTTP POST Request Method in MESSAGE mode");
701: //return false;
702: case PAYLOAD:
703: return true;
704: }
705: } else if (HTTPBinding.HTTP_BINDING.equals(bindingId)) {
706: switch (_mode) {
707: case MESSAGE:
708: case PAYLOAD:
709: throw new WebServiceException(
710: "XML/HTTP Binding with null invocation parameter is not allowed with HTTP POST Request Method in MESSAGE or PAYLOAD mode");
711: }
712:
713: } else if (SOAPBinding.SOAP12HTTP_BINDING.equals(bindingId)
714: || SOAPBinding.SOAP12HTTP_MTOM_BINDING
715: .equals(bindingId)) {
716: switch (_mode) {
717: case MESSAGE:
718: throw new WebServiceException(
719: "SOAP 1.2 Binding with null invocation parameter is not allowed with HTTP POST Request Method in MESSAGE mode");
720: //return false;
721: case PAYLOAD:
722: return true;
723: }
724: }
725:
726: } else if ("GET".equalsIgnoreCase(method)) {
727:
728: if (SOAPBinding.SOAP12HTTP_BINDING.equals(bindingId)
729: || SOAPBinding.SOAP12HTTP_MTOM_BINDING
730: .equals(bindingId)) {
731: switch (_mode) {
732: case MESSAGE:
733: //return false;
734: throw new WebServiceException(
735: "SOAP 1.2 Binding with null invocation parameter is not allowed with HTTP GET Request Method in MESAGE mode.");
736: case PAYLOAD:
737: return true;
738: }
739: } else if (SOAPBinding.SOAP11HTTP_BINDING.equals(bindingId)
740: || SOAPBinding.SOAP11HTTP_MTOM_BINDING
741: .equals(bindingId)) {
742: switch (_mode) {
743: case MESSAGE:
744: case PAYLOAD:
745: throw new WebServiceException(
746: "SOAP 1.1 Binding with null invocation parameter is not allowed with HTTP GET Request Method in either PAYLOAD or MESAGE mode.");
747: //return false;
748: }
749: } else if (HTTPBinding.HTTP_BINDING.equals(bindingId)) {
750: switch (_mode) {
751: case MESSAGE:
752: case PAYLOAD:
753: return true;
754: }
755: }
756:
757: } else if ("DELETE".equalsIgnoreCase(method)
758: || "HEAD".equalsIgnoreCase(method)) {
759:
760: if (HTTPBinding.HTTP_BINDING.equals(bindingId)) {
761: switch (_mode) {
762: case MESSAGE:
763: case PAYLOAD:
764: return true;
765: }
766: } else if (SOAPBinding.SOAP12HTTP_BINDING.equals(bindingId)
767: || SOAPBinding.SOAP12HTTP_MTOM_BINDING
768: .equals(bindingId)) {
769: switch (_mode) {
770: case MESSAGE:
771: //return false;
772: throw new WebServiceException(
773: "SOAP 1.2 Binding with null invocation parameter is not allowed with HTTP "
774: + method
775: + " Request Method in MESAGE mode.");
776: case PAYLOAD:
777: return true;
778: }
779: } else if (SOAPBinding.SOAP11HTTP_BINDING.equals(bindingId)
780: || SOAPBinding.SOAP11HTTP_MTOM_BINDING
781: .equals(bindingId)) {
782: //return false;
783: throw new WebServiceException(
784: "SOAP 1.1 Binding with null invocation parameter is not allowed with HTTP "
785: + method
786: + " Request Method in either PAYLOAD or MESAGE mode.");
787: //return false;
788: }
789:
790: }
791: return false;
792: }
793:
794: private static ClientTransportFactory defaultTransportFactory = null;
795: private static final Logger logger = Logger
796: .getLogger(new StringBuffer()
797: .append(
798: com.sun.xml.internal.ws.util.Constants.LoggingDomain)
799: .append(".client.dispatch").toString());
800:
801: protected Map _requestContext;
802: protected Map _responseContext;
803: protected Service.Mode _mode;
804: protected WSServiceDelegate _service;
805: protected Class _clazz;
806: protected JAXBContext _jaxbContext;
807:
808: protected Delegate _delegate = null;
809: protected PortInfoBase _portInfo = null;
810:
811: protected String _bindingId = null;
812: protected BindingImpl binding;
813:
814: private ClientTransportFactory _transportFactory;
815: private Lock _lock;
816:
817: }
|