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

changeset 286
f50545b5e2f1
child 368
0989ad8c0860
equal deleted inserted replaced
284:88b85470e72c 286:f50545b5e2f1
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 */
25
26 package com.sun.xml.internal.ws.client;
27
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;
63
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;
80
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";
100
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;
107
108 private final Engine engine;
109
110 /**
111 * The {@link WSServiceDelegate} object that owns us.
112 */
113 protected final WSServiceDelegate owner;
114
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;
128
129 protected final BindingImpl binding;
130
131 protected final WSPortInfo portInfo;
132
133 /**
134 * represents AddressingVersion on binding if enabled, otherwise null;
135 */
136 protected AddressingVersion addrVersion;
137
138 public RequestContext requestContext = new RequestContext();
139
140 private final RequestContext cleanRequestContext;
141
142 /**
143 * {@link ResponseContext} from the last synchronous operation.
144 */
145 private ResponseContext responseContext;
146 @Nullable
147 protected final WSDLPort wsdlPort;
148
149 protected QName portname;
150
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;
157
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;
166
167 private final Set<Component> components = new CopyOnWriteArraySet<Component>();
168
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 }
184
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 }
201
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 }
217
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);
231
232 }
233
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;
246
247 ComponentFeature cf = binding.getFeature(ComponentFeature.class);
248 if (cf != null && Target.STUB.equals(cf.getTarget())) {
249 components.add(cf.getComponent());
250 }
251
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);
260
261 this.cleanRequestContext = this.requestContext.copy();
262
263 // ManagedObjectManager MUST be created before the pipeline
264 // is constructed.
265
266 managedObjectManager = new MonitorRootClient(this).createManagedObjectManager(this);
267
268 if (master != null)
269 this.tubes = new TubePool(master);
270 else
271 this.tubes = new TubePool(createPipeline(portInfo, binding));
272
273 addrVersion = binding.getAddressingVersion();
274
275 // This needs to happen after createPipeline.
276 // TBD: Check if it needs to happen outside the Stub constructor.
277 managedObjectManager.resumeJMXRegistration();
278 }
279
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();
294
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 }
305
306 public WSDLPort getWSDLPort() {
307 return wsdlPort;
308 }
309
310 public WSService getService() {
311 return owner;
312 }
313
314 public Pool<Tube> getTubes() {
315 return tubes;
316 }
317
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 }
330
331 public WSPortInfo getPortInfo() {
332 return portInfo;
333 }
334
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 }
346
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();
357
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 }
371
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 }
383
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
408
409 Fiber fiber = engine.createFiber();
410 // then send it away!
411 Tube tube = pool.take();
412
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.
419
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));
424
425 pool.recycle(tube);
426 }
427 }
428
429 private void configureRequestPacket(Packet packet, RequestContext requestContext) {
430 // fill in Packet
431 packet.proxy = this;
432 packet.handlerConfig = binding.getHandlerConfig();
433
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);
438
439 requestContext.fill(packet, (binding.getAddressingVersion() != null));
440 packet.addSatellite(wsdlProperties);
441
442 if (addrVersion != null) {
443 // populate request WS-Addressing headers
444 HeaderList headerList = packet.getMessage().getHeaders();
445 headerList.fillRequestAddressingHeaders(wsdlPort, binding, packet);
446
447
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 }
456
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);
479
480 final Pool<Tube> pool = tubes;
481 if (pool == null)
482 throw new WebServiceException("close method has already been invoked"); // TODO: i18n
483
484 final Fiber fiber = engine.createFiber();
485
486 receiver.setCancelable(fiber);
487
488 // check race condition on cancel
489 if (receiver.isCancelled())
490 return;
491
492 FiberContextSwitchInterceptorFactory fcsif = owner.getSPI(FiberContextSwitchInterceptorFactory.class);
493 if(fcsif != null)
494 fiber.addInterceptor(fcsif.create());
495
496 // then send it away!
497 final Tube tube = pool.take();
498
499 Fiber.CompletionCallback fiberCallback = new Fiber.CompletionCallback() {
500 public void onCompletion(@NotNull Packet response) {
501 pool.recycle(tube);
502 completionCallback.onCompletion(response);
503 }
504
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 };
511
512 // Check for SyncStartForAsyncInvokeFeature
513
514 fiber.start(tube, request, fiberCallback,
515 getBinding().isFeatureEnabled(SyncStartForAsyncFeature.class) &&
516 !requestContext.containsKey(PREVENT_SYNC_START_FOR_ASYNC_INVOKE));
517 }
518
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 }
534
535 }
536
537 public final WSBinding getBinding() {
538 return binding;
539 }
540
541 public final Map<String, Object> getRequestContext() {
542 return requestContext.getMapView();
543 }
544
545 public void resetRequestContext() {
546 requestContext = cleanRequestContext.copy();
547 }
548
549 public final ResponseContext getResponseContext() {
550 return responseContext;
551 }
552
553 public void setResponseContext(ResponseContext rc) {
554 this.responseContext = rc;
555 }
556
557 public String toString() {
558 return RuntimeVersion.VERSION + ": Stub for " + getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
559 }
560
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"));
564
565 if (endpointReference != null) {
566 return endpointReference;
567 }
568
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";
576
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 }
586
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);
594
595 return this.endpointReference;
596 }
597
598
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 }
604
605 public final <T extends EndpointReference> T getEndpointReference(Class<T> clazz) {
606 return getWSEndpointReference().toSpec(clazz);
607 }
608
609 public
610 @NotNull
611 ManagedObjectManager getManagedObjectManager() {
612 return managedObjectManager;
613 }
614
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 }
631
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 }
645
646 public final List<Header> getInboundHeaders() {
647 return Collections.unmodifiableList((HeaderList)
648 responseContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY));
649 }
650
651 public final void setAddress(String address) {
652 requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
653 }
654
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 }
663
664 public Set<Component> getComponents() {
665 return components;
666 }
667 }

mercurial