/*
* 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 Tube
for processing. This class implements the management of pipe instances, and most of the BindingProvider
methods.
Author: Kohsuke Kawaguchi
/**
* Base class for stubs, which accept method invocations from
* client applications and pass the message to a {@link Tube}
* for processing.
*
* <p>
* 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.
/**
* 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 closed
.
/**
* Reuse pipelines as it's expensive to create.
* <p>
* Set to null when {@link #close() closed}.
*/
private Pool<Tube> tubes;
private final Engine engine;
The WSServiceDelegate
object that owns us. /**
* 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.
/**
* Non-null if this stub is configured to talk to an EPR.
* <p>
* 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.
* <p>
* 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;
/**
* represents AddressingVersion on binding if enabled, otherwise null;
*/
protected AddressingVersion addrVersion;
public RequestContext requestContext = new RequestContext();
private final RequestContext cleanRequestContext;
ResponseContext
from the last synchronous operation. /**
* {@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<Component> components = new CopyOnWriteArraySet<Component>();
Params: - master – The created stub will send messages to this pipe.
- binding – As a
BindingProvider
, this object will return this binding from BindingProvider.getBinding()
. - defaultEndPointAddress – The destination of the message. The actual destination could be overridden by
RequestContext
. - 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
.
/**
* @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 {@code 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);
}
Params: - portname – The name of this port
- master – The created stub will send messages to this pipe.
- binding – As a
BindingProvider
, this object will return this binding from BindingProvider.getBinding()
. - defaultEndPointAddress – The destination of the message. The actual destination could be overridden by
RequestContext
. - 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
.
/**
* @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 {@code 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);
}
Params: - portInfo – PortInfo for this stub
- binding – As a
BindingProvider
, this object will return this binding from BindingProvider.getBinding()
. - master – The created stub will send messages to this pipe.
- defaultEndPointAddress – The destination of the message. The actual destination could be overridden by
RequestContext
. - 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
.
/**
* @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 {@code 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);
}
Params: - portInfo – PortInfo for this stub
- binding – As a
BindingProvider
, this object will return this binding from BindingProvider.getBinding()
. - defaultEndPointAddress – The destination of the message. The actual destination could be overridden by
RequestContext
. - 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
.
/**
* @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 {@code 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.
/**
* 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<Tube> 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
/**
* 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
Returns:
/**
* 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 wsdlPort
is non-null, the port name is always the same as WSDLPort.getName()
, but this method returns a port name even if no WSDL is available for this stub.
/**
* Gets the port name that this stub is configured to talk to.
* <p>
* 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 wsdlPort
is non-null, the service name is always the same as the one that's inferred from WSDLPort.getOwner()
, but this method returns a port name even if no WSDL is available for this stub.
/**
* Gets the service name that this stub is configured to talk to.
* <p>
* 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 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.
Returns: always non-null.
/**
* Gets the {@link Executor} to be used for asynchronous method invocations.
* <p>
* 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 Tube
instances, this method is thread-safe and can be invoked from multiple threads concurrently.
Params: - packet – The message to be sent to the server
- requestContext – The
RequestContext
when this invocation is originally scheduled. This must be the same object as 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. - receiver – Receives the
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.
/**
* Passes a message to a pipe for processing.
* <p>
* 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<Tube> 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 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 Tube
instances, this method is thread-safe and can be invoked from multiple threads concurrently.
Params: - receiver – The
Response
implementation - request – The message to be sent to the server
- requestContext – The
RequestContext
when this invocation is originally scheduled. This must be the same object as 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. - completionCallback – Once the processing is done, the callback is invoked.
/**
* 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.
*
* <p>
* 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<Tube> 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<String, Object> 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<T> 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<WSEndpointReference.EPRExtension> wsdlEPRExtensions = new ArrayList<WSEndpointReference.EPRExtension>();
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 extends EndpointReference> T getEndpointReference(Class<T> clazz) {
return getWSEndpointReference().toSpec(clazz);
}
public
@NotNull
@Override
ManagedObjectManager getManagedObjectManager() {
return managedObjectManager;
}
//
//
// WSBindingProvider methods
//
//
@Override
public final void setOutboundHeaders(List<Header> 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<Header> 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> S getSPI(Class<S> spiType) {
for (Component c : components) {
S s = c.getSPI(spiType);
if (s != null) {
return s;
}
}
return owner.getSPI(spiType);
}
@Override
public Set<Component> getComponents() {
return components;
}
}