Wed, 27 Apr 2016 01:27:09 +0800
Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17
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 }