14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * This code is free software; you can redistribute it and/or modify it
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * under the terms of the GNU General Public License version 2 only, as
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * published by the Free Software Foundation. Oracle designates this
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * particular file as subject to the "Classpath" exception as provided
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * by Oracle in the LICENSE file that accompanied this code.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * This code is distributed in the hope that it will be useful, but WITHOUT
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * version 2 for more details (a copy is included in the LICENSE file that
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * accompanied this code).
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * You should have received a copy of the GNU General Public License version
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * 2 along with this work; if not, write to the Free Software Foundation,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * or visit www.oracle.com if you need additional information or have any
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * questions.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncpackage com.sun.xml.internal.ws.client.dispatch;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.istack.internal.NotNull;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.istack.internal.Nullable;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.BindingID;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.SOAPVersion;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.WSBinding;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.client.WSPortInfo;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.message.Attachment;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.message.AttachmentSet;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.message.Message;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.message.Packet;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.pipe.Fiber;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.api.pipe.Tube;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.binding.BindingImpl;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.client.*;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.encoding.soap.DeserializationException;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.message.AttachmentSetImpl;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.message.DataHandlerAttachment;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport com.sun.xml.internal.ws.resources.DispatchMessages;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.activation.DataHandler;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.bind.JAXBException;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.namespace.QName;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.transform.Source;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.AsyncHandler;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.BindingProvider;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.Dispatch;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.Response;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.Service;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.Service.Mode;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.WebServiceException;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.handler.MessageContext;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.http.HTTPBinding;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.soap.SOAPBinding;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport javax.xml.ws.soap.SOAPFaultException;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.net.MalformedURLException;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.net.URI;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.net.URISyntaxException;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.net.URL;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.ArrayList;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.HashMap;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.List;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.Map;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.concurrent.Callable;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.concurrent.ExecutorService;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.concurrent.Future;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncimport java.util.concurrent.TimeUnit;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/**
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * The <code>DispatchImpl</code> abstract class provides support
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * for the dynamic invocation of a service endpoint operation using XML
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * constructs, JAXB objects or <code>SOAPMessage</code>. The <code>javax.xml.ws.Service</code>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * interface acts as a factory for the creation of <code>DispatchImpl</code>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * instances.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @author WS Development Team
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @version 1.0
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncpublic abstract class DispatchImpl<T> extends Stub implements Dispatch<T> {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync final Service.Mode mode;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync final QName portname;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync final SOAPVersion soapVersion;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync static final long AWAIT_TERMINATION_TIME = 800L;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync /**
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param port dispatch instance is asssociated with this wsdl port qName
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param owner Service that created the Dispatch
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param pipe Master pipe for the pipeline
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync @Deprecated
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync protected DispatchImpl(QName port, Service.Mode mode, WSServiceDelegate owner, Tube pipe, BindingImpl binding, @Nullable WSEndpointReference epr) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync super(owner, pipe, binding, (owner.getWsdlService() != null)? owner.getWsdlService().get(port) : null , owner.getEndpointAddress(port), epr);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync this.portname = port;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync this.mode = mode;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync this.soapVersion = binding.getSOAPVersion();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync /**
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param portInfo dispatch instance is asssociated with this portInfo
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync protected DispatchImpl(WSPortInfo portInfo, Service.Mode mode, BindingImpl binding, @Nullable WSEndpointReference epr) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync super(portInfo, binding, portInfo.getEndpointAddress(), epr);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync this.portname = portInfo.getPortName();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync this.mode = mode;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync this.soapVersion = binding.getSOAPVersion();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync /**
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Abstract method that is implemented by each concrete Dispatch class
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @param msg message passed in from the client program on the invocation
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * @return The Message created returned as the Interface in actuallity a
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * concrete Message Type
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync abstract Packet createPacket(T msg);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync /**
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Obtains the value to return from the response message.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync abstract T toReturnValue(Packet response);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync public final Response<T> invokeAsync(T param) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync AsyncInvoker invoker = new DispatchAsyncInvoker(param);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync AsyncResponseImpl<T> ft = new AsyncResponseImpl<T>(invoker,null);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync invoker.setReceiver(ft);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ft.run();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return ft;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync public final Future<?> invokeAsync(T param, AsyncHandler<T> asyncHandler) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync AsyncInvoker invoker = new DispatchAsyncInvoker(param);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync AsyncResponseImpl<T> ft = new AsyncResponseImpl<T>(invoker,asyncHandler);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync invoker.setReceiver(ft);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // temp needed so that unit tests run and complete otherwise they may
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //not. Need a way to put this in the test harness or other way to do this
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //todo: as above
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync// ExecutorService exec = (ExecutorService) owner.getExecutor();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync// try {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync// exec.awaitTermination(AWAIT_TERMINATION_TIME, TimeUnit.MICROSECONDS);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync// } catch (InterruptedException e) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync// throw new WebServiceException(e);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync// }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ft.run();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return ft;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync /**
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Synchronously invokes a service.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * See {@link #process(Packet, RequestContext, ResponseContextReceiver)} on
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * why it takes a {@link RequestContext} and {@link ResponseContextReceiver} as a parameter.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync public final T doInvoke(T in, RequestContext rc, ResponseContextReceiver receiver){
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync Packet response;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync try {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync checkNullAllowed(in, rc, binding, mode);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync Packet message = createPacket(in);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync resolveEndpointAddress(message, rc);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync setProperties(message,true);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync response = process(message,rc,receiver);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync Message msg = response.getMessage();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if(msg != null && msg.isFault()) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync SOAPFaultBuilder faultBuilder = SOAPFaultBuilder.create(msg);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // passing null means there is no checked excpetion we're looking for all
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // it will get back to us is a protocol exception
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw (SOAPFaultException)faultBuilder.createException(null);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } catch (JAXBException e) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //TODO: i18nify
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new DeserializationException(DispatchMessages.INVALID_RESPONSE_DESERIALIZATION(),e);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } catch(WebServiceException e){
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //it could be a WebServiceException or a ProtocolException
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw e;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } catch(Throwable e){
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // it could be a RuntimeException resulting due to some internal bug or
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // its some other exception resulting from user error, wrap it in
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // WebServiceException
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(e);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return toReturnValue(response);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync public final T invoke(T in) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return doInvoke(in,requestContext,this);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync public final void invokeOneWay(T in) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync try {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync checkNullAllowed(in, requestContext, binding, mode);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync Packet request = createPacket(in);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync setProperties(request,false);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync Packet response = process(request,requestContext,this);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } catch(WebServiceException e){
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //it could be a WebServiceException or a ProtocolException
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw e;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } catch(Throwable e){
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // it could be a RuntimeException resulting due to some internal bug or
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // its some other exception resulting from user error, wrap it in
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // WebServiceException
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(e);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync void setProperties(Packet packet, boolean expectReply) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync packet.expectReply = expectReply;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync static boolean isXMLHttp(@NotNull WSBinding binding) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return binding.getBindingId().equals(BindingID.XML_HTTP);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync static boolean isPAYLOADMode(@NotNull Service.Mode mode) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return mode == Service.Mode.PAYLOAD;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync static void checkNullAllowed(@Nullable Object in, RequestContext rc, WSBinding binding, Service.Mode mode) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (in != null)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //With HTTP Binding a null invocation parameter can not be used
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //with HTTP Request Method == POST
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (isXMLHttp(binding)){
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (methodNotOk(rc))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(DispatchMessages.INVALID_NULLARG_XMLHTTP_REQUEST_METHOD(HTTP_REQUEST_METHOD_POST, HTTP_REQUEST_METHOD_GET));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } else { //soapBinding
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (mode == Service.Mode.MESSAGE )
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(DispatchMessages.INVALID_NULLARG_SOAP_MSGMODE(mode.name(), Service.Mode.PAYLOAD.toString()));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync static boolean methodNotOk(@NotNull RequestContext rc) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync String requestMethod = (String)rc.get(MessageContext.HTTP_REQUEST_METHOD);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync String request = (requestMethod == null)? HTTP_REQUEST_METHOD_POST: requestMethod;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // if method == post or put with a null invocation parameter in xml/http binding this is not ok
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return HTTP_REQUEST_METHOD_POST.equalsIgnoreCase(request) || HTTP_REQUEST_METHOD_PUT.equalsIgnoreCase(request);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync public static void checkValidSOAPMessageDispatch(WSBinding binding, Service.Mode mode) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // Dispatch<SOAPMessage> is only valid for soap binding and in Service.Mode.MESSAGE
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (DispatchImpl.isXMLHttp(binding))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(DispatchMessages.INVALID_SOAPMESSAGE_DISPATCH_BINDING(HTTPBinding.HTTP_BINDING, SOAPBinding.SOAP11HTTP_BINDING + " or " + SOAPBinding.SOAP12HTTP_BINDING));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (DispatchImpl.isPAYLOADMode(mode))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(DispatchMessages.INVALID_SOAPMESSAGE_DISPATCH_MSGMODE(mode.name(), Service.Mode.MESSAGE.toString()));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync public static void checkValidDataSourceDispatch(WSBinding binding, Service.Mode mode) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync // Dispatch<DataSource> is only valid with xml/http binding and in Service.Mode.MESSAGE
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (!DispatchImpl.isXMLHttp(binding))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(DispatchMessages.INVALID_DATASOURCE_DISPATCH_BINDING("SOAP/HTTP", HTTPBinding.HTTP_BINDING));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (DispatchImpl.isPAYLOADMode(mode))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync throw new WebServiceException(DispatchMessages.INVALID_DATASOURCE_DISPATCH_MSGMODE(mode.name(), Service.Mode.MESSAGE.toString()));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync protected final @NotNull QName getPortName() {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return portname;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync void resolveEndpointAddress(@NotNull Packet message, @NotNull RequestContext requestContext) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync //resolve endpoint look for query parameters, pathInfo
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync String endpoint = (String) requestContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (endpoint == null)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync 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<String, DataHandler> attachments = (HashMap<String, DataHandler>)
getRequestContext().get(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS);
if (attachments != null) {
List<Attachment> alist = new ArrayList();
for (Map.Entry<String, DataHandler> 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<String, DataHandler> in = new HashMap<String, DataHandler>();
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 {
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);
Packet message = createPacket(param);
resolveEndpointAddress(message, rc);
setProperties(message,true);
Fiber.CompletionCallback callback = new Fiber.CompletionCallback() {
public void onCompletion(@NotNull Packet response) {
Message msg = response.getMessage();
try {
if(msg != null && msg.isFault()) {
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 (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(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<Source> 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<Source> 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);
}
}