src/share/jaxws_classes/com/sun/xml/internal/ws/client/Stub.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 408
b0610cd08440
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.client;
    28 import com.sun.istack.internal.NotNull;
    29 import com.sun.istack.internal.Nullable;
    30 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
    31 import com.sun.xml.internal.ws.addressing.WSEPRExtension;
    32 import com.sun.xml.internal.ws.api.BindingID;
    33 import com.sun.xml.internal.ws.api.Component;
    34 import com.sun.xml.internal.ws.api.ComponentFeature;
    35 import com.sun.xml.internal.ws.api.ComponentFeature.Target;
    36 import com.sun.xml.internal.ws.api.ComponentRegistry;
    37 import com.sun.xml.internal.ws.api.ComponentsFeature;
    38 import com.sun.xml.internal.ws.api.EndpointAddress;
    39 import com.sun.xml.internal.ws.api.WSBinding;
    40 import com.sun.xml.internal.ws.api.WSService;
    41 import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
    42 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
    43 import com.sun.xml.internal.ws.api.client.WSPortInfo;
    44 import com.sun.xml.internal.ws.api.message.AddressingUtils;
    45 import com.sun.xml.internal.ws.api.message.Header;
    46 import com.sun.xml.internal.ws.api.message.HeaderList;
    47 import com.sun.xml.internal.ws.api.message.MessageHeaders;
    48 import com.sun.xml.internal.ws.api.message.Packet;
    49 import com.sun.xml.internal.ws.api.model.SEIModel;
    50 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
    51 import com.sun.xml.internal.ws.api.pipe.ClientTubeAssemblerContext;
    52 import com.sun.xml.internal.ws.api.pipe.Engine;
    53 import com.sun.xml.internal.ws.api.pipe.Fiber;
    54 import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptorFactory;
    55 import com.sun.xml.internal.ws.api.pipe.SyncStartForAsyncFeature;
    56 import com.sun.xml.internal.ws.api.pipe.Tube;
    57 import com.sun.xml.internal.ws.api.pipe.TubelineAssembler;
    58 import com.sun.xml.internal.ws.api.pipe.TubelineAssemblerFactory;
    59 import com.sun.xml.internal.ws.api.server.Container;
    60 import com.sun.xml.internal.ws.api.server.ContainerResolver;
    61 import com.sun.xml.internal.ws.binding.BindingImpl;
    62 import com.sun.xml.internal.ws.developer.JAXWSProperties;
    63 import com.sun.xml.internal.ws.developer.WSBindingProvider;
    64 import com.sun.xml.internal.ws.model.wsdl.WSDLDirectProperties;
    65 import com.sun.xml.internal.ws.model.wsdl.WSDLPortImpl;
    66 import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties;
    67 import com.sun.xml.internal.ws.model.wsdl.WSDLProperties;
    68 import com.sun.xml.internal.ws.resources.ClientMessages;
    69 import com.sun.xml.internal.ws.util.Pool;
    70 import com.sun.xml.internal.ws.util.Pool.TubePool;
    71 import com.sun.xml.internal.ws.util.RuntimeVersion;
    72 import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
    73 import com.sun.org.glassfish.gmbal.ManagedObjectManager;
    75 import javax.xml.namespace.QName;
    76 import javax.xml.stream.XMLStreamException;
    77 import javax.xml.ws.BindingProvider;
    78 import javax.xml.ws.EndpointReference;
    79 import javax.xml.ws.RespectBindingFeature;
    80 import javax.xml.ws.Response;
    81 import javax.xml.ws.WebServiceException;
    82 import javax.xml.ws.http.HTTPBinding;
    83 import javax.xml.ws.wsaddressing.W3CEndpointReference;
    84 import java.util.ArrayList;
    85 import java.util.Collections;
    86 import java.util.List;
    87 import java.util.Map;
    88 import java.util.Set;
    89 import java.util.concurrent.CopyOnWriteArraySet;
    90 import java.util.concurrent.Executor;
    91 import java.util.logging.Level;
    92 import java.util.logging.Logger;
    93 import javax.management.ObjectName;
    95 /**
    96  * Base class for stubs, which accept method invocations from
    97  * client applications and pass the message to a {@link Tube}
    98  * for processing.
    99  *
   100  * <p>
   101  * This class implements the management of pipe instances,
   102  * and most of the {@link BindingProvider} methods.
   103  *
   104  * @author Kohsuke Kawaguchi
   105  */
   106 public abstract class Stub implements WSBindingProvider, ResponseContextReceiver, ComponentRegistry  {
   107     /**
   108      * Internal flag indicating async dispatch should be used even when the
   109      * SyncStartForAsyncInvokeFeature is present on the binding associated
   110      * with a stub. There is no type associated with this property on the
   111      * request context. Its presence is what triggers the 'prevent' behavior.
   112      */
   113     public static final String PREVENT_SYNC_START_FOR_ASYNC_INVOKE = "com.sun.xml.internal.ws.client.StubRequestSyncStartForAsyncInvoke";
   115     /**
   116      * Reuse pipelines as it's expensive to create.
   117      * <p>
   118      * Set to null when {@link #close() closed}.
   119      */
   120     private Pool<Tube> tubes;
   122     private final Engine engine;
   124     /**
   125      * The {@link WSServiceDelegate} object that owns us.
   126      */
   127     protected final WSServiceDelegate owner;
   129     /**
   130      * Non-null if this stub is configured to talk to an EPR.
   131      * <p>
   132      * When this field is non-null, its reference parameters are sent as out-bound headers.
   133      * This field can be null even when addressing is enabled, but if the addressing is
   134      * not enabled, this field must be null.
   135      * <p>
   136      * Unlike endpoint address, we are not letting users to change the EPR,
   137      * as it contains references to services and so on that we don't want to change.
   138      */
   139     protected
   140     @Nullable
   141     WSEndpointReference endpointReference;
   143     protected final BindingImpl binding;
   145     protected final WSPortInfo portInfo;
   147     /**
   148      * represents AddressingVersion on binding if enabled, otherwise null;
   149      */
   150     protected AddressingVersion addrVersion;
   152     public RequestContext requestContext = new RequestContext();
   154     private final RequestContext cleanRequestContext;
   156     /**
   157      * {@link ResponseContext} from the last synchronous operation.
   158      */
   159     private ResponseContext responseContext;
   160     @Nullable
   161     protected final WSDLPort wsdlPort;
   163     protected QName portname;
   165     /**
   166      * {@link Header}s to be added to outbound {@link Packet}.
   167      * The contents is determined by the user.
   168      */
   169     @Nullable
   170     private volatile Header[] userOutboundHeaders;
   172     private final
   173     @NotNull
   174     WSDLProperties wsdlProperties;
   175     protected OperationDispatcher operationDispatcher = null;
   176     private final
   177     @NotNull
   178     ManagedObjectManager managedObjectManager;
   179     private boolean managedObjectManagerClosed = false;
   181     private final Set<Component> components = new CopyOnWriteArraySet<Component>();
   183     /**
   184      * @param master                 The created stub will send messages to this pipe.
   185      * @param binding                As a {@link BindingProvider}, this object will
   186      *                               return this binding from {@link BindingProvider#getBinding()}.
   187      * @param defaultEndPointAddress The destination of the message. The actual destination
   188      *                               could be overridden by {@link RequestContext}.
   189      * @param epr                    To create a stub that sends out reference parameters
   190      *                               of a specific EPR, give that instance. Otherwise null.
   191      *                               Its address field will not be used, and that should be given
   192      *                               separately as the <tt>defaultEndPointAddress</tt>.
   193      */
   194     @Deprecated
   195     protected Stub(WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   196         this(owner, master, null, null, binding, wsdlPort, defaultEndPointAddress, epr);
   197     }
   199     /**
   200      * @param portname               The name of this port
   201      * @param master                 The created stub will send messages to this pipe.
   202      * @param binding                As a {@link BindingProvider}, this object will
   203      *                               return this binding from {@link BindingProvider#getBinding()}.
   204      * @param defaultEndPointAddress The destination of the message. The actual destination
   205      *                               could be overridden by {@link RequestContext}.
   206      * @param epr                    To create a stub that sends out reference parameters
   207      *                               of a specific EPR, give that instance. Otherwise null.
   208      *                               Its address field will not be used, and that should be given
   209      *                               separately as the <tt>defaultEndPointAddress</tt>.
   210      */
   211     @Deprecated
   212     protected Stub(QName portname, WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   213         this(owner, master, null, portname, binding, wsdlPort, defaultEndPointAddress, epr);
   214     }
   216     /**
   217      * @param portInfo               PortInfo  for this stub
   218      * @param binding                As a {@link BindingProvider}, this object will
   219      *                               return this binding from {@link BindingProvider#getBinding()}.
   220      * @param master                 The created stub will send messages to this pipe.
   221      * @param defaultEndPointAddress The destination of the message. The actual destination
   222      *                               could be overridden by {@link RequestContext}.
   223      * @param epr                    To create a stub that sends out reference parameters
   224      *                               of a specific EPR, give that instance. Otherwise null.
   225      *                               Its address field will not be used, and that should be given
   226      *                               separately as the <tt>defaultEndPointAddress</tt>.
   227      */
   228     protected Stub(WSPortInfo portInfo, BindingImpl binding, Tube master,EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   229          this((WSServiceDelegate) portInfo.getOwner(), master, portInfo, null, binding,portInfo.getPort(), defaultEndPointAddress, epr);
   230     }
   232   /**
   233    * @param portInfo               PortInfo  for this stub
   234    * @param binding                As a {@link BindingProvider}, this object will
   235    *                               return this binding from {@link BindingProvider#getBinding()}.
   236    * @param defaultEndPointAddress The destination of the message. The actual destination
   237    *                               could be overridden by {@link RequestContext}.
   238    * @param epr                    To create a stub that sends out reference parameters
   239    *                               of a specific EPR, give that instance. Otherwise null.
   240    *                               Its address field will not be used, and that should be given
   241    *                               separately as the <tt>defaultEndPointAddress</tt>.
   242    */
   243   protected Stub(WSPortInfo portInfo, BindingImpl binding, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   244        this(portInfo,binding,null, defaultEndPointAddress,epr);
   246   }
   248     private Stub(WSServiceDelegate owner, @Nullable Tube master, @Nullable WSPortInfo portInfo, QName portname, BindingImpl binding, @Nullable WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   249         Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer());
   250         try {
   251             this.owner = owner;
   252             this.portInfo = portInfo;
   253             this.wsdlPort = wsdlPort != null ? wsdlPort : (portInfo != null ? portInfo.getPort() : null);
   254             this.portname = portname;
   255             if (portname == null) {
   256                 if (portInfo != null) {
   257                     this.portname = portInfo.getPortName();
   258                 } else if (wsdlPort != null) {
   259                     this.portname = wsdlPort.getName();
   260                 }
   261             }
   262             this.binding = binding;
   264             ComponentFeature cf = binding.getFeature(ComponentFeature.class);
   265             if (cf != null && Target.STUB.equals(cf.getTarget())) {
   266                 components.add(cf.getComponent());
   267             }
   268             ComponentsFeature csf = binding.getFeature(ComponentsFeature.class);
   269             if (csf != null) {
   270                 for (ComponentFeature cfi : csf.getComponentFeatures()) {
   271                     if (Target.STUB.equals(cfi.getTarget()))
   272                         components.add(cfi.getComponent());
   273                 }
   274             }
   276             // if there is an EPR, EPR's address should be used for invocation instead of default address
   277             if (epr != null) {
   278                 this.requestContext.setEndPointAddressString(epr.getAddress());
   279             } else {
   280                 this.requestContext.setEndpointAddress(defaultEndPointAddress);
   281             }
   282             this.engine = new Engine(getStringId(), owner.getContainer(), owner.getExecutor());
   283             this.endpointReference = epr;
   284             wsdlProperties = (wsdlPort == null) ? new WSDLDirectProperties(owner.getServiceName(), portname) : new WSDLPortProperties(wsdlPort);
   286             this.cleanRequestContext = this.requestContext.copy();
   288             // ManagedObjectManager MUST be created before the pipeline
   289             // is constructed.
   291             managedObjectManager = new MonitorRootClient(this).createManagedObjectManager(this);
   293             if (master != null) {
   294                 this.tubes = new TubePool(master);
   295             } else {
   296                 this.tubes = new TubePool(createPipeline(portInfo, binding));
   297             }
   299             addrVersion = binding.getAddressingVersion();
   301             // This needs to happen after createPipeline.
   302             // TBD: Check if it needs to happen outside the Stub constructor.
   303             managedObjectManager.resumeJMXRegistration();
   304         } finally {
   305             ContainerResolver.getDefault().exitContainer(old);
   306         }
   307     }
   309     /**
   310      * Creates a new pipeline for the given port name.
   311      */
   312     private Tube createPipeline(WSPortInfo portInfo, WSBinding binding) {
   313         //Check all required WSDL extensions are understood
   314         checkAllWSDLExtensionsUnderstood(portInfo, binding);
   315         SEIModel seiModel = null;
   316         Class sei = null;
   317         if (portInfo instanceof SEIPortInfo) {
   318                 SEIPortInfo sp = (SEIPortInfo) portInfo;
   319             seiModel = sp.model;
   320             sei = sp.sei;
   321         }
   322         BindingID bindingId = portInfo.getBindingId();
   324         TubelineAssembler assembler = TubelineAssemblerFactory.create(
   325                 Thread.currentThread().getContextClassLoader(), bindingId, owner.getContainer());
   326         if (assembler == null) {
   327             throw new WebServiceException("Unable to process bindingID=" + bindingId); // TODO: i18n
   328         }
   329         return assembler.createClient(
   330                 new ClientTubeAssemblerContext(
   331                         portInfo.getEndpointAddress(),
   332                         portInfo.getPort(),
   333                         this, binding, owner.getContainer(), ((BindingImpl) binding).createCodec(), seiModel, sei));
   334     }
   336     public WSDLPort getWSDLPort() {
   337         return wsdlPort;
   338     }
   340     public WSService getService() {
   341         return owner;
   342     }
   344     public Pool<Tube> getTubes() {
   345         return tubes;
   346     }
   348     /**
   349      * Checks only if RespectBindingFeature is enabled
   350      * checks if all required wsdl extensions in the
   351      * corresponding wsdl:Port are understood when RespectBindingFeature is enabled.
   352      * @throws WebServiceException
   353      *      when any wsdl extension that has wsdl:required=true is not understood
   354      */
   355     private static void checkAllWSDLExtensionsUnderstood(WSPortInfo port, WSBinding binding) {
   356         if (port.getPort() != null && binding.isFeatureEnabled(RespectBindingFeature.class)) {
   357             ((WSDLPortImpl) port.getPort()).areRequiredExtensionsUnderstood();
   358         }
   359     }
   361     @Override
   362     public WSPortInfo getPortInfo() {
   363         return portInfo;
   364     }
   366     /**
   367      * Nullable when there is no associated WSDL Model
   368      * @return
   369      */
   370     public
   371     @Nullable
   372     OperationDispatcher getOperationDispatcher() {
   373         if (operationDispatcher == null && wsdlPort != null) {
   374             operationDispatcher = new OperationDispatcher(wsdlPort, binding, null);
   375         }
   376         return operationDispatcher;
   377     }
   379     /**
   380      * Gets the port name that this stub is configured to talk to.
   381      * <p>
   382      * When {@link #wsdlPort} is non-null, the port name is always
   383      * the same as {@link WSDLPort#getName()}, but this method
   384      * returns a port name even if no WSDL is available for this stub.
   385      */
   386     protected abstract
   387     @NotNull
   388     QName getPortName();
   390     /**
   391      * Gets the service name that this stub is configured to talk to.
   392      * <p>
   393      * When {@link #wsdlPort} is non-null, the service name is always
   394      * the same as the one that's inferred from {@link WSDLPort#getOwner()},
   395      * but this method returns a port name even if no WSDL is available for
   396      * this stub.
   397      */
   398     protected final
   399     @NotNull
   400     QName getServiceName() {
   401         return owner.getServiceName();
   402     }
   404     /**
   405      * Gets the {@link Executor} to be used for asynchronous method invocations.
   406      * <p>
   407      * Note that the value this method returns may different from invocations
   408      * to invocations. The caller must not cache.
   409      *
   410      * @return always non-null.
   411      */
   412     public final Executor getExecutor() {
   413         return owner.getExecutor();
   414     }
   416     /**
   417      * Passes a message to a pipe for processing.
   418      * <p>
   419      * Unlike {@link Tube} instances,
   420      * this method is thread-safe and can be invoked from
   421      * multiple threads concurrently.
   422      *
   423      * @param packet         The message to be sent to the server
   424      * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
   425      *                       This must be the same object as {@link #requestContext} for synchronous
   426      *                       invocations, but for asynchronous invocations, it needs to be a snapshot
   427      *                       captured at the point of invocation, to correctly satisfy the spec requirement.
   428      * @param receiver       Receives the {@link ResponseContext}. Since the spec requires
   429      *                       that the asynchronous invocations must not update response context,
   430      *                       depending on the mode of invocation they have to go to different places.
   431      *                       So we take a setter that abstracts that away.
   432      */
   433     protected final Packet process(Packet packet, RequestContext requestContext, ResponseContextReceiver receiver) {
   434         packet.isSynchronousMEP = true;
   435         packet.component = this;
   436         configureRequestPacket(packet, requestContext);
   437         Pool<Tube> pool = tubes;
   438         if (pool == null) {
   439             throw new WebServiceException("close method has already been invoked"); // TODO: i18n
   440         }
   442         Fiber fiber = engine.createFiber();
   443         configureFiber(fiber);
   445         // then send it away!
   446         Tube tube = pool.take();
   448         try {
   449             return fiber.runSync(tube, packet);
   450         } finally {
   451             // this allows us to capture the packet even when the call failed with an exception.
   452             // when the call fails with an exception it's no longer a 'reply' but it may provide some information
   453             // about what went wrong.
   455             // note that Packet can still be updated after
   456             // ResponseContext is created.
   457             Packet reply = (fiber.getPacket() == null) ? packet : fiber.getPacket();
   458             receiver.setResponseContext(new ResponseContext(reply));
   460             pool.recycle(tube);
   461         }
   462     }
   464     private void configureRequestPacket(Packet packet, RequestContext requestContext) {
   465         // fill in Packet
   466         packet.proxy = this;
   467         packet.handlerConfig = binding.getHandlerConfig();
   469         // to make it multi-thread safe we need to first get a stable snapshot
   470         Header[] hl = userOutboundHeaders;
   471         if (hl != null) {
   472             MessageHeaders mh = packet.getMessage().getHeaders();
   473             for (Header h : hl) {
   474                 mh.add(h);
   475             }
   476         }
   478         requestContext.fill(packet, (binding.getAddressingVersion() != null));
   479         packet.addSatellite(wsdlProperties);
   481         if (addrVersion != null) {
   482             // populate request WS-Addressing headers
   483             MessageHeaders headerList = packet.getMessage().getHeaders();
   484             AddressingUtils.fillRequestAddressingHeaders(headerList, wsdlPort, binding, packet);
   487             // Spec is not clear on if ReferenceParameters are to be added when addressing is not enabled,
   488             // but the EPR has ReferenceParameters.
   489             // Current approach: Add ReferenceParameters only if addressing enabled.
   490             if (endpointReference != null) {
   491                 endpointReference.addReferenceParametersToList(packet.getMessage().getHeaders());
   492             }
   493         }
   494     }
   496     /**
   497      * Passes a message through a {@link Tube}line for processing. The processing happens
   498      * asynchronously and when the response is available, Fiber.CompletionCallback is
   499      * called. The processing could happen on multiple threads.
   500      *
   501      * <p>
   502      * Unlike {@link Tube} instances,
   503      * this method is thread-safe and can be invoked from
   504      * multiple threads concurrently.
   505      *
   506      * @param receiver       The {@link Response} implementation
   507      * @param request         The message to be sent to the server
   508      * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
   509      *                       This must be the same object as {@link #requestContext} for synchronous
   510      *                       invocations, but for asynchronous invocations, it needs to be a snapshot
   511      *                       captured at the point of invocation, to correctly satisfy the spec requirement.
   512      * @param completionCallback Once the processing is done, the callback is invoked.
   513      */
   514     protected final void processAsync(AsyncResponseImpl<?> receiver, Packet request, RequestContext requestContext, final Fiber.CompletionCallback completionCallback) {
   515         // fill in Packet
   516         request.component = this;
   517         configureRequestPacket(request, requestContext);
   519         final Pool<Tube> pool = tubes;
   520         if (pool == null) {
   521             throw new WebServiceException("close method has already been invoked"); // TODO: i18n
   522         }
   524         final Fiber fiber = engine.createFiber();
   525         configureFiber(fiber);
   527         receiver.setCancelable(fiber);
   529         // check race condition on cancel
   530         if (receiver.isCancelled()) {
   531             return;
   532         }
   534         FiberContextSwitchInterceptorFactory fcsif = owner.getSPI(FiberContextSwitchInterceptorFactory.class);
   535         if (fcsif != null) {
   536             fiber.addInterceptor(fcsif.create());
   537         }
   539         // then send it away!
   540         final Tube tube = pool.take();
   542         Fiber.CompletionCallback fiberCallback = new Fiber.CompletionCallback() {
   543             @Override
   544             public void onCompletion(@NotNull Packet response) {
   545                 pool.recycle(tube);
   546                 completionCallback.onCompletion(response);
   547             }
   549             @Override
   550             public void onCompletion(@NotNull Throwable error) {
   551                 // let's not reuse tubes as they might be in a wrong state, so not
   552                 // calling pool.recycle()
   553                 completionCallback.onCompletion(error);
   554             }
   555         };
   557         // Check for SyncStartForAsyncInvokeFeature
   559         fiber.start(tube, request, fiberCallback,
   560                         getBinding().isFeatureEnabled(SyncStartForAsyncFeature.class) &&
   561                         !requestContext.containsKey(PREVENT_SYNC_START_FOR_ASYNC_INVOKE));
   562     }
   564     protected void configureFiber(Fiber fiber) {
   565         // no-op in the base class, but can be used by derived classes to configure the Fiber prior
   566         // to invocation
   567     }
   569     private static final Logger monitoringLogger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
   571     @Override
   572     public void close() {
   573         TubePool tp = (TubePool) tubes;
   574         if (tp != null) {
   575             // multi-thread safety of 'close' needs to be considered more carefully.
   576             // some calls might be pending while this method is invoked. Should we
   577             // block until they are complete, or should we abort them (but how?)
   578             Tube p = tp.takeMaster();
   579             p.preDestroy();
   580             tubes = null;
   581         }
   582         if (!managedObjectManagerClosed) {
   583             try {
   584                 final ObjectName name = managedObjectManager.getObjectName(managedObjectManager.getRoot());
   585                 // The name is null when the MOM is a NOOP.
   586                 if (name != null) {
   587                     monitoringLogger.log(Level.INFO, "Closing Metro monitoring root: {0}", name);
   588                 }
   589                 managedObjectManager.close();
   590             } catch (java.io.IOException e) {
   591                 monitoringLogger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e);
   592             }
   593             managedObjectManagerClosed = true;
   594         }
   595     }
   597     @Override
   598     public final WSBinding getBinding() {
   599         return binding;
   600     }
   602     @Override
   603     public final Map<String, Object> getRequestContext() {
   604         return requestContext.asMap();
   605     }
   607     public void resetRequestContext() {
   608         requestContext = cleanRequestContext.copy();
   609     }
   611     @Override
   612     public final ResponseContext getResponseContext() {
   613         return responseContext;
   614     }
   616     @Override
   617     public void setResponseContext(ResponseContext rc) {
   618         this.responseContext = rc;
   619     }
   621     private String getStringId() {
   622         return RuntimeVersion.VERSION + ": Stub for " + getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
   623     }
   625     @Override
   626     public String toString() {
   627         return getStringId();
   628     }
   630     @Override
   631     public final WSEndpointReference getWSEndpointReference() {
   632         if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) {
   633             throw new java.lang.UnsupportedOperationException(
   634                         ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference(Class<T> class)", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding")
   635                     );
   636         }
   638         if (endpointReference != null) {
   639             return endpointReference;
   640         }
   642         String eprAddress = requestContext.getEndpointAddress().toString();
   643         QName portTypeName = null;
   644         String wsdlAddress = null;
   645         List<WSEndpointReference.EPRExtension> wsdlEPRExtensions = new ArrayList<WSEndpointReference.EPRExtension>();
   646         if (wsdlPort != null) {
   647             portTypeName = wsdlPort.getBinding().getPortTypeName();
   648             wsdlAddress = eprAddress + "?wsdl";
   650             //gather EPRExtensions specified in WSDL.
   651             try {
   652                 WSEndpointReference wsdlEpr = ((WSDLPortImpl) wsdlPort).getEPR();
   653                 if (wsdlEpr != null) {
   654                     for (WSEndpointReference.EPRExtension extnEl : wsdlEpr.getEPRExtensions()) {
   655                         wsdlEPRExtensions.add(new WSEPRExtension(
   656                                 XMLStreamBuffer.createNewBufferFromXMLStreamReader(extnEl.readAsXMLStreamReader()), extnEl.getQName()));
   657                     }
   658                 }
   660             } catch (XMLStreamException ex) {
   661                 throw new WebServiceException(ex);
   662             }
   663         }
   664         AddressingVersion av = AddressingVersion.W3C;
   665         this.endpointReference = new WSEndpointReference(
   666                 av, eprAddress, getServiceName(), getPortName(), portTypeName, null, wsdlAddress, null, wsdlEPRExtensions, null);
   668         return this.endpointReference;
   669     }
   672     @Override
   673     public final W3CEndpointReference getEndpointReference() {
   674         if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) {
   675             throw new java.lang.UnsupportedOperationException(
   676                         ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference()", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding"));
   677         }
   678         return getEndpointReference(W3CEndpointReference.class);
   679     }
   681     @Override
   682     public final <T extends EndpointReference> T getEndpointReference(Class<T> clazz) {
   683         return getWSEndpointReference().toSpec(clazz);
   684     }
   686     public
   687     @NotNull
   688     @Override
   689     ManagedObjectManager getManagedObjectManager() {
   690         return managedObjectManager;
   691     }
   693     //
   694 //
   695 // WSBindingProvider methods
   696 //
   697 //
   698     @Override
   699     public final void setOutboundHeaders(List<Header> headers) {
   700         if (headers == null) {
   701             this.userOutboundHeaders = null;
   702         } else {
   703             for (Header h : headers) {
   704                 if (h == null) {
   705                     throw new IllegalArgumentException();
   706                 }
   707             }
   708             userOutboundHeaders = headers.toArray(new Header[headers.size()]);
   709         }
   710     }
   712     @Override
   713     public final void setOutboundHeaders(Header... headers) {
   714         if (headers == null) {
   715             this.userOutboundHeaders = null;
   716         } else {
   717             for (Header h : headers) {
   718                 if (h == null) {
   719                     throw new IllegalArgumentException();
   720                 }
   721             }
   722             Header[] hl = new Header[headers.length];
   723             System.arraycopy(headers, 0, hl, 0, headers.length);
   724             userOutboundHeaders = hl;
   725         }
   726     }
   728     @Override
   729     public final List<Header> getInboundHeaders() {
   730         return Collections.unmodifiableList(((MessageHeaders)
   731                 responseContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)).asList());
   732     }
   734     @Override
   735     public final void setAddress(String address) {
   736         requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
   737     }
   739     @Override
   740     public <S> S getSPI(Class<S> spiType) {
   741         for (Component c : components) {
   742             S s = c.getSPI(spiType);
   743             if (s != null) {
   744                 return s;
   745             }
   746         }
   747         return owner.getSPI(spiType);
   748     }
   750     @Override
   751     public Set<Component> getComponents() {
   752         return components;
   753     }
   754 }

mercurial