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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     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.WSDLPortProperties;
    66 import com.sun.xml.internal.ws.model.wsdl.WSDLProperties;
    67 import com.sun.xml.internal.ws.resources.ClientMessages;
    68 import com.sun.xml.internal.ws.util.Pool;
    69 import com.sun.xml.internal.ws.util.Pool.TubePool;
    70 import com.sun.xml.internal.ws.util.RuntimeVersion;
    71 import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
    72 import com.sun.org.glassfish.gmbal.ManagedObjectManager;
    74 import javax.xml.namespace.QName;
    75 import javax.xml.stream.XMLStreamException;
    76 import javax.xml.ws.BindingProvider;
    77 import javax.xml.ws.EndpointReference;
    78 import javax.xml.ws.RespectBindingFeature;
    79 import javax.xml.ws.Response;
    80 import javax.xml.ws.WebServiceException;
    81 import javax.xml.ws.http.HTTPBinding;
    82 import javax.xml.ws.wsaddressing.W3CEndpointReference;
    83 import java.util.ArrayList;
    84 import java.util.Collections;
    85 import java.util.List;
    86 import java.util.Map;
    87 import java.util.Set;
    88 import java.util.concurrent.CopyOnWriteArraySet;
    89 import java.util.concurrent.Executor;
    90 import java.util.logging.Level;
    91 import java.util.logging.Logger;
    92 import javax.management.ObjectName;
    94 /**
    95  * Base class for stubs, which accept method invocations from
    96  * client applications and pass the message to a {@link Tube}
    97  * for processing.
    98  *
    99  * <p>
   100  * This class implements the management of pipe instances,
   101  * and most of the {@link BindingProvider} methods.
   102  *
   103  * @author Kohsuke Kawaguchi
   104  */
   105 public abstract class Stub implements WSBindingProvider, ResponseContextReceiver, ComponentRegistry  {
   106     /**
   107      * Internal flag indicating async dispatch should be used even when the
   108      * SyncStartForAsyncInvokeFeature is present on the binding associated
   109      * with a stub. There is no type associated with this property on the
   110      * request context. Its presence is what triggers the 'prevent' behavior.
   111      */
   112     public static final String PREVENT_SYNC_START_FOR_ASYNC_INVOKE = "com.sun.xml.internal.ws.client.StubRequestSyncStartForAsyncInvoke";
   114     /**
   115      * Reuse pipelines as it's expensive to create.
   116      * <p>
   117      * Set to null when {@link #close() closed}.
   118      */
   119     private Pool<Tube> tubes;
   121     private final Engine engine;
   123     /**
   124      * The {@link WSServiceDelegate} object that owns us.
   125      */
   126     protected final WSServiceDelegate owner;
   128     /**
   129      * Non-null if this stub is configured to talk to an EPR.
   130      * <p>
   131      * When this field is non-null, its reference parameters are sent as out-bound headers.
   132      * This field can be null even when addressing is enabled, but if the addressing is
   133      * not enabled, this field must be null.
   134      * <p>
   135      * Unlike endpoint address, we are not letting users to change the EPR,
   136      * as it contains references to services and so on that we don't want to change.
   137      */
   138     protected
   139     @Nullable
   140     WSEndpointReference endpointReference;
   142     protected final BindingImpl binding;
   144     protected final WSPortInfo portInfo;
   146     /**
   147      * represents AddressingVersion on binding if enabled, otherwise null;
   148      */
   149     protected AddressingVersion addrVersion;
   151     public RequestContext requestContext = new RequestContext();
   153     private final RequestContext cleanRequestContext;
   155     /**
   156      * {@link ResponseContext} from the last synchronous operation.
   157      */
   158     private ResponseContext responseContext;
   159     @Nullable
   160     protected final WSDLPort wsdlPort;
   162     protected QName portname;
   164     /**
   165      * {@link Header}s to be added to outbound {@link Packet}.
   166      * The contents is determined by the user.
   167      */
   168     @Nullable
   169     private volatile Header[] userOutboundHeaders;
   171     private final
   172     @NotNull
   173     WSDLProperties wsdlProperties;
   174     protected OperationDispatcher operationDispatcher = null;
   175     private final
   176     @NotNull
   177     ManagedObjectManager managedObjectManager;
   178     private boolean managedObjectManagerClosed = false;
   180     private final Set<Component> components = new CopyOnWriteArraySet<Component>();
   182     /**
   183      * @param master                 The created stub will send messages to this pipe.
   184      * @param binding                As a {@link BindingProvider}, this object will
   185      *                               return this binding from {@link BindingProvider#getBinding()}.
   186      * @param defaultEndPointAddress The destination of the message. The actual destination
   187      *                               could be overridden by {@link RequestContext}.
   188      * @param epr                    To create a stub that sends out reference parameters
   189      *                               of a specific EPR, give that instance. Otherwise null.
   190      *                               Its address field will not be used, and that should be given
   191      *                               separately as the <tt>defaultEndPointAddress</tt>.
   192      */
   193     @Deprecated
   194     protected Stub(WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   195         this(owner, master, null, null, binding, wsdlPort, defaultEndPointAddress, epr);
   196     }
   198     /**
   199      * @param portname               The name of this port
   200      * @param master                 The created stub will send messages to this pipe.
   201      * @param binding                As a {@link BindingProvider}, this object will
   202      *                               return this binding from {@link BindingProvider#getBinding()}.
   203      * @param defaultEndPointAddress The destination of the message. The actual destination
   204      *                               could be overridden by {@link RequestContext}.
   205      * @param epr                    To create a stub that sends out reference parameters
   206      *                               of a specific EPR, give that instance. Otherwise null.
   207      *                               Its address field will not be used, and that should be given
   208      *                               separately as the <tt>defaultEndPointAddress</tt>.
   209      */
   210     @Deprecated
   211     protected Stub(QName portname, WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   212         this(owner, master, null, portname, binding, wsdlPort, defaultEndPointAddress, epr);
   213     }
   215     /**
   216      * @param portInfo               PortInfo  for this stub
   217      * @param binding                As a {@link BindingProvider}, this object will
   218      *                               return this binding from {@link BindingProvider#getBinding()}.
   219      * @param master                 The created stub will send messages to this pipe.
   220      * @param defaultEndPointAddress The destination of the message. The actual destination
   221      *                               could be overridden by {@link RequestContext}.
   222      * @param epr                    To create a stub that sends out reference parameters
   223      *                               of a specific EPR, give that instance. Otherwise null.
   224      *                               Its address field will not be used, and that should be given
   225      *                               separately as the <tt>defaultEndPointAddress</tt>.
   226      */
   227     protected Stub(WSPortInfo portInfo, BindingImpl binding, Tube master,EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   228          this((WSServiceDelegate) portInfo.getOwner(), master, portInfo, null, binding,portInfo.getPort(), defaultEndPointAddress, epr);
   229     }
   231   /**
   232    * @param portInfo               PortInfo  for this stub
   233    * @param binding                As a {@link BindingProvider}, this object will
   234    *                               return this binding from {@link BindingProvider#getBinding()}.
   235    * @param defaultEndPointAddress The destination of the message. The actual destination
   236    *                               could be overridden by {@link RequestContext}.
   237    * @param epr                    To create a stub that sends out reference parameters
   238    *                               of a specific EPR, give that instance. Otherwise null.
   239    *                               Its address field will not be used, and that should be given
   240    *                               separately as the <tt>defaultEndPointAddress</tt>.
   241    */
   242   protected Stub(WSPortInfo portInfo, BindingImpl binding, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   243        this(portInfo,binding,null, defaultEndPointAddress,epr);
   245   }
   247     private Stub(WSServiceDelegate owner, @Nullable Tube master, @Nullable WSPortInfo portInfo, QName portname, BindingImpl binding, @Nullable WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   248         Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer());
   249         try {
   250             this.owner = owner;
   251             this.portInfo = portInfo;
   252             this.wsdlPort = wsdlPort != null ? wsdlPort : (portInfo != null ? portInfo.getPort() : null);
   253             this.portname = portname;
   254             if (portname == null) {
   255                 if (portInfo != null) {
   256                     this.portname = portInfo.getPortName();
   257                 } else if (wsdlPort != null) {
   258                     this.portname = wsdlPort.getName();
   259                 }
   260             }
   261             this.binding = binding;
   263             ComponentFeature cf = binding.getFeature(ComponentFeature.class);
   264             if (cf != null && Target.STUB.equals(cf.getTarget())) {
   265                 components.add(cf.getComponent());
   266             }
   267             ComponentsFeature csf = binding.getFeature(ComponentsFeature.class);
   268             if (csf != null) {
   269                 for (ComponentFeature cfi : csf.getComponentFeatures()) {
   270                     if (Target.STUB.equals(cfi.getTarget()))
   271                         components.add(cfi.getComponent());
   272                 }
   273             }
   275             // if there is an EPR, EPR's address should be used for invocation instead of default address
   276             if (epr != null) {
   277                 this.requestContext.setEndPointAddressString(epr.getAddress());
   278             } else {
   279                 this.requestContext.setEndpointAddress(defaultEndPointAddress);
   280             }
   281             this.engine = new Engine(getStringId(), owner.getContainer(), owner.getExecutor());
   282             this.endpointReference = epr;
   283             wsdlProperties = (wsdlPort == null) ? new WSDLDirectProperties(owner.getServiceName(), portname) : new WSDLPortProperties(wsdlPort);
   285             this.cleanRequestContext = this.requestContext.copy();
   287             // ManagedObjectManager MUST be created before the pipeline
   288             // is constructed.
   290             managedObjectManager = new MonitorRootClient(this).createManagedObjectManager(this);
   292             if (master != null) {
   293                 this.tubes = new TubePool(master);
   294             } else {
   295                 this.tubes = new TubePool(createPipeline(portInfo, binding));
   296             }
   298             addrVersion = binding.getAddressingVersion();
   300             // This needs to happen after createPipeline.
   301             // TBD: Check if it needs to happen outside the Stub constructor.
   302             managedObjectManager.resumeJMXRegistration();
   303         } finally {
   304             ContainerResolver.getDefault().exitContainer(old);
   305         }
   306     }
   308     /**
   309      * Creates a new pipeline for the given port name.
   310      */
   311     private Tube createPipeline(WSPortInfo portInfo, WSBinding binding) {
   312         //Check all required WSDL extensions are understood
   313         checkAllWSDLExtensionsUnderstood(portInfo, binding);
   314         SEIModel seiModel = null;
   315         Class sei = null;
   316         if (portInfo instanceof SEIPortInfo) {
   317                 SEIPortInfo sp = (SEIPortInfo) portInfo;
   318             seiModel = sp.model;
   319             sei = sp.sei;
   320         }
   321         BindingID bindingId = portInfo.getBindingId();
   323         TubelineAssembler assembler = TubelineAssemblerFactory.create(
   324                 Thread.currentThread().getContextClassLoader(), bindingId, owner.getContainer());
   325         if (assembler == null) {
   326             throw new WebServiceException("Unable to process bindingID=" + bindingId); // TODO: i18n
   327         }
   328         return assembler.createClient(
   329                 new ClientTubeAssemblerContext(
   330                         portInfo.getEndpointAddress(),
   331                         portInfo.getPort(),
   332                         this, binding, owner.getContainer(), ((BindingImpl) binding).createCodec(), seiModel, sei));
   333     }
   335     public WSDLPort getWSDLPort() {
   336         return wsdlPort;
   337     }
   339     public WSService getService() {
   340         return owner;
   341     }
   343     public Pool<Tube> getTubes() {
   344         return tubes;
   345     }
   347     /**
   348      * Checks only if RespectBindingFeature is enabled
   349      * checks if all required wsdl extensions in the
   350      * corresponding wsdl:Port are understood when RespectBindingFeature is enabled.
   351      * @throws WebServiceException
   352      *      when any wsdl extension that has wsdl:required=true is not understood
   353      */
   354     private static void checkAllWSDLExtensionsUnderstood(WSPortInfo port, WSBinding binding) {
   355         if (port.getPort() != null && binding.isFeatureEnabled(RespectBindingFeature.class)) {
   356             port.getPort().areRequiredExtensionsUnderstood();
   357         }
   358     }
   360     @Override
   361     public WSPortInfo getPortInfo() {
   362         return portInfo;
   363     }
   365     /**
   366      * Nullable when there is no associated WSDL Model
   367      * @return
   368      */
   369     public
   370     @Nullable
   371     OperationDispatcher getOperationDispatcher() {
   372         if (operationDispatcher == null && wsdlPort != null) {
   373             operationDispatcher = new OperationDispatcher(wsdlPort, binding, null);
   374         }
   375         return operationDispatcher;
   376     }
   378     /**
   379      * Gets the port name that this stub is configured to talk to.
   380      * <p>
   381      * When {@link #wsdlPort} is non-null, the port name is always
   382      * the same as {@link WSDLPort#getName()}, but this method
   383      * returns a port name even if no WSDL is available for this stub.
   384      */
   385     protected abstract
   386     @NotNull
   387     QName getPortName();
   389     /**
   390      * Gets the service name that this stub is configured to talk to.
   391      * <p>
   392      * When {@link #wsdlPort} is non-null, the service name is always
   393      * the same as the one that's inferred from {@link WSDLPort#getOwner()},
   394      * but this method returns a port name even if no WSDL is available for
   395      * this stub.
   396      */
   397     protected final
   398     @NotNull
   399     QName getServiceName() {
   400         return owner.getServiceName();
   401     }
   403     /**
   404      * Gets the {@link Executor} to be used for asynchronous method invocations.
   405      * <p>
   406      * Note that the value this method returns may different from invocations
   407      * to invocations. The caller must not cache.
   408      *
   409      * @return always non-null.
   410      */
   411     public final Executor getExecutor() {
   412         return owner.getExecutor();
   413     }
   415     /**
   416      * Passes a message to a pipe for processing.
   417      * <p>
   418      * Unlike {@link Tube} instances,
   419      * this method is thread-safe and can be invoked from
   420      * multiple threads concurrently.
   421      *
   422      * @param packet         The message to be sent to the server
   423      * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
   424      *                       This must be the same object as {@link #requestContext} for synchronous
   425      *                       invocations, but for asynchronous invocations, it needs to be a snapshot
   426      *                       captured at the point of invocation, to correctly satisfy the spec requirement.
   427      * @param receiver       Receives the {@link ResponseContext}. Since the spec requires
   428      *                       that the asynchronous invocations must not update response context,
   429      *                       depending on the mode of invocation they have to go to different places.
   430      *                       So we take a setter that abstracts that away.
   431      */
   432     protected final Packet process(Packet packet, RequestContext requestContext, ResponseContextReceiver receiver) {
   433         packet.isSynchronousMEP = true;
   434         packet.component = this;
   435         configureRequestPacket(packet, requestContext);
   436         Pool<Tube> pool = tubes;
   437         if (pool == null) {
   438             throw new WebServiceException("close method has already been invoked"); // TODO: i18n
   439         }
   441         Fiber fiber = engine.createFiber();
   442         configureFiber(fiber);
   444         // then send it away!
   445         Tube tube = pool.take();
   447         try {
   448             return fiber.runSync(tube, packet);
   449         } finally {
   450             // this allows us to capture the packet even when the call failed with an exception.
   451             // when the call fails with an exception it's no longer a 'reply' but it may provide some information
   452             // about what went wrong.
   454             // note that Packet can still be updated after
   455             // ResponseContext is created.
   456             Packet reply = (fiber.getPacket() == null) ? packet : fiber.getPacket();
   457             receiver.setResponseContext(new ResponseContext(reply));
   459             pool.recycle(tube);
   460         }
   461     }
   463     private void configureRequestPacket(Packet packet, RequestContext requestContext) {
   464         // fill in Packet
   465         packet.proxy = this;
   466         packet.handlerConfig = binding.getHandlerConfig();
   468         // to make it multi-thread safe we need to first get a stable snapshot
   469         Header[] hl = userOutboundHeaders;
   470         if (hl != null) {
   471             MessageHeaders mh = packet.getMessage().getHeaders();
   472             for (Header h : hl) {
   473                 mh.add(h);
   474             }
   475         }
   477         requestContext.fill(packet, (binding.getAddressingVersion() != null));
   478         packet.addSatellite(wsdlProperties);
   480         if (addrVersion != null) {
   481             // populate request WS-Addressing headers
   482             MessageHeaders headerList = packet.getMessage().getHeaders();
   483             AddressingUtils.fillRequestAddressingHeaders(headerList, wsdlPort, binding, packet);
   486             // Spec is not clear on if ReferenceParameters are to be added when addressing is not enabled,
   487             // but the EPR has ReferenceParameters.
   488             // Current approach: Add ReferenceParameters only if addressing enabled.
   489             if (endpointReference != null) {
   490                 endpointReference.addReferenceParametersToList(packet.getMessage().getHeaders());
   491             }
   492         }
   493     }
   495     /**
   496      * Passes a message through a {@link Tube}line for processing. The processing happens
   497      * asynchronously and when the response is available, Fiber.CompletionCallback is
   498      * called. The processing could happen on multiple threads.
   499      *
   500      * <p>
   501      * Unlike {@link Tube} instances,
   502      * this method is thread-safe and can be invoked from
   503      * multiple threads concurrently.
   504      *
   505      * @param receiver       The {@link Response} implementation
   506      * @param request         The message to be sent to the server
   507      * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
   508      *                       This must be the same object as {@link #requestContext} for synchronous
   509      *                       invocations, but for asynchronous invocations, it needs to be a snapshot
   510      *                       captured at the point of invocation, to correctly satisfy the spec requirement.
   511      * @param completionCallback Once the processing is done, the callback is invoked.
   512      */
   513     protected final void processAsync(AsyncResponseImpl<?> receiver, Packet request, RequestContext requestContext, final Fiber.CompletionCallback completionCallback) {
   514         // fill in Packet
   515         request.component = this;
   516         configureRequestPacket(request, requestContext);
   518         final Pool<Tube> pool = tubes;
   519         if (pool == null) {
   520             throw new WebServiceException("close method has already been invoked"); // TODO: i18n
   521         }
   523         final Fiber fiber = engine.createFiber();
   524         configureFiber(fiber);
   526         receiver.setCancelable(fiber);
   528         // check race condition on cancel
   529         if (receiver.isCancelled()) {
   530             return;
   531         }
   533         FiberContextSwitchInterceptorFactory fcsif = owner.getSPI(FiberContextSwitchInterceptorFactory.class);
   534         if (fcsif != null) {
   535             fiber.addInterceptor(fcsif.create());
   536         }
   538         // then send it away!
   539         final Tube tube = pool.take();
   541         Fiber.CompletionCallback fiberCallback = new Fiber.CompletionCallback() {
   542             @Override
   543             public void onCompletion(@NotNull Packet response) {
   544                 pool.recycle(tube);
   545                 completionCallback.onCompletion(response);
   546             }
   548             @Override
   549             public void onCompletion(@NotNull Throwable error) {
   550                 // let's not reuse tubes as they might be in a wrong state, so not
   551                 // calling pool.recycle()
   552                 completionCallback.onCompletion(error);
   553             }
   554         };
   556         // Check for SyncStartForAsyncInvokeFeature
   558         fiber.start(tube, request, fiberCallback,
   559                         getBinding().isFeatureEnabled(SyncStartForAsyncFeature.class) &&
   560                         !requestContext.containsKey(PREVENT_SYNC_START_FOR_ASYNC_INVOKE));
   561     }
   563     protected void configureFiber(Fiber fiber) {
   564         // no-op in the base class, but can be used by derived classes to configure the Fiber prior
   565         // to invocation
   566     }
   568     private static final Logger monitoringLogger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
   570     @Override
   571     public void close() {
   572         TubePool tp = (TubePool) tubes;
   573         if (tp != null) {
   574             // multi-thread safety of 'close' needs to be considered more carefully.
   575             // some calls might be pending while this method is invoked. Should we
   576             // block until they are complete, or should we abort them (but how?)
   577             Tube p = tp.takeMaster();
   578             p.preDestroy();
   579             tubes = null;
   580         }
   581         if (!managedObjectManagerClosed) {
   582             try {
   583                 final ObjectName name = managedObjectManager.getObjectName(managedObjectManager.getRoot());
   584                 // The name is null when the MOM is a NOOP.
   585                 if (name != null) {
   586                     monitoringLogger.log(Level.INFO, "Closing Metro monitoring root: {0}", name);
   587                 }
   588                 managedObjectManager.close();
   589             } catch (java.io.IOException e) {
   590                 monitoringLogger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e);
   591             }
   592             managedObjectManagerClosed = true;
   593         }
   594     }
   596     @Override
   597     public final WSBinding getBinding() {
   598         return binding;
   599     }
   601     @Override
   602     public final Map<String, Object> getRequestContext() {
   603         return requestContext.asMap();
   604     }
   606     public void resetRequestContext() {
   607         requestContext = cleanRequestContext.copy();
   608     }
   610     @Override
   611     public final ResponseContext getResponseContext() {
   612         return responseContext;
   613     }
   615     @Override
   616     public void setResponseContext(ResponseContext rc) {
   617         this.responseContext = rc;
   618     }
   620     private String getStringId() {
   621         return RuntimeVersion.VERSION + ": Stub for " + getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
   622     }
   624     @Override
   625     public String toString() {
   626         return getStringId();
   627     }
   629     @Override
   630     public final WSEndpointReference getWSEndpointReference() {
   631         if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) {
   632             throw new java.lang.UnsupportedOperationException(
   633                         ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference(Class<T> class)", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding")
   634                     );
   635         }
   637         if (endpointReference != null) {
   638             return endpointReference;
   639         }
   641         String eprAddress = requestContext.getEndpointAddress().toString();
   642         QName portTypeName = null;
   643         String wsdlAddress = null;
   644         List<WSEndpointReference.EPRExtension> wsdlEPRExtensions = new ArrayList<WSEndpointReference.EPRExtension>();
   645         if (wsdlPort != null) {
   646             portTypeName = wsdlPort.getBinding().getPortTypeName();
   647             wsdlAddress = eprAddress + "?wsdl";
   649             //gather EPRExtensions specified in WSDL.
   650             try {
   651                 WSEndpointReference wsdlEpr = wsdlPort.getEPR();
   652                 if (wsdlEpr != null) {
   653                     for (WSEndpointReference.EPRExtension extnEl : wsdlEpr.getEPRExtensions()) {
   654                         wsdlEPRExtensions.add(new WSEPRExtension(
   655                                 XMLStreamBuffer.createNewBufferFromXMLStreamReader(extnEl.readAsXMLStreamReader()), extnEl.getQName()));
   656                     }
   657                 }
   659             } catch (XMLStreamException ex) {
   660                 throw new WebServiceException(ex);
   661             }
   662         }
   663         AddressingVersion av = AddressingVersion.W3C;
   664         this.endpointReference = new WSEndpointReference(
   665                 av, eprAddress, getServiceName(), getPortName(), portTypeName, null, wsdlAddress, null, wsdlEPRExtensions, null);
   667         return this.endpointReference;
   668     }
   671     @Override
   672     public final W3CEndpointReference getEndpointReference() {
   673         if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) {
   674             throw new java.lang.UnsupportedOperationException(
   675                         ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference()", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding"));
   676         }
   677         return getEndpointReference(W3CEndpointReference.class);
   678     }
   680     @Override
   681     public final <T extends EndpointReference> T getEndpointReference(Class<T> clazz) {
   682         return getWSEndpointReference().toSpec(clazz);
   683     }
   685     public
   686     @NotNull
   687     @Override
   688     ManagedObjectManager getManagedObjectManager() {
   689         return managedObjectManager;
   690     }
   692     //
   693 //
   694 // WSBindingProvider methods
   695 //
   696 //
   697     @Override
   698     public final void setOutboundHeaders(List<Header> headers) {
   699         if (headers == null) {
   700             this.userOutboundHeaders = null;
   701         } else {
   702             for (Header h : headers) {
   703                 if (h == null) {
   704                     throw new IllegalArgumentException();
   705                 }
   706             }
   707             userOutboundHeaders = headers.toArray(new Header[headers.size()]);
   708         }
   709     }
   711     @Override
   712     public final void setOutboundHeaders(Header... headers) {
   713         if (headers == null) {
   714             this.userOutboundHeaders = null;
   715         } else {
   716             for (Header h : headers) {
   717                 if (h == null) {
   718                     throw new IllegalArgumentException();
   719                 }
   720             }
   721             Header[] hl = new Header[headers.length];
   722             System.arraycopy(headers, 0, hl, 0, headers.length);
   723             userOutboundHeaders = hl;
   724         }
   725     }
   727     @Override
   728     public final List<Header> getInboundHeaders() {
   729         return Collections.unmodifiableList(((MessageHeaders)
   730                 responseContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)).asList());
   731     }
   733     @Override
   734     public final void setAddress(String address) {
   735         requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
   736     }
   738     @Override
   739     public <S> S getSPI(Class<S> spiType) {
   740         for (Component c : components) {
   741             S s = c.getSPI(spiType);
   742             if (s != null) {
   743                 return s;
   744             }
   745         }
   746         return owner.getSPI(spiType);
   747     }
   749     @Override
   750     public Set<Component> getComponents() {
   751         return components;
   752     }
   753 }

mercurial