diff -r 88b85470e72c -r f50545b5e2f1 src/share/jaxws_classes/com/sun/xml/internal/ws/client/dispatch/DispatchImpl.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/client/dispatch/DispatchImpl.java Tue Mar 06 16:09:35 2012 -0800
@@ -0,0 +1,621 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.xml.internal.ws.client.dispatch;
+
+import com.sun.istack.internal.NotNull;
+import com.sun.istack.internal.Nullable;
+import com.sun.xml.internal.ws.api.BindingID;
+import com.sun.xml.internal.ws.api.SOAPVersion;
+import com.sun.xml.internal.ws.api.WSBinding;
+import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
+import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
+import com.sun.xml.internal.ws.api.client.WSPortInfo;
+import com.sun.xml.internal.ws.api.message.Attachment;
+import com.sun.xml.internal.ws.api.message.AttachmentSet;
+import com.sun.xml.internal.ws.api.message.Message;
+import com.sun.xml.internal.ws.api.message.Packet;
+import com.sun.xml.internal.ws.api.pipe.Fiber;
+import com.sun.xml.internal.ws.api.pipe.Tube;
+import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptor;
+import com.sun.xml.internal.ws.binding.BindingImpl;
+import com.sun.xml.internal.ws.client.*;
+import com.sun.xml.internal.ws.encoding.soap.DeserializationException;
+import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
+import com.sun.xml.internal.ws.message.AttachmentSetImpl;
+import com.sun.xml.internal.ws.message.DataHandlerAttachment;
+import com.sun.xml.internal.ws.resources.DispatchMessages;
+
+import javax.activation.DataHandler;
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Response;
+import javax.xml.ws.Service;
+import javax.xml.ws.Service.Mode;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.http.HTTPBinding;
+import javax.xml.ws.soap.SOAPBinding;
+import javax.xml.ws.soap.SOAPFaultException;
+import javax.xml.ws.WebServiceClient;
+import javax.xml.ws.WebEndpoint;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.lang.reflect.Method;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * The DispatchImpl
abstract class provides support
+ * for the dynamic invocation of a service endpoint operation using XML
+ * constructs, JAXB objects or SOAPMessage
. The javax.xml.ws.Service
+ * interface acts as a factory for the creation of DispatchImpl
+ * instances.
+ *
+ * @author WS Development Team
+ * @version 1.0
+ */
+public abstract class DispatchImpl extends Stub implements Dispatch {
+
+ private static final Logger LOGGER = Logger.getLogger(DispatchImpl.class.getName());
+
+ final Service.Mode mode;
+ final SOAPVersion soapVersion;
+ final boolean allowFaultResponseMsg;
+ static final long AWAIT_TERMINATION_TIME = 800L;
+
+ /**
+ *
+ * @param port dispatch instance is associated with this wsdl port qName
+ * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD
+ * @param owner Service that created the Dispatch
+ * @param pipe Master pipe for the pipeline
+ * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP
+ */
+ @Deprecated
+ protected DispatchImpl(QName port, Service.Mode mode, WSServiceDelegate owner, Tube pipe, BindingImpl binding, @Nullable WSEndpointReference epr) {
+ super(port, owner, pipe, binding, (owner.getWsdlService() != null)? owner.getWsdlService().get(port) : null , owner.getEndpointAddress(port), epr);
+ this.mode = mode;
+ this.soapVersion = binding.getSOAPVersion();
+ this.allowFaultResponseMsg = false;
+ }
+
+ /**
+ * @param portInfo dispatch instance is associated with this portInfo
+ * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD
+ * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP
+ */
+ protected DispatchImpl(WSPortInfo portInfo, Service.Mode mode, BindingImpl binding, @Nullable WSEndpointReference epr) {
+ this(portInfo, mode, binding, epr, false);
+ }
+
+ /**
+ * @param portInfo dispatch instance is associated with this portInfo
+ * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD
+ * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP
+ * @param allowFaultResponseMsg A packet containing a SOAP fault message is allowed as the response to a request on this dispatch instance.
+ */
+ protected DispatchImpl(WSPortInfo portInfo, Service.Mode mode, BindingImpl binding, @Nullable WSEndpointReference epr, boolean allowFaultResponseMsg) {
+ this(portInfo, mode, binding, null, epr, allowFaultResponseMsg);
+ }
+
+ /**
+ * @param portInfo dispatch instance is associated with this portInfo
+ * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD
+ * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP
+ * @param pipe Master pipe for the pipeline
+ * @param allowFaultResponseMsg A packet containing a SOAP fault message is allowed as the response to a request on this dispatch instance.
+ */
+ protected DispatchImpl(WSPortInfo portInfo, Service.Mode mode, BindingImpl binding, Tube pipe, @Nullable WSEndpointReference epr, boolean allowFaultResponseMsg) {
+ super(portInfo, binding, pipe, portInfo.getEndpointAddress(), epr);
+ this.mode = mode;
+ this.soapVersion = binding.getSOAPVersion();
+ this.allowFaultResponseMsg = allowFaultResponseMsg;
+ }
+ /**
+ *
+ * @param port dispatch instance is associated with this wsdl port qName
+ * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD
+ * @param owner Service that created the Dispatch
+ * @param pipe Master pipe for the pipeline
+ * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP
+ * @param allowFaultResponseMsg A packet containing a SOAP fault message is allowed as the response to a request on this dispatch instance.
+ */
+ protected DispatchImpl(WSPortInfo portInfo, Service.Mode mode, Tube pipe, BindingImpl binding, @Nullable WSEndpointReference epr, boolean allowFaultResponseMsg) {
+ super(portInfo, binding, pipe, portInfo.getEndpointAddress(), epr);
+ this.mode = mode;
+ this.soapVersion = binding.getSOAPVersion();
+ this.allowFaultResponseMsg = allowFaultResponseMsg;
+ }
+
+ /**
+ * Abstract method that is implemented by each concrete Dispatch class
+ * @param msg message passed in from the client program on the invocation
+ * @return The Message created returned as the Interface in actuallity a
+ * concrete Message Type
+ */
+ abstract Packet createPacket(T msg);
+
+ /**
+ * Obtains the value to return from the response message.
+ */
+ abstract T toReturnValue(Packet response);
+
+ public final Response invokeAsync(T param) {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ dumpParam(param, "invokeAsync(T)");
+ }
+ AsyncInvoker invoker = new DispatchAsyncInvoker(param);
+ AsyncResponseImpl ft = new AsyncResponseImpl(invoker,null);
+ invoker.setReceiver(ft);
+ ft.run();
+ return ft;
+ }
+
+ private void dumpParam(T param, String method) {
+ if (param instanceof Packet) {
+ Packet message = (Packet)param;
+
+ String action;
+ String msgId;
+ if (LOGGER.isLoggable(Level.FINE)) {
+ AddressingVersion av = DispatchImpl.this.getBinding().getAddressingVersion();
+ SOAPVersion sv = DispatchImpl.this.getBinding().getSOAPVersion();
+ action =
+ av != null && message.getMessage() != null ?
+ message.getMessage().getHeaders().getAction(av, sv) : null;
+ msgId =
+ av != null && message.getMessage() != null ?
+ message.getMessage().getHeaders().getMessageID(av, sv) : null;
+ LOGGER.fine("In DispatchImpl." + method + " for message with action: " + action + " and msg ID: " + msgId + " msg: " + message.getMessage());
+
+ if (message.getMessage() == null) {
+ LOGGER.fine("Dispatching null message for action: " + action + " and msg ID: " + msgId);
+ }
+ }
+ }
+ }
+ public final Future> invokeAsync(T param, AsyncHandler asyncHandler) {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ dumpParam(param, "invokeAsync(T, AsyncHandler)");
+ }
+ AsyncInvoker invoker = new DispatchAsyncInvoker(param);
+ AsyncResponseImpl ft = new AsyncResponseImpl(invoker,asyncHandler);
+ invoker.setReceiver(ft);
+ invoker.setNonNullAsyncHandlerGiven(asyncHandler != null);
+
+ ft.run();
+ return ft;
+ }
+
+ /**
+ * Synchronously invokes a service.
+ *
+ * See {@link #process(Packet, RequestContext, ResponseContextReceiver)} on
+ * why it takes a {@link RequestContext} and {@link ResponseContextReceiver} as a parameter.
+ */
+ public final T doInvoke(T in, RequestContext rc, ResponseContextReceiver receiver){
+ Packet response = null;
+ try {
+ try {
+ checkNullAllowed(in, rc, binding, mode);
+
+ Packet message = createPacket(in);
+ resolveEndpointAddress(message, rc);
+ setProperties(message,true);
+ response = process(message,rc,receiver);
+ Message msg = response.getMessage();
+
+ // REVIEW: eliminate allowFaultResponseMsg, but make that behavior default for MessageDispatch, PacketDispatch
+ if(msg != null && msg.isFault() &&
+ !allowFaultResponseMsg) {
+ SOAPFaultBuilder faultBuilder = SOAPFaultBuilder.create(msg);
+ // passing null means there is no checked excpetion we're looking for all
+ // it will get back to us is a protocol exception
+ throw (SOAPFaultException)faultBuilder.createException(null);
+ }
+ } catch (JAXBException e) {
+ //TODO: i18nify
+ throw new DeserializationException(DispatchMessages.INVALID_RESPONSE_DESERIALIZATION(),e);
+ } catch(WebServiceException e){
+ //it could be a WebServiceException or a ProtocolException
+ throw e;
+ } catch(Throwable e){
+ // it could be a RuntimeException resulting due to some internal bug or
+ // its some other exception resulting from user error, wrap it in
+ // WebServiceException
+ throw new WebServiceException(e);
+ }
+
+ return toReturnValue(response);
+ } finally {
+ // REVIEW: Move to AsyncTransportProvider
+ if (response != null && response.transportBackChannel != null)
+ response.transportBackChannel.close();
+ }
+ }
+
+ public final T invoke(T in) {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ dumpParam(in, "invoke(T)");
+ }
+
+ return doInvoke(in,requestContext,this);
+ }
+
+ public final void invokeOneWay(T in) {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ dumpParam(in, "invokeOneWay(T)");
+ }
+
+ try {
+ checkNullAllowed(in, requestContext, binding, mode);
+
+ Packet request = createPacket(in);
+ setProperties(request,false);
+ Packet response = process(request,requestContext,this);
+ } catch(WebServiceException e){
+ //it could be a WebServiceException or a ProtocolException
+ throw e;
+ } catch(Throwable e){
+ // it could be a RuntimeException resulting due to some internal bug or
+ // its some other exception resulting from user error, wrap it in
+ // WebServiceException
+ throw new WebServiceException(e);
+ }
+ }
+
+ void setProperties(Packet packet, boolean expectReply) {
+ packet.expectReply = expectReply;
+ }
+
+ static boolean isXMLHttp(@NotNull WSBinding binding) {
+ return binding.getBindingId().equals(BindingID.XML_HTTP);
+ }
+
+ static boolean isPAYLOADMode(@NotNull Service.Mode mode) {
+ return mode == Service.Mode.PAYLOAD;
+ }
+
+ static void checkNullAllowed(@Nullable Object in, RequestContext rc, WSBinding binding, Service.Mode mode) {
+
+ if (in != null)
+ return;
+
+ //With HTTP Binding a null invocation parameter can not be used
+ //with HTTP Request Method == POST
+ if (isXMLHttp(binding)){
+ if (methodNotOk(rc))
+ throw new WebServiceException(DispatchMessages.INVALID_NULLARG_XMLHTTP_REQUEST_METHOD(HTTP_REQUEST_METHOD_POST, HTTP_REQUEST_METHOD_GET));
+ } else { //soapBinding
+ if (mode == Service.Mode.MESSAGE )
+ throw new WebServiceException(DispatchMessages.INVALID_NULLARG_SOAP_MSGMODE(mode.name(), Service.Mode.PAYLOAD.toString()));
+ }
+ }
+
+ static boolean methodNotOk(@NotNull RequestContext rc) {
+ String requestMethod = (String)rc.get(MessageContext.HTTP_REQUEST_METHOD);
+ String request = (requestMethod == null)? HTTP_REQUEST_METHOD_POST: requestMethod;
+ // if method == post or put with a null invocation parameter in xml/http binding this is not ok
+ return HTTP_REQUEST_METHOD_POST.equalsIgnoreCase(request) || HTTP_REQUEST_METHOD_PUT.equalsIgnoreCase(request);
+ }
+
+ public static void checkValidSOAPMessageDispatch(WSBinding binding, Service.Mode mode) {
+ // Dispatch is only valid for soap binding and in Service.Mode.MESSAGE
+ if (DispatchImpl.isXMLHttp(binding))
+ throw new WebServiceException(DispatchMessages.INVALID_SOAPMESSAGE_DISPATCH_BINDING(HTTPBinding.HTTP_BINDING, SOAPBinding.SOAP11HTTP_BINDING + " or " + SOAPBinding.SOAP12HTTP_BINDING));
+ if (DispatchImpl.isPAYLOADMode(mode))
+ throw new WebServiceException(DispatchMessages.INVALID_SOAPMESSAGE_DISPATCH_MSGMODE(mode.name(), Service.Mode.MESSAGE.toString()));
+ }
+
+ public static void checkValidDataSourceDispatch(WSBinding binding, Service.Mode mode) {
+ // Dispatch is only valid with xml/http binding and in Service.Mode.MESSAGE
+ if (!DispatchImpl.isXMLHttp(binding))
+ throw new WebServiceException(DispatchMessages.INVALID_DATASOURCE_DISPATCH_BINDING("SOAP/HTTP", HTTPBinding.HTTP_BINDING));
+ if (DispatchImpl.isPAYLOADMode(mode))
+ throw new WebServiceException(DispatchMessages.INVALID_DATASOURCE_DISPATCH_MSGMODE(mode.name(), Service.Mode.MESSAGE.toString()));
+ }
+
+ public final @NotNull QName getPortName() {
+ return portname;
+ }
+
+ void resolveEndpointAddress(@NotNull Packet message, @NotNull RequestContext requestContext) {
+ //resolve endpoint look for query parameters, pathInfo
+ String endpoint = (String) requestContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+ if (endpoint == null)
+ endpoint = message.endpointAddress.toString();
+
+ String pathInfo = null;
+ String queryString = null;
+ if (requestContext.get(MessageContext.PATH_INFO) != null)
+ pathInfo = (String) requestContext.get(MessageContext.PATH_INFO);
+
+ if (requestContext.get(MessageContext.QUERY_STRING) != null)
+ queryString = (String) requestContext.get(MessageContext.QUERY_STRING);
+
+
+ String resolvedEndpoint = null;
+ if (pathInfo != null || queryString != null) {
+ pathInfo = checkPath(pathInfo);
+ queryString = checkQuery(queryString);
+ if (endpoint != null) {
+ try {
+ final URI endpointURI = new URI(endpoint);
+ resolvedEndpoint = resolveURI(endpointURI, pathInfo, queryString);
+ } catch (URISyntaxException e) {
+ throw new WebServiceException(DispatchMessages.INVALID_URI(endpoint));
+ }
+ }
+ requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, resolvedEndpoint);
+ //message.endpointAddress = EndpointAddress.create(resolvedEndpoint);
+ }
+ }
+
+ protected @NotNull String resolveURI(@NotNull URI endpointURI, @Nullable String pathInfo, @Nullable String queryString) {
+ String query = null;
+ String fragment = null;
+ if (queryString != null) {
+ final URI result;
+ try {
+ URI tp = new URI(null, null, endpointURI.getPath(), queryString, null);
+ result = endpointURI.resolve(tp);
+ } catch (URISyntaxException e) {
+ throw new WebServiceException(DispatchMessages.INVALID_QUERY_STRING(queryString));
+ }
+ query = result.getQuery();
+ fragment = result.getFragment();
+ }
+
+ final String path = (pathInfo != null) ? pathInfo : endpointURI.getPath();
+ try {
+ //final URI temp = new URI(null, null, path, query, fragment);
+ //return endpointURI.resolve(temp).toURL().toExternalForm();
+ // Using the following HACK instead of the above to avoid double encoding of
+ // the query. Application's QUERY_STRING is encoded using URLEncoder.encode().
+ // If we use that query in URI's constructor, it is encoded again.
+ // URLEncoder's encoding is not the same as URI's encoding of the query.
+ // See {@link URL}
+ StringBuilder spec = new StringBuilder();
+ if (path != null) {
+ spec.append(path);
+ }
+ if (query != null) {
+ spec.append("?");
+ spec.append(query);
+ }
+ if (fragment != null) {
+ spec.append("#");
+ spec.append(fragment);
+ }
+ return new URL(endpointURI.toURL(), spec.toString()).toExternalForm();
+ } catch (MalformedURLException e) {
+ throw new WebServiceException(DispatchMessages.INVALID_URI_RESOLUTION(path));
+ }
+ }
+
+ private static String checkPath(@Nullable String path) {
+ //does it begin with /
+ return (path == null || path.startsWith("/")) ? path : "/" + path;
+ }
+
+ private static String checkQuery(@Nullable String query) {
+ if (query == null) return null;
+
+ if (query.indexOf('?') == 0)
+ throw new WebServiceException(DispatchMessages.INVALID_QUERY_LEADING_CHAR(query));
+ return query;
+ }
+
+
+ protected AttachmentSet setOutboundAttachments() {
+ HashMap attachments = (HashMap)
+ getRequestContext().get(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS);
+
+ if (attachments != null) {
+ List alist = new ArrayList();
+ for (Map.Entry att : attachments.entrySet()) {
+ DataHandlerAttachment dha = new DataHandlerAttachment(att.getKey(), att.getValue());
+ alist.add(dha);
+ }
+ return new AttachmentSetImpl(alist);
+ }
+ return new AttachmentSetImpl();
+ }
+
+ /* private void getInboundAttachments(Message msg) {
+ AttachmentSet attachments = msg.getAttachments();
+ if (!attachments.isEmpty()) {
+ Map in = new HashMap();
+ for (Attachment attachment : attachments)
+ in.put(attachment.getContentId(), attachment.asDataHandler());
+ getResponseContext().put(MessageContext.INBOUND_MESSAGE_ATTACHMENTS, in);
+ }
+
+ }
+ */
+
+
+ /**
+ * Calls {@link DispatchImpl#doInvoke(Object,RequestContext,ResponseContextReceiver)}.
+ */
+ private class Invoker implements Callable {
+ private final T param;
+ // snapshot the context now. this is necessary to avoid concurrency issue,
+ // and is required by the spec
+ private final RequestContext rc = requestContext.copy();
+
+ /**
+ * Because of the object instantiation order,
+ * we can't take this as a constructor parameter.
+ */
+ private ResponseContextReceiver receiver;
+
+ Invoker(T param) {
+ this.param = param;
+ }
+
+ public T call() throws Exception {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ dumpParam(param, "call()");
+ }
+ return doInvoke(param,rc,receiver);
+ }
+
+ void setReceiver(ResponseContextReceiver receiver) {
+ this.receiver = receiver;
+ }
+ }
+
+ /**
+ *
+ */
+ private class DispatchAsyncInvoker extends AsyncInvoker {
+ private final T param;
+ // snapshot the context now. this is necessary to avoid concurrency issue,
+ // and is required by the spec
+ private final RequestContext rc = requestContext.copy();
+
+ DispatchAsyncInvoker(T param) {
+ this.param = param;
+ }
+
+ public void do_run () {
+ checkNullAllowed(param, rc, binding, mode);
+ final Packet message = createPacket(param);
+ message.nonNullAsyncHandlerGiven = this.nonNullAsyncHandlerGiven;
+ resolveEndpointAddress(message, rc);
+ setProperties(message,true);
+
+ String action = null;
+ String msgId = null;
+ if (LOGGER.isLoggable(Level.FINE)) {
+ AddressingVersion av = DispatchImpl.this.getBinding().getAddressingVersion();
+ SOAPVersion sv = DispatchImpl.this.getBinding().getSOAPVersion();
+ action =
+ av != null && message.getMessage() != null ?
+ message.getMessage().getHeaders().getAction(av, sv) : null;
+ msgId =
+ av != null&& message.getMessage() != null ?
+ message.getMessage().getHeaders().getMessageID(av, sv) : null;
+ LOGGER.fine("In DispatchAsyncInvoker.do_run for async message with action: " + action + " and msg ID: " + msgId);
+ }
+
+ final String actionUse = action;
+ final String msgIdUse = msgId;
+
+ Fiber.CompletionCallback callback = new Fiber.CompletionCallback() {
+ public void onCompletion(@NotNull Packet response) {
+
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("Done with processAsync in DispatchAsyncInvoker.do_run, and setting response for async message with action: " + actionUse + " and msg ID: " + msgIdUse);
+ }
+
+ Message msg = response.getMessage();
+
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("Done with processAsync in DispatchAsyncInvoker.do_run, and setting response for async message with action: " + actionUse + " and msg ID: " + msgIdUse + " msg: " + msg);
+ }
+
+ try {
+ if(msg != null && msg.isFault() &&
+ !allowFaultResponseMsg) {
+ SOAPFaultBuilder faultBuilder = SOAPFaultBuilder.create(msg);
+ // passing null means there is no checked excpetion we're looking for all
+ // it will get back to us is a protocol exception
+ throw (SOAPFaultException)faultBuilder.createException(null);
+ }
+ responseImpl.setResponseContext(new ResponseContext(response));
+ responseImpl.set(toReturnValue(response), null);
+ } catch (JAXBException e) {
+ //TODO: i18nify
+ responseImpl.set(null, new DeserializationException(DispatchMessages.INVALID_RESPONSE_DESERIALIZATION(),e));
+ } catch(WebServiceException e){
+ //it could be a WebServiceException or a ProtocolException
+ responseImpl.set(null, e);
+ } catch(Throwable e){
+ // It could be any RuntimeException resulting due to some internal bug.
+ // or its some other exception resulting from user error, wrap it in
+ // WebServiceException
+ responseImpl.set(null, new WebServiceException(e));
+ }
+ }
+ public void onCompletion(@NotNull Throwable error) {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("Done with processAsync in DispatchAsyncInvoker.do_run, and setting response for async message with action: " + actionUse + " and msg ID: " + msgIdUse + " Throwable: " + error.toString());
+ }
+ if (error instanceof WebServiceException) {
+ responseImpl.set(null, error);
+
+ } else {
+ //its RuntimeException or some other exception resulting from user error, wrap it in
+ // WebServiceException
+ responseImpl.set(null, new WebServiceException(error));
+ }
+ }
+ };
+ processAsync(responseImpl,message,rc, callback);
+ }
+ }
+
+ public void setOutboundHeaders(Object... headers) {
+ throw new UnsupportedOperationException();
+ }
+
+ static final String HTTP_REQUEST_METHOD_GET="GET";
+ static final String HTTP_REQUEST_METHOD_POST="POST";
+ static final String HTTP_REQUEST_METHOD_PUT="PUT";
+
+ @Deprecated
+ public static Dispatch createSourceDispatch(QName port, Mode mode, WSServiceDelegate owner, Tube pipe, BindingImpl binding, WSEndpointReference epr) {
+ if(isXMLHttp(binding))
+ return new RESTSourceDispatch(port,mode,owner,pipe,binding,epr);
+ else
+ return new SOAPSourceDispatch(port,mode,owner,pipe,binding,epr);
+ }
+
+ public static Dispatch createSourceDispatch(WSPortInfo portInfo, Mode mode, BindingImpl binding, WSEndpointReference epr) {
+ if (isXMLHttp(binding))
+ return new RESTSourceDispatch(portInfo, mode, binding, epr);
+ else
+ return new SOAPSourceDispatch(portInfo, mode, binding, epr);
+ }
+}