diff -r 000000000000 -r 373ffda63c9a src/share/jaxws_classes/com/sun/xml/internal/ws/client/Stub.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/client/Stub.java Wed Apr 27 01:27:09 2016 +0800
@@ -0,0 +1,753 @@
+/*
+ * Copyright (c) 1997, 2013, 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;
+
+import com.sun.istack.internal.NotNull;
+import com.sun.istack.internal.Nullable;
+import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
+import com.sun.xml.internal.ws.addressing.WSEPRExtension;
+import com.sun.xml.internal.ws.api.BindingID;
+import com.sun.xml.internal.ws.api.Component;
+import com.sun.xml.internal.ws.api.ComponentFeature;
+import com.sun.xml.internal.ws.api.ComponentFeature.Target;
+import com.sun.xml.internal.ws.api.ComponentRegistry;
+import com.sun.xml.internal.ws.api.ComponentsFeature;
+import com.sun.xml.internal.ws.api.EndpointAddress;
+import com.sun.xml.internal.ws.api.WSBinding;
+import com.sun.xml.internal.ws.api.WSService;
+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.AddressingUtils;
+import com.sun.xml.internal.ws.api.message.Header;
+import com.sun.xml.internal.ws.api.message.HeaderList;
+import com.sun.xml.internal.ws.api.message.MessageHeaders;
+import com.sun.xml.internal.ws.api.message.Packet;
+import com.sun.xml.internal.ws.api.model.SEIModel;
+import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
+import com.sun.xml.internal.ws.api.pipe.ClientTubeAssemblerContext;
+import com.sun.xml.internal.ws.api.pipe.Engine;
+import com.sun.xml.internal.ws.api.pipe.Fiber;
+import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptorFactory;
+import com.sun.xml.internal.ws.api.pipe.SyncStartForAsyncFeature;
+import com.sun.xml.internal.ws.api.pipe.Tube;
+import com.sun.xml.internal.ws.api.pipe.TubelineAssembler;
+import com.sun.xml.internal.ws.api.pipe.TubelineAssemblerFactory;
+import com.sun.xml.internal.ws.api.server.Container;
+import com.sun.xml.internal.ws.api.server.ContainerResolver;
+import com.sun.xml.internal.ws.binding.BindingImpl;
+import com.sun.xml.internal.ws.developer.JAXWSProperties;
+import com.sun.xml.internal.ws.developer.WSBindingProvider;
+import com.sun.xml.internal.ws.model.wsdl.WSDLDirectProperties;
+import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties;
+import com.sun.xml.internal.ws.model.wsdl.WSDLProperties;
+import com.sun.xml.internal.ws.resources.ClientMessages;
+import com.sun.xml.internal.ws.util.Pool;
+import com.sun.xml.internal.ws.util.Pool.TubePool;
+import com.sun.xml.internal.ws.util.RuntimeVersion;
+import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
+import com.sun.org.glassfish.gmbal.ManagedObjectManager;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.EndpointReference;
+import javax.xml.ws.RespectBindingFeature;
+import javax.xml.ws.Response;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.http.HTTPBinding;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.ObjectName;
+
+/**
+ * Base class for stubs, which accept method invocations from
+ * client applications and pass the message to a {@link Tube}
+ * for processing.
+ *
+ *
+ * This class implements the management of pipe instances,
+ * and most of the {@link BindingProvider} methods.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+public abstract class Stub implements WSBindingProvider, ResponseContextReceiver, ComponentRegistry {
+ /**
+ * Internal flag indicating async dispatch should be used even when the
+ * SyncStartForAsyncInvokeFeature is present on the binding associated
+ * with a stub. There is no type associated with this property on the
+ * request context. Its presence is what triggers the 'prevent' behavior.
+ */
+ public static final String PREVENT_SYNC_START_FOR_ASYNC_INVOKE = "com.sun.xml.internal.ws.client.StubRequestSyncStartForAsyncInvoke";
+
+ /**
+ * Reuse pipelines as it's expensive to create.
+ *
+ * Set to null when {@link #close() closed}.
+ */
+ private Pool tubes;
+
+ private final Engine engine;
+
+ /**
+ * The {@link WSServiceDelegate} object that owns us.
+ */
+ protected final WSServiceDelegate owner;
+
+ /**
+ * Non-null if this stub is configured to talk to an EPR.
+ *
+ * When this field is non-null, its reference parameters are sent as out-bound headers.
+ * This field can be null even when addressing is enabled, but if the addressing is
+ * not enabled, this field must be null.
+ *
+ * Unlike endpoint address, we are not letting users to change the EPR,
+ * as it contains references to services and so on that we don't want to change.
+ */
+ protected
+ @Nullable
+ WSEndpointReference endpointReference;
+
+ protected final BindingImpl binding;
+
+ protected final WSPortInfo portInfo;
+
+ /**
+ * represents AddressingVersion on binding if enabled, otherwise null;
+ */
+ protected AddressingVersion addrVersion;
+
+ public RequestContext requestContext = new RequestContext();
+
+ private final RequestContext cleanRequestContext;
+
+ /**
+ * {@link ResponseContext} from the last synchronous operation.
+ */
+ private ResponseContext responseContext;
+ @Nullable
+ protected final WSDLPort wsdlPort;
+
+ protected QName portname;
+
+ /**
+ * {@link Header}s to be added to outbound {@link Packet}.
+ * The contents is determined by the user.
+ */
+ @Nullable
+ private volatile Header[] userOutboundHeaders;
+
+ private final
+ @NotNull
+ WSDLProperties wsdlProperties;
+ protected OperationDispatcher operationDispatcher = null;
+ private final
+ @NotNull
+ ManagedObjectManager managedObjectManager;
+ private boolean managedObjectManagerClosed = false;
+
+ private final Set components = new CopyOnWriteArraySet();
+
+ /**
+ * @param master The created stub will send messages to this pipe.
+ * @param binding As a {@link BindingProvider}, this object will
+ * return this binding from {@link BindingProvider#getBinding()}.
+ * @param defaultEndPointAddress The destination of the message. The actual destination
+ * could be overridden by {@link RequestContext}.
+ * @param epr To create a stub that sends out reference parameters
+ * of a specific EPR, give that instance. Otherwise null.
+ * Its address field will not be used, and that should be given
+ * separately as the defaultEndPointAddress.
+ */
+ @Deprecated
+ protected Stub(WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
+ this(owner, master, null, null, binding, wsdlPort, defaultEndPointAddress, epr);
+ }
+
+ /**
+ * @param portname The name of this port
+ * @param master The created stub will send messages to this pipe.
+ * @param binding As a {@link BindingProvider}, this object will
+ * return this binding from {@link BindingProvider#getBinding()}.
+ * @param defaultEndPointAddress The destination of the message. The actual destination
+ * could be overridden by {@link RequestContext}.
+ * @param epr To create a stub that sends out reference parameters
+ * of a specific EPR, give that instance. Otherwise null.
+ * Its address field will not be used, and that should be given
+ * separately as the defaultEndPointAddress.
+ */
+ @Deprecated
+ protected Stub(QName portname, WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
+ this(owner, master, null, portname, binding, wsdlPort, defaultEndPointAddress, epr);
+ }
+
+ /**
+ * @param portInfo PortInfo for this stub
+ * @param binding As a {@link BindingProvider}, this object will
+ * return this binding from {@link BindingProvider#getBinding()}.
+ * @param master The created stub will send messages to this pipe.
+ * @param defaultEndPointAddress The destination of the message. The actual destination
+ * could be overridden by {@link RequestContext}.
+ * @param epr To create a stub that sends out reference parameters
+ * of a specific EPR, give that instance. Otherwise null.
+ * Its address field will not be used, and that should be given
+ * separately as the defaultEndPointAddress.
+ */
+ protected Stub(WSPortInfo portInfo, BindingImpl binding, Tube master,EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
+ this((WSServiceDelegate) portInfo.getOwner(), master, portInfo, null, binding,portInfo.getPort(), defaultEndPointAddress, epr);
+ }
+
+ /**
+ * @param portInfo PortInfo for this stub
+ * @param binding As a {@link BindingProvider}, this object will
+ * return this binding from {@link BindingProvider#getBinding()}.
+ * @param defaultEndPointAddress The destination of the message. The actual destination
+ * could be overridden by {@link RequestContext}.
+ * @param epr To create a stub that sends out reference parameters
+ * of a specific EPR, give that instance. Otherwise null.
+ * Its address field will not be used, and that should be given
+ * separately as the defaultEndPointAddress.
+ */
+ protected Stub(WSPortInfo portInfo, BindingImpl binding, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
+ this(portInfo,binding,null, defaultEndPointAddress,epr);
+
+ }
+
+ private Stub(WSServiceDelegate owner, @Nullable Tube master, @Nullable WSPortInfo portInfo, QName portname, BindingImpl binding, @Nullable WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
+ Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer());
+ try {
+ this.owner = owner;
+ this.portInfo = portInfo;
+ this.wsdlPort = wsdlPort != null ? wsdlPort : (portInfo != null ? portInfo.getPort() : null);
+ this.portname = portname;
+ if (portname == null) {
+ if (portInfo != null) {
+ this.portname = portInfo.getPortName();
+ } else if (wsdlPort != null) {
+ this.portname = wsdlPort.getName();
+ }
+ }
+ this.binding = binding;
+
+ ComponentFeature cf = binding.getFeature(ComponentFeature.class);
+ if (cf != null && Target.STUB.equals(cf.getTarget())) {
+ components.add(cf.getComponent());
+ }
+ ComponentsFeature csf = binding.getFeature(ComponentsFeature.class);
+ if (csf != null) {
+ for (ComponentFeature cfi : csf.getComponentFeatures()) {
+ if (Target.STUB.equals(cfi.getTarget()))
+ components.add(cfi.getComponent());
+ }
+ }
+
+ // if there is an EPR, EPR's address should be used for invocation instead of default address
+ if (epr != null) {
+ this.requestContext.setEndPointAddressString(epr.getAddress());
+ } else {
+ this.requestContext.setEndpointAddress(defaultEndPointAddress);
+ }
+ this.engine = new Engine(getStringId(), owner.getContainer(), owner.getExecutor());
+ this.endpointReference = epr;
+ wsdlProperties = (wsdlPort == null) ? new WSDLDirectProperties(owner.getServiceName(), portname) : new WSDLPortProperties(wsdlPort);
+
+ this.cleanRequestContext = this.requestContext.copy();
+
+ // ManagedObjectManager MUST be created before the pipeline
+ // is constructed.
+
+ managedObjectManager = new MonitorRootClient(this).createManagedObjectManager(this);
+
+ if (master != null) {
+ this.tubes = new TubePool(master);
+ } else {
+ this.tubes = new TubePool(createPipeline(portInfo, binding));
+ }
+
+ addrVersion = binding.getAddressingVersion();
+
+ // This needs to happen after createPipeline.
+ // TBD: Check if it needs to happen outside the Stub constructor.
+ managedObjectManager.resumeJMXRegistration();
+ } finally {
+ ContainerResolver.getDefault().exitContainer(old);
+ }
+ }
+
+ /**
+ * Creates a new pipeline for the given port name.
+ */
+ private Tube createPipeline(WSPortInfo portInfo, WSBinding binding) {
+ //Check all required WSDL extensions are understood
+ checkAllWSDLExtensionsUnderstood(portInfo, binding);
+ SEIModel seiModel = null;
+ Class sei = null;
+ if (portInfo instanceof SEIPortInfo) {
+ SEIPortInfo sp = (SEIPortInfo) portInfo;
+ seiModel = sp.model;
+ sei = sp.sei;
+ }
+ BindingID bindingId = portInfo.getBindingId();
+
+ TubelineAssembler assembler = TubelineAssemblerFactory.create(
+ Thread.currentThread().getContextClassLoader(), bindingId, owner.getContainer());
+ if (assembler == null) {
+ throw new WebServiceException("Unable to process bindingID=" + bindingId); // TODO: i18n
+ }
+ return assembler.createClient(
+ new ClientTubeAssemblerContext(
+ portInfo.getEndpointAddress(),
+ portInfo.getPort(),
+ this, binding, owner.getContainer(), ((BindingImpl) binding).createCodec(), seiModel, sei));
+ }
+
+ public WSDLPort getWSDLPort() {
+ return wsdlPort;
+ }
+
+ public WSService getService() {
+ return owner;
+ }
+
+ public Pool getTubes() {
+ return tubes;
+ }
+
+ /**
+ * Checks only if RespectBindingFeature is enabled
+ * checks if all required wsdl extensions in the
+ * corresponding wsdl:Port are understood when RespectBindingFeature is enabled.
+ * @throws WebServiceException
+ * when any wsdl extension that has wsdl:required=true is not understood
+ */
+ private static void checkAllWSDLExtensionsUnderstood(WSPortInfo port, WSBinding binding) {
+ if (port.getPort() != null && binding.isFeatureEnabled(RespectBindingFeature.class)) {
+ port.getPort().areRequiredExtensionsUnderstood();
+ }
+ }
+
+ @Override
+ public WSPortInfo getPortInfo() {
+ return portInfo;
+ }
+
+ /**
+ * Nullable when there is no associated WSDL Model
+ * @return
+ */
+ public
+ @Nullable
+ OperationDispatcher getOperationDispatcher() {
+ if (operationDispatcher == null && wsdlPort != null) {
+ operationDispatcher = new OperationDispatcher(wsdlPort, binding, null);
+ }
+ return operationDispatcher;
+ }
+
+ /**
+ * Gets the port name that this stub is configured to talk to.
+ *
+ * When {@link #wsdlPort} is non-null, the port name is always
+ * the same as {@link WSDLPort#getName()}, but this method
+ * returns a port name even if no WSDL is available for this stub.
+ */
+ protected abstract
+ @NotNull
+ QName getPortName();
+
+ /**
+ * Gets the service name that this stub is configured to talk to.
+ *
+ * When {@link #wsdlPort} is non-null, the service name is always
+ * the same as the one that's inferred from {@link WSDLPort#getOwner()},
+ * but this method returns a port name even if no WSDL is available for
+ * this stub.
+ */
+ protected final
+ @NotNull
+ QName getServiceName() {
+ return owner.getServiceName();
+ }
+
+ /**
+ * Gets the {@link Executor} to be used for asynchronous method invocations.
+ *
+ * Note that the value this method returns may different from invocations
+ * to invocations. The caller must not cache.
+ *
+ * @return always non-null.
+ */
+ public final Executor getExecutor() {
+ return owner.getExecutor();
+ }
+
+ /**
+ * Passes a message to a pipe for processing.
+ *
+ * Unlike {@link Tube} instances,
+ * this method is thread-safe and can be invoked from
+ * multiple threads concurrently.
+ *
+ * @param packet The message to be sent to the server
+ * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
+ * This must be the same object as {@link #requestContext} for synchronous
+ * invocations, but for asynchronous invocations, it needs to be a snapshot
+ * captured at the point of invocation, to correctly satisfy the spec requirement.
+ * @param receiver Receives the {@link ResponseContext}. Since the spec requires
+ * that the asynchronous invocations must not update response context,
+ * depending on the mode of invocation they have to go to different places.
+ * So we take a setter that abstracts that away.
+ */
+ protected final Packet process(Packet packet, RequestContext requestContext, ResponseContextReceiver receiver) {
+ packet.isSynchronousMEP = true;
+ packet.component = this;
+ configureRequestPacket(packet, requestContext);
+ Pool pool = tubes;
+ if (pool == null) {
+ throw new WebServiceException("close method has already been invoked"); // TODO: i18n
+ }
+
+ Fiber fiber = engine.createFiber();
+ configureFiber(fiber);
+
+ // then send it away!
+ Tube tube = pool.take();
+
+ try {
+ return fiber.runSync(tube, packet);
+ } finally {
+ // this allows us to capture the packet even when the call failed with an exception.
+ // when the call fails with an exception it's no longer a 'reply' but it may provide some information
+ // about what went wrong.
+
+ // note that Packet can still be updated after
+ // ResponseContext is created.
+ Packet reply = (fiber.getPacket() == null) ? packet : fiber.getPacket();
+ receiver.setResponseContext(new ResponseContext(reply));
+
+ pool.recycle(tube);
+ }
+ }
+
+ private void configureRequestPacket(Packet packet, RequestContext requestContext) {
+ // fill in Packet
+ packet.proxy = this;
+ packet.handlerConfig = binding.getHandlerConfig();
+
+ // to make it multi-thread safe we need to first get a stable snapshot
+ Header[] hl = userOutboundHeaders;
+ if (hl != null) {
+ MessageHeaders mh = packet.getMessage().getHeaders();
+ for (Header h : hl) {
+ mh.add(h);
+ }
+ }
+
+ requestContext.fill(packet, (binding.getAddressingVersion() != null));
+ packet.addSatellite(wsdlProperties);
+
+ if (addrVersion != null) {
+ // populate request WS-Addressing headers
+ MessageHeaders headerList = packet.getMessage().getHeaders();
+ AddressingUtils.fillRequestAddressingHeaders(headerList, wsdlPort, binding, packet);
+
+
+ // Spec is not clear on if ReferenceParameters are to be added when addressing is not enabled,
+ // but the EPR has ReferenceParameters.
+ // Current approach: Add ReferenceParameters only if addressing enabled.
+ if (endpointReference != null) {
+ endpointReference.addReferenceParametersToList(packet.getMessage().getHeaders());
+ }
+ }
+ }
+
+ /**
+ * Passes a message through a {@link Tube}line for processing. The processing happens
+ * asynchronously and when the response is available, Fiber.CompletionCallback is
+ * called. The processing could happen on multiple threads.
+ *
+ *
+ * Unlike {@link Tube} instances,
+ * this method is thread-safe and can be invoked from
+ * multiple threads concurrently.
+ *
+ * @param receiver The {@link Response} implementation
+ * @param request The message to be sent to the server
+ * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
+ * This must be the same object as {@link #requestContext} for synchronous
+ * invocations, but for asynchronous invocations, it needs to be a snapshot
+ * captured at the point of invocation, to correctly satisfy the spec requirement.
+ * @param completionCallback Once the processing is done, the callback is invoked.
+ */
+ protected final void processAsync(AsyncResponseImpl> receiver, Packet request, RequestContext requestContext, final Fiber.CompletionCallback completionCallback) {
+ // fill in Packet
+ request.component = this;
+ configureRequestPacket(request, requestContext);
+
+ final Pool pool = tubes;
+ if (pool == null) {
+ throw new WebServiceException("close method has already been invoked"); // TODO: i18n
+ }
+
+ final Fiber fiber = engine.createFiber();
+ configureFiber(fiber);
+
+ receiver.setCancelable(fiber);
+
+ // check race condition on cancel
+ if (receiver.isCancelled()) {
+ return;
+ }
+
+ FiberContextSwitchInterceptorFactory fcsif = owner.getSPI(FiberContextSwitchInterceptorFactory.class);
+ if (fcsif != null) {
+ fiber.addInterceptor(fcsif.create());
+ }
+
+ // then send it away!
+ final Tube tube = pool.take();
+
+ Fiber.CompletionCallback fiberCallback = new Fiber.CompletionCallback() {
+ @Override
+ public void onCompletion(@NotNull Packet response) {
+ pool.recycle(tube);
+ completionCallback.onCompletion(response);
+ }
+
+ @Override
+ public void onCompletion(@NotNull Throwable error) {
+ // let's not reuse tubes as they might be in a wrong state, so not
+ // calling pool.recycle()
+ completionCallback.onCompletion(error);
+ }
+ };
+
+ // Check for SyncStartForAsyncInvokeFeature
+
+ fiber.start(tube, request, fiberCallback,
+ getBinding().isFeatureEnabled(SyncStartForAsyncFeature.class) &&
+ !requestContext.containsKey(PREVENT_SYNC_START_FOR_ASYNC_INVOKE));
+ }
+
+ protected void configureFiber(Fiber fiber) {
+ // no-op in the base class, but can be used by derived classes to configure the Fiber prior
+ // to invocation
+ }
+
+ private static final Logger monitoringLogger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
+
+ @Override
+ public void close() {
+ TubePool tp = (TubePool) tubes;
+ if (tp != null) {
+ // multi-thread safety of 'close' needs to be considered more carefully.
+ // some calls might be pending while this method is invoked. Should we
+ // block until they are complete, or should we abort them (but how?)
+ Tube p = tp.takeMaster();
+ p.preDestroy();
+ tubes = null;
+ }
+ if (!managedObjectManagerClosed) {
+ try {
+ final ObjectName name = managedObjectManager.getObjectName(managedObjectManager.getRoot());
+ // The name is null when the MOM is a NOOP.
+ if (name != null) {
+ monitoringLogger.log(Level.INFO, "Closing Metro monitoring root: {0}", name);
+ }
+ managedObjectManager.close();
+ } catch (java.io.IOException e) {
+ monitoringLogger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e);
+ }
+ managedObjectManagerClosed = true;
+ }
+ }
+
+ @Override
+ public final WSBinding getBinding() {
+ return binding;
+ }
+
+ @Override
+ public final Map getRequestContext() {
+ return requestContext.asMap();
+ }
+
+ public void resetRequestContext() {
+ requestContext = cleanRequestContext.copy();
+ }
+
+ @Override
+ public final ResponseContext getResponseContext() {
+ return responseContext;
+ }
+
+ @Override
+ public void setResponseContext(ResponseContext rc) {
+ this.responseContext = rc;
+ }
+
+ private String getStringId() {
+ return RuntimeVersion.VERSION + ": Stub for " + getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+ }
+
+ @Override
+ public String toString() {
+ return getStringId();
+ }
+
+ @Override
+ public final WSEndpointReference getWSEndpointReference() {
+ if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) {
+ throw new java.lang.UnsupportedOperationException(
+ ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference(Class class)", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding")
+ );
+ }
+
+ if (endpointReference != null) {
+ return endpointReference;
+ }
+
+ String eprAddress = requestContext.getEndpointAddress().toString();
+ QName portTypeName = null;
+ String wsdlAddress = null;
+ List wsdlEPRExtensions = new ArrayList();
+ if (wsdlPort != null) {
+ portTypeName = wsdlPort.getBinding().getPortTypeName();
+ wsdlAddress = eprAddress + "?wsdl";
+
+ //gather EPRExtensions specified in WSDL.
+ try {
+ WSEndpointReference wsdlEpr = wsdlPort.getEPR();
+ if (wsdlEpr != null) {
+ for (WSEndpointReference.EPRExtension extnEl : wsdlEpr.getEPRExtensions()) {
+ wsdlEPRExtensions.add(new WSEPRExtension(
+ XMLStreamBuffer.createNewBufferFromXMLStreamReader(extnEl.readAsXMLStreamReader()), extnEl.getQName()));
+ }
+ }
+
+ } catch (XMLStreamException ex) {
+ throw new WebServiceException(ex);
+ }
+ }
+ AddressingVersion av = AddressingVersion.W3C;
+ this.endpointReference = new WSEndpointReference(
+ av, eprAddress, getServiceName(), getPortName(), portTypeName, null, wsdlAddress, null, wsdlEPRExtensions, null);
+
+ return this.endpointReference;
+ }
+
+
+ @Override
+ public final W3CEndpointReference getEndpointReference() {
+ if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) {
+ throw new java.lang.UnsupportedOperationException(
+ ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference()", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding"));
+ }
+ return getEndpointReference(W3CEndpointReference.class);
+ }
+
+ @Override
+ public final T getEndpointReference(Class clazz) {
+ return getWSEndpointReference().toSpec(clazz);
+ }
+
+ public
+ @NotNull
+ @Override
+ ManagedObjectManager getManagedObjectManager() {
+ return managedObjectManager;
+ }
+
+ //
+//
+// WSBindingProvider methods
+//
+//
+ @Override
+ public final void setOutboundHeaders(List headers) {
+ if (headers == null) {
+ this.userOutboundHeaders = null;
+ } else {
+ for (Header h : headers) {
+ if (h == null) {
+ throw new IllegalArgumentException();
+ }
+ }
+ userOutboundHeaders = headers.toArray(new Header[headers.size()]);
+ }
+ }
+
+ @Override
+ public final void setOutboundHeaders(Header... headers) {
+ if (headers == null) {
+ this.userOutboundHeaders = null;
+ } else {
+ for (Header h : headers) {
+ if (h == null) {
+ throw new IllegalArgumentException();
+ }
+ }
+ Header[] hl = new Header[headers.length];
+ System.arraycopy(headers, 0, hl, 0, headers.length);
+ userOutboundHeaders = hl;
+ }
+ }
+
+ @Override
+ public final List getInboundHeaders() {
+ return Collections.unmodifiableList(((MessageHeaders)
+ responseContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)).asList());
+ }
+
+ @Override
+ public final void setAddress(String address) {
+ requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
+ }
+
+ @Override
+ public S getSPI(Class spiType) {
+ for (Component c : components) {
+ S s = c.getSPI(spiType);
+ if (s != null) {
+ return s;
+ }
+ }
+ return owner.getSPI(spiType);
+ }
+
+ @Override
+ public Set getComponents() {
+ return components;
+ }
+}