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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

     1 /*
     2  * Copyright (c) 1997, 2010, 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.model.wsdl.WSDLDirectProperties;
    34 import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties;
    35 import com.sun.xml.internal.ws.model.wsdl.WSDLProperties;
    36 import com.sun.xml.internal.ws.model.wsdl.WSDLServiceImpl;
    37 import com.sun.xml.internal.ws.api.Component;
    38 import com.sun.xml.internal.ws.api.ComponentFeature;
    39 import com.sun.xml.internal.ws.api.ComponentFeature.Target;
    40 import com.sun.xml.internal.ws.api.ComponentRegistry;
    41 import com.sun.xml.internal.ws.api.EndpointAddress;
    42 import com.sun.xml.internal.ws.api.WSBinding;
    43 import com.sun.xml.internal.ws.api.WSService;
    44 import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
    45 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
    46 import com.sun.xml.internal.ws.api.client.WSPortInfo;
    47 import com.sun.xml.internal.ws.api.message.Header;
    48 import com.sun.xml.internal.ws.api.message.HeaderList;
    49 import com.sun.xml.internal.ws.api.message.Packet;
    50 import com.sun.xml.internal.ws.api.model.SEIModel;
    51 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
    52 import com.sun.xml.internal.ws.api.pipe.*;
    53 import com.sun.xml.internal.ws.binding.BindingImpl;
    54 import com.sun.xml.internal.ws.developer.JAXWSProperties;
    55 import com.sun.xml.internal.ws.developer.WSBindingProvider;
    56 import com.sun.xml.internal.ws.model.wsdl.WSDLPortImpl;
    57 import com.sun.xml.internal.ws.resources.ClientMessages;
    58 import com.sun.xml.internal.ws.util.Pool;
    59 import com.sun.xml.internal.ws.util.Pool.TubePool;
    60 import com.sun.xml.internal.ws.util.RuntimeVersion;
    61 import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
    62 import com.sun.org.glassfish.gmbal.ManagedObjectManager;
    64 import javax.xml.namespace.QName;
    65 import javax.xml.stream.XMLStreamException;
    66 import javax.xml.ws.BindingProvider;
    67 import javax.xml.ws.EndpointReference;
    68 import javax.xml.ws.RespectBindingFeature;
    69 import javax.xml.ws.WebServiceException;
    70 import javax.xml.ws.http.HTTPBinding;
    71 import javax.xml.ws.wsaddressing.W3CEndpointReference;
    72 import java.util.ArrayList;
    73 import java.util.Collections;
    74 import java.util.List;
    75 import java.util.Map;
    76 import java.util.Set;
    77 import java.util.concurrent.CopyOnWriteArraySet;
    78 import java.util.concurrent.Executor;
    79 import org.xml.sax.InputSource;
    81 /**
    82  * Base class for stubs, which accept method invocations from
    83  * client applications and pass the message to a {@link Tube}
    84  * for processing.
    85  *
    86  * <p>
    87  * This class implements the management of pipe instances,
    88  * and most of the {@link BindingProvider} methods.
    89  *
    90  * @author Kohsuke Kawaguchi
    91  */
    92 public abstract class Stub implements WSBindingProvider, ResponseContextReceiver, ComponentRegistry  {
    93     /**
    94      * Internal flag indicating async dispatch should be used even when the
    95      * SyncStartForAsyncInvokeFeature is present on the binding associated
    96      * with a stub. There is no type associated with this property on the
    97      * request context. Its presence is what triggers the 'prevent' behavior.
    98      */
    99     public static final String PREVENT_SYNC_START_FOR_ASYNC_INVOKE = "com.sun.xml.internal.ws.client.StubRequestSyncStartForAsyncInvoke";
   101     /**
   102      * Reuse pipelines as it's expensive to create.
   103      * <p>
   104      * Set to null when {@link #close() closed}.
   105      */
   106     private Pool<Tube> tubes;
   108     private final Engine engine;
   110     /**
   111      * The {@link WSServiceDelegate} object that owns us.
   112      */
   113     protected final WSServiceDelegate owner;
   115     /**
   116      * Non-null if this stub is configured to talk to an EPR.
   117      * <p>
   118      * When this field is non-null, its reference parameters are sent as out-bound headers.
   119      * This field can be null even when addressing is enabled, but if the addressing is
   120      * not enabled, this field must be null.
   121      * <p>
   122      * Unlike endpoint address, we are not letting users to change the EPR,
   123      * as it contains references to services and so on that we don't want to change.
   124      */
   125     protected
   126     @Nullable
   127     WSEndpointReference endpointReference;
   129     protected final BindingImpl binding;
   131     protected final WSPortInfo portInfo;
   133     /**
   134      * represents AddressingVersion on binding if enabled, otherwise null;
   135      */
   136     protected AddressingVersion addrVersion;
   138     public RequestContext requestContext = new RequestContext();
   140     private final RequestContext cleanRequestContext;
   142     /**
   143      * {@link ResponseContext} from the last synchronous operation.
   144      */
   145     private ResponseContext responseContext;
   146     @Nullable
   147     protected final WSDLPort wsdlPort;
   149     protected QName portname;
   151     /**
   152      * {@link Header}s to be added to outbound {@link Packet}.
   153      * The contents is determined by the user.
   154      */
   155     @Nullable
   156     private volatile Header[] userOutboundHeaders;
   158     private final
   159     @NotNull
   160     WSDLProperties wsdlProperties;
   161     protected OperationDispatcher operationDispatcher = null;
   162     private final
   163     @NotNull
   164     ManagedObjectManager managedObjectManager;
   165     private boolean managedObjectManagerClosed = false;
   167     private final Set<Component> components = new CopyOnWriteArraySet<Component>();
   169     /**
   170      * @param master                 The created stub will send messages to this pipe.
   171      * @param binding                As a {@link BindingProvider}, this object will
   172      *                               return this binding from {@link BindingProvider#getBinding()}.
   173      * @param defaultEndPointAddress The destination of the message. The actual destination
   174      *                               could be overridden by {@link RequestContext}.
   175      * @param epr                    To create a stub that sends out reference parameters
   176      *                               of a specific EPR, give that instance. Otherwise null.
   177      *                               Its address field will not be used, and that should be given
   178      *                               separately as the <tt>defaultEndPointAddress</tt>.
   179      */
   180     @Deprecated
   181     protected Stub(WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   182         this(owner, master, null, null, binding, wsdlPort, defaultEndPointAddress, epr);
   183     }
   185     /**
   186      * @param portname               The name of this port
   187      * @param master                 The created stub will send messages to this pipe.
   188      * @param binding                As a {@link BindingProvider}, this object will
   189      *                               return this binding from {@link BindingProvider#getBinding()}.
   190      * @param defaultEndPointAddress The destination of the message. The actual destination
   191      *                               could be overridden by {@link RequestContext}.
   192      * @param epr                    To create a stub that sends out reference parameters
   193      *                               of a specific EPR, give that instance. Otherwise null.
   194      *                               Its address field will not be used, and that should be given
   195      *                               separately as the <tt>defaultEndPointAddress</tt>.
   196      */
   197     @Deprecated
   198     protected Stub(QName portname, WSServiceDelegate owner, Tube master, BindingImpl binding, WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   199         this(owner, master, null, portname, binding, wsdlPort, defaultEndPointAddress, epr);
   200     }
   202     /**
   203      * @param portInfo               PortInfo  for this stub
   204      * @param binding                As a {@link BindingProvider}, this object will
   205      *                               return this binding from {@link BindingProvider#getBinding()}.
   206      * @param master                 The created stub will send messages to this pipe.
   207      * @param defaultEndPointAddress The destination of the message. The actual destination
   208      *                               could be overridden by {@link RequestContext}.
   209      * @param epr                    To create a stub that sends out reference parameters
   210      *                               of a specific EPR, give that instance. Otherwise null.
   211      *                               Its address field will not be used, and that should be given
   212      *                               separately as the <tt>defaultEndPointAddress</tt>.
   213      */
   214     protected Stub(WSPortInfo portInfo, BindingImpl binding, Tube master,EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   215          this((WSServiceDelegate) portInfo.getOwner(), master, portInfo, null, binding,portInfo.getPort(), defaultEndPointAddress, epr);
   216     }
   218   /**
   219    * @param portInfo               PortInfo  for this stub
   220    * @param binding                As a {@link BindingProvider}, this object will
   221    *                               return this binding from {@link BindingProvider#getBinding()}.
   222    * @param defaultEndPointAddress The destination of the message. The actual destination
   223    *                               could be overridden by {@link RequestContext}.
   224    * @param epr                    To create a stub that sends out reference parameters
   225    *                               of a specific EPR, give that instance. Otherwise null.
   226    *                               Its address field will not be used, and that should be given
   227    *                               separately as the <tt>defaultEndPointAddress</tt>.
   228    */
   229   protected Stub(WSPortInfo portInfo, BindingImpl binding, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   230        this(portInfo,binding,null, defaultEndPointAddress,epr);
   232   }
   234     private Stub(WSServiceDelegate owner, @Nullable Tube master, @Nullable WSPortInfo portInfo, QName portname, BindingImpl binding, @Nullable WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) {
   235         this.owner = owner;
   236         this.portInfo = portInfo;
   237         this.wsdlPort = wsdlPort != null ? wsdlPort : (portInfo != null ? portInfo.getPort() : null);
   238         this.portname = portname;
   239         if (portname == null) {
   240                 if (portInfo != null)
   241                         this.portname = portInfo.getPortName();
   242                 else if (wsdlPort != null)
   243                         this.portname = wsdlPort.getName();
   244         }
   245         this.binding = binding;
   247         ComponentFeature cf = binding.getFeature(ComponentFeature.class);
   248         if (cf != null && Target.STUB.equals(cf.getTarget())) {
   249             components.add(cf.getComponent());
   250         }
   252         // if there is an EPR, EPR's address should be used for invocation instead of default address
   253         if (epr != null)
   254             this.requestContext.setEndPointAddressString(epr.getAddress());
   255         else
   256             this.requestContext.setEndpointAddress(defaultEndPointAddress);
   257         this.engine = new Engine(toString(), owner.getExecutor());
   258         this.endpointReference = epr;
   259         wsdlProperties = (wsdlPort == null) ? new WSDLDirectProperties(owner.getServiceName(), portname) : new WSDLPortProperties(wsdlPort);
   261         this.cleanRequestContext = this.requestContext.copy();
   263         // ManagedObjectManager MUST be created before the pipeline
   264         // is constructed.
   266         managedObjectManager = new MonitorRootClient(this).createManagedObjectManager(this);
   268         if (master != null)
   269             this.tubes = new TubePool(master);
   270         else
   271             this.tubes = new TubePool(createPipeline(portInfo, binding));
   273         addrVersion = binding.getAddressingVersion();
   275         // This needs to happen after createPipeline.
   276         // TBD: Check if it needs to happen outside the Stub constructor.
   277         managedObjectManager.resumeJMXRegistration();
   278     }
   280     /**
   281      * Creates a new pipeline for the given port name.
   282      */
   283     private Tube createPipeline(WSPortInfo portInfo, WSBinding binding) {
   284         //Check all required WSDL extensions are understood
   285         checkAllWSDLExtensionsUnderstood(portInfo, binding);
   286         SEIModel seiModel = null;
   287         Class sei = null;
   288         if (portInfo instanceof SEIPortInfo) {
   289                 SEIPortInfo sp = (SEIPortInfo) portInfo;
   290             seiModel = sp.model;
   291             sei = sp.sei;
   292         }
   293         BindingID bindingId = portInfo.getBindingId();
   295         TubelineAssembler assembler = TubelineAssemblerFactory.create(
   296                 Thread.currentThread().getContextClassLoader(), bindingId);
   297         if (assembler == null)
   298             throw new WebServiceException("Unable to process bindingID=" + bindingId);    // TODO: i18n
   299         return assembler.createClient(
   300                 new ClientTubeAssemblerContext(
   301                         portInfo.getEndpointAddress(),
   302                         portInfo.getPort(),
   303                         this, binding, owner.getContainer(), ((BindingImpl) binding).createCodec(), seiModel, sei));
   304     }
   306     public WSDLPort getWSDLPort() {
   307         return wsdlPort;
   308     }
   310     public WSService getService() {
   311         return owner;
   312     }
   314     public Pool<Tube> getTubes() {
   315         return tubes;
   316     }
   318     /**
   319      * Checks only if RespectBindingFeature is enabled
   320      * checks if all required wsdl extensions in the
   321      * corresponding wsdl:Port are understood when RespectBindingFeature is enabled.
   322      * @throws WebServiceException
   323      *      when any wsdl extension that has wsdl:required=true is not understood
   324      */
   325     private static void checkAllWSDLExtensionsUnderstood(WSPortInfo port, WSBinding binding) {
   326         if (port.getPort() != null && binding.isFeatureEnabled(RespectBindingFeature.class)) {
   327             ((WSDLPortImpl) port.getPort()).areRequiredExtensionsUnderstood();
   328         }
   329     }
   331     public WSPortInfo getPortInfo() {
   332         return portInfo;
   333     }
   335     /**
   336      * Nullable when there is no associated WSDL Model
   337      * @return
   338      */
   339     public
   340     @Nullable
   341     OperationDispatcher getOperationDispatcher() {
   342         if (operationDispatcher == null && wsdlPort != null)
   343             operationDispatcher = new OperationDispatcher(wsdlPort, binding, null);
   344         return operationDispatcher;
   345     }
   347     /**
   348      * Gets the port name that this stub is configured to talk to.
   349      * <p>
   350      * When {@link #wsdlPort} is non-null, the port name is always
   351      * the same as {@link WSDLPort#getName()}, but this method
   352      * returns a port name even if no WSDL is available for this stub.
   353      */
   354     protected abstract
   355     @NotNull
   356     QName getPortName();
   358     /**
   359      * Gets the service name that this stub is configured to talk to.
   360      * <p>
   361      * When {@link #wsdlPort} is non-null, the service name is always
   362      * the same as the one that's inferred from {@link WSDLPort#getOwner()},
   363      * but this method returns a port name even if no WSDL is available for
   364      * this stub.
   365      */
   366     protected final
   367     @NotNull
   368     QName getServiceName() {
   369         return owner.getServiceName();
   370     }
   372     /**
   373      * Gets the {@link Executor} to be used for asynchronous method invocations.
   374      * <p>
   375      * Note that the value this method returns may different from invocations
   376      * to invocations. The caller must not cache.
   377      *
   378      * @return always non-null.
   379      */
   380     public final Executor getExecutor() {
   381         return owner.getExecutor();
   382     }
   384     /**
   385      * Passes a message to a pipe for processing.
   386      * <p>
   387      * Unlike {@link Tube} instances,
   388      * this method is thread-safe and can be invoked from
   389      * multiple threads concurrently.
   390      *
   391      * @param packet         The message to be sent to the server
   392      * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
   393      *                       This must be the same object as {@link #requestContext} for synchronous
   394      *                       invocations, but for asynchronous invocations, it needs to be a snapshot
   395      *                       captured at the point of invocation, to correctly satisfy the spec requirement.
   396      * @param receiver       Receives the {@link ResponseContext}. Since the spec requires
   397      *                       that the asynchronous invocations must not update response context,
   398      *                       depending on the mode of invocation they have to go to different places.
   399      *                       So we take a setter that abstracts that away.
   400      */
   401     protected final Packet process(Packet packet, RequestContext requestContext, ResponseContextReceiver receiver) {
   402         packet.isSynchronousMEP = true;
   403         packet.component = this;
   404         configureRequestPacket(packet, requestContext);
   405         Pool<Tube> pool = tubes;
   406         if (pool == null)
   407             throw new WebServiceException("close method has already been invoked"); // TODO: i18n
   409         Fiber fiber = engine.createFiber();
   410         // then send it away!
   411         Tube tube = pool.take();
   413         try {
   414             return fiber.runSync(tube, packet);
   415         } finally {
   416             // this allows us to capture the packet even when the call failed with an exception.
   417             // when the call fails with an exception it's no longer a 'reply' but it may provide some information
   418             // about what went wrong.
   420             // note that Packet can still be updated after
   421             // ResponseContext is created.
   422             Packet reply = (fiber.getPacket() == null) ? packet : fiber.getPacket();
   423             receiver.setResponseContext(new ResponseContext(reply));
   425             pool.recycle(tube);
   426         }
   427     }
   429     private void configureRequestPacket(Packet packet, RequestContext requestContext) {
   430         // fill in Packet
   431         packet.proxy = this;
   432         packet.handlerConfig = binding.getHandlerConfig();
   434         // to make it multi-thread safe we need to first get a stable snapshot
   435         Header[] hl = userOutboundHeaders;
   436         if (hl != null)
   437             packet.getMessage().getHeaders().addAll(hl);
   439         requestContext.fill(packet, (binding.getAddressingVersion() != null));
   440         packet.addSatellite(wsdlProperties);
   442         if (addrVersion != null) {
   443             // populate request WS-Addressing headers
   444             HeaderList headerList = packet.getMessage().getHeaders();
   445             headerList.fillRequestAddressingHeaders(wsdlPort, binding, packet);
   448             // Spec is not clear on if ReferenceParameters are to be added when addressing is not enabled,
   449             // but the EPR has ReferenceParameters.
   450             // Current approach: Add ReferenceParameters only if addressing enabled.
   451             if (endpointReference != null) {
   452                 endpointReference.addReferenceParametersToList(packet.getMessage().getHeaders());
   453             }
   454         }
   455     }
   457     /**
   458      * Passes a message through a {@link Tube}line for processing. The processing happens
   459      * asynchronously and when the response is available, Fiber.CompletionCallback is
   460      * called. The processing could happen on multiple threads.
   461      *
   462      * <p>
   463      * Unlike {@link Tube} instances,
   464      * this method is thread-safe and can be invoked from
   465      * multiple threads concurrently.
   466      *
   467      * @param receiver       The {@link Response} implementation
   468      * @param request         The message to be sent to the server
   469      * @param requestContext The {@link RequestContext} when this invocation is originally scheduled.
   470      *                       This must be the same object as {@link #requestContext} for synchronous
   471      *                       invocations, but for asynchronous invocations, it needs to be a snapshot
   472      *                       captured at the point of invocation, to correctly satisfy the spec requirement.
   473      * @param completionCallback Once the processing is done, the callback is invoked.
   474      */
   475     protected final void processAsync(AsyncResponseImpl<?> receiver, Packet request, RequestContext requestContext, final Fiber.CompletionCallback completionCallback) {
   476         // fill in Packet
   477         request.component = this;
   478         configureRequestPacket(request, requestContext);
   480         final Pool<Tube> pool = tubes;
   481         if (pool == null)
   482             throw new WebServiceException("close method has already been invoked"); // TODO: i18n
   484         final Fiber fiber = engine.createFiber();
   486         receiver.setCancelable(fiber);
   488         // check race condition on cancel
   489         if (receiver.isCancelled())
   490                 return;
   492         FiberContextSwitchInterceptorFactory fcsif = owner.getSPI(FiberContextSwitchInterceptorFactory.class);
   493         if(fcsif != null)
   494             fiber.addInterceptor(fcsif.create());
   496         // then send it away!
   497         final Tube tube = pool.take();
   499         Fiber.CompletionCallback fiberCallback = new Fiber.CompletionCallback() {
   500             public void onCompletion(@NotNull Packet response) {
   501                 pool.recycle(tube);
   502                 completionCallback.onCompletion(response);
   503             }
   505             public void onCompletion(@NotNull Throwable error) {
   506                 // let's not reuse tubes as they might be in a wrong state, so not
   507                 // calling pool.recycle()
   508                 completionCallback.onCompletion(error);
   509             }
   510         };
   512         // Check for SyncStartForAsyncInvokeFeature
   514         fiber.start(tube, request, fiberCallback,
   515                         getBinding().isFeatureEnabled(SyncStartForAsyncFeature.class) &&
   516                         !requestContext.containsKey(PREVENT_SYNC_START_FOR_ASYNC_INVOKE));
   517     }
   519     public void close() {
   520         if (tubes != null) {
   521             // multi-thread safety of 'close' needs to be considered more carefully.
   522             // some calls might be pending while this method is invoked. Should we
   523             // block until they are complete, or should we abort them (but how?)
   524             Tube p = tubes.take();
   525             tubes = null;
   526             p.preDestroy();
   527         }
   528         if (managedObjectManagerClosed) {
   529             return;
   530         } else {
   531             com.sun.xml.internal.ws.server.MonitorBase.closeMOM(managedObjectManager);
   532             managedObjectManagerClosed = true;
   533         }
   535     }
   537     public final WSBinding getBinding() {
   538         return binding;
   539     }
   541     public final Map<String, Object> getRequestContext() {
   542         return requestContext.getMapView();
   543     }
   545     public void resetRequestContext() {
   546         requestContext = cleanRequestContext.copy();
   547     }
   549     public final ResponseContext getResponseContext() {
   550         return responseContext;
   551     }
   553     public void setResponseContext(ResponseContext rc) {
   554         this.responseContext = rc;
   555     }
   557     public String toString() {
   558         return RuntimeVersion.VERSION + ": Stub for " + getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
   559     }
   561     public final WSEndpointReference getWSEndpointReference() {
   562         if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING))
   563             throw new java.lang.UnsupportedOperationException(ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference(Class<T> class)", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding"));
   565         if (endpointReference != null) {
   566             return endpointReference;
   567         }
   569         String eprAddress = requestContext.getEndpointAddress().toString();
   570         QName portTypeName = null;
   571         String wsdlAddress = null;
   572         List<WSEndpointReference.EPRExtension> wsdlEPRExtensions = new ArrayList<WSEndpointReference.EPRExtension>();
   573         if (wsdlPort != null) {
   574             portTypeName = wsdlPort.getBinding().getPortTypeName();
   575             wsdlAddress = eprAddress + "?wsdl";
   577             //gather EPRExtensions specified in WSDL.
   578             try {
   579                 WSEndpointReference wsdlEpr = ((WSDLPortImpl) wsdlPort).getEPR();
   580                 if (wsdlEpr != null) {
   581                     for (WSEndpointReference.EPRExtension extnEl : wsdlEpr.getEPRExtensions()) {
   582                         wsdlEPRExtensions.add(new WSEPRExtension(
   583                                 XMLStreamBuffer.createNewBufferFromXMLStreamReader(extnEl.readAsXMLStreamReader()), extnEl.getQName()));
   584                     }
   585                 }
   587             } catch (XMLStreamException ex) {
   588                 throw new WebServiceException(ex);
   589             }
   590         }
   591         AddressingVersion av = AddressingVersion.W3C;
   592         this.endpointReference = new WSEndpointReference(
   593                 av, eprAddress, getServiceName(), getPortName(), portTypeName, null, wsdlAddress, null, wsdlEPRExtensions, null);
   595         return this.endpointReference;
   596     }
   599     public final W3CEndpointReference getEndpointReference() {
   600         if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING))
   601             throw new java.lang.UnsupportedOperationException(ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference()", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding"));
   602         return getEndpointReference(W3CEndpointReference.class);
   603     }
   605     public final <T extends EndpointReference> T getEndpointReference(Class<T> clazz) {
   606         return getWSEndpointReference().toSpec(clazz);
   607     }
   609     public
   610     @NotNull
   611     ManagedObjectManager getManagedObjectManager() {
   612         return managedObjectManager;
   613     }
   615     //
   616 //
   617 // WSBindingProvider methods
   618 //
   619 //
   620     public final void setOutboundHeaders(List<Header> headers) {
   621         if (headers == null) {
   622             this.userOutboundHeaders = null;
   623         } else {
   624             for (Header h : headers) {
   625                 if (h == null)
   626                     throw new IllegalArgumentException();
   627             }
   628             userOutboundHeaders = headers.toArray(new Header[headers.size()]);
   629         }
   630     }
   632     public final void setOutboundHeaders(Header... headers) {
   633         if (headers == null) {
   634             this.userOutboundHeaders = null;
   635         } else {
   636             for (Header h : headers) {
   637                 if (h == null)
   638                     throw new IllegalArgumentException();
   639             }
   640             Header[] hl = new Header[headers.length];
   641             System.arraycopy(headers, 0, hl, 0, headers.length);
   642             userOutboundHeaders = hl;
   643         }
   644     }
   646     public final List<Header> getInboundHeaders() {
   647         return Collections.unmodifiableList((HeaderList)
   648                 responseContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY));
   649     }
   651     public final void setAddress(String address) {
   652         requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
   653     }
   655     public <S> S getSPI(Class<S> spiType) {
   656         for (Component c : components) {
   657             S s = c.getSPI(spiType);
   658             if (s != null)
   659                 return s;
   660         }
   661         return owner.getSPI(spiType);
   662     }
   664     public Set<Component> getComponents() {
   665         return components;
   666     }
   667 }

mercurial