src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/Packet.java

Wed, 27 Apr 2016 01:27:09 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:27:09 +0800
changeset 0
373ffda63c9a
child 637
9c07ef4934dd
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.ws.api.message;
aoqi@0 27
aoqi@0 28 import com.oracle.webservices.internal.api.message.ContentType;
aoqi@0 29 import com.oracle.webservices.internal.api.message.PropertySet;
aoqi@0 30 import com.sun.istack.internal.NotNull;
aoqi@0 31 import com.sun.istack.internal.Nullable;
aoqi@0 32 import com.sun.xml.internal.bind.marshaller.SAX2DOMEx;
aoqi@0 33 import com.sun.xml.internal.ws.addressing.WsaPropertyBag;
aoqi@0 34 import com.sun.xml.internal.ws.addressing.WsaServerTube;
aoqi@0 35 import com.sun.xml.internal.ws.addressing.WsaTubeHelper;
aoqi@0 36 import com.sun.xml.internal.ws.api.Component;
aoqi@0 37 import com.sun.xml.internal.ws.api.EndpointAddress;
aoqi@0 38 import com.sun.xml.internal.ws.api.SOAPVersion;
aoqi@0 39 import com.sun.xml.internal.ws.api.WSBinding;
aoqi@0 40 import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
aoqi@0 41 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
aoqi@0 42 import com.sun.xml.internal.ws.api.model.JavaMethod;
aoqi@0 43 import com.sun.xml.internal.ws.api.model.SEIModel;
aoqi@0 44 import com.sun.xml.internal.ws.api.model.WSDLOperationMapping;
aoqi@0 45 import com.sun.xml.internal.ws.api.model.wsdl.WSDLOperation;
aoqi@0 46 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
aoqi@0 47 import com.sun.xml.internal.ws.api.pipe.Codec;
aoqi@0 48 import com.sun.xml.internal.ws.api.pipe.Tube;
aoqi@0 49 import com.sun.xml.internal.ws.api.server.Adapter;
aoqi@0 50 import com.sun.xml.internal.ws.api.server.TransportBackChannel;
aoqi@0 51 import com.sun.xml.internal.ws.api.server.WSEndpoint;
aoqi@0 52 import com.sun.xml.internal.ws.api.server.WebServiceContextDelegate;
aoqi@0 53 import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
aoqi@0 54 import com.sun.xml.internal.ws.client.*;
aoqi@0 55 import com.sun.xml.internal.ws.developer.JAXWSProperties;
aoqi@0 56 import com.sun.xml.internal.ws.encoding.MtomCodec;
aoqi@0 57 import com.sun.xml.internal.ws.message.RelatesToHeader;
aoqi@0 58 import com.sun.xml.internal.ws.message.StringHeader;
aoqi@0 59 import com.sun.xml.internal.ws.util.DOMUtil;
aoqi@0 60 import com.sun.xml.internal.ws.util.xml.XmlUtil;
aoqi@0 61 import com.sun.xml.internal.ws.wsdl.DispatchException;
aoqi@0 62 import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
aoqi@0 63 import com.sun.xml.internal.ws.resources.AddressingMessages;
aoqi@0 64
aoqi@0 65
aoqi@0 66 import org.w3c.dom.Document;
aoqi@0 67 import org.w3c.dom.Element;
aoqi@0 68 import org.xml.sax.SAXException;
aoqi@0 69
aoqi@0 70 import javax.xml.namespace.QName;
aoqi@0 71 import javax.xml.soap.SOAPException;
aoqi@0 72 import javax.xml.soap.SOAPMessage;
aoqi@0 73 import javax.xml.stream.XMLStreamWriter;
aoqi@0 74 import javax.xml.stream.XMLStreamException;
aoqi@0 75 import javax.xml.ws.BindingProvider;
aoqi@0 76 import javax.xml.ws.Dispatch;
aoqi@0 77 import javax.xml.ws.WebServiceContext;
aoqi@0 78 import javax.xml.ws.WebServiceException;
aoqi@0 79 import javax.xml.ws.handler.LogicalMessageContext;
aoqi@0 80 import javax.xml.ws.handler.MessageContext;
aoqi@0 81 import javax.xml.ws.handler.soap.SOAPMessageContext;
aoqi@0 82 import javax.xml.ws.soap.MTOMFeature;
aoqi@0 83
aoqi@0 84 import java.util.*;
aoqi@0 85 import java.util.logging.Logger;
aoqi@0 86 import java.io.ByteArrayOutputStream;
aoqi@0 87 import java.io.IOException;
aoqi@0 88 import java.io.OutputStream;
aoqi@0 89 import java.nio.channels.WritableByteChannel;
aoqi@0 90
aoqi@0 91 /**
aoqi@0 92 * Represents a container of a {@link Message}.
aoqi@0 93 *
aoqi@0 94 * <h2>What is a {@link Packet}?</h2>
aoqi@0 95 * <p>
aoqi@0 96 * A packet can be thought of as a frame/envelope/package that wraps
aoqi@0 97 * a {@link Message}. A packet keeps track of optional metadata (properties)
aoqi@0 98 * about a {@link Message} that doesn't go across the wire.
aoqi@0 99 * This roughly corresponds to {@link MessageContext} in the JAX-WS API.
aoqi@0 100 *
aoqi@0 101 * <p>
aoqi@0 102 * Usually a packet contains a {@link Message} in it, but sometimes
aoqi@0 103 * (such as for a reply of an one-way operation), a packet may
aoqi@0 104 * float around without a {@link Message} in it.
aoqi@0 105 *
aoqi@0 106 *
aoqi@0 107 * <a name="properties"></a>
aoqi@0 108 * <h2>Properties</h2>
aoqi@0 109 * <p>
aoqi@0 110 * Information frequently used inside the JAX-WS RI
aoqi@0 111 * is stored in the strongly-typed fields. Other information is stored
aoqi@0 112 * in terms of a generic {@link Map} (see
aoqi@0 113 * {@link #invocationProperties}.)
aoqi@0 114 *
aoqi@0 115 * <p>
aoqi@0 116 * Some properties need to be retained between request and response,
aoqi@0 117 * some don't. For strongly typed fields, this characteristic is
aoqi@0 118 * statically known for each of them, and propagation happens accordingly.
aoqi@0 119 * For generic information stored in {@link Map}, {@link #invocationProperties}
aoqi@0 120 * stores per-invocation scope information (which carries over to
aoqi@0 121 * the response.)
aoqi@0 122 *
aoqi@0 123 * <p>
aoqi@0 124 * This object is used as the backing store of {@link MessageContext}, and
aoqi@0 125 * {@link LogicalMessageContext} and {@link SOAPMessageContext} will
aoqi@0 126 * be delegating to this object for storing/retrieving values.
aoqi@0 127 *
aoqi@0 128 *
aoqi@0 129 * <h3>Relationship to request/response context</h3>
aoqi@0 130 * <p>
aoqi@0 131 * {@link BindingProvider#getRequestContext() Request context} is used to
aoqi@0 132 * seed the initial values of {@link Packet}.
aoqi@0 133 * Some of those values go to strongly-typed fields, and others go to
aoqi@0 134 * {@link #invocationProperties}, as they need to be retained in the reply message.
aoqi@0 135 *
aoqi@0 136 * <p>
aoqi@0 137 * Similarly, {@link BindingProvider#getResponseContext() response context}
aoqi@0 138 * is constructed from {@link Packet} (or rather it's just a view of {@link Packet}.)
aoqi@0 139 * by using properties from {@link #invocationProperties},
aoqi@0 140 * modulo properties named explicitly in {@link #getHandlerScopePropertyNames(boolean)}.
aoqi@0 141 * IOW, properties added to {@link #invocationProperties}
aoqi@0 142 * are exposed to the response context by default.
aoqi@0 143 *
aoqi@0 144 *
aoqi@0 145 *
aoqi@0 146 * <h3>TODO</h3>
aoqi@0 147 * <ol>
aoqi@0 148 * <li>this class needs to be cloneable since Message is copiable.
aoqi@0 149 * <li>The three live views aren't implemented correctly. It will be
aoqi@0 150 * more work to do so, although I'm sure it's possible.
aoqi@0 151 * <li>{@link PropertySet.Property} annotation is to make it easy
aoqi@0 152 * for {@link MessageContext} to export properties on this object,
aoqi@0 153 * but it probably needs some clean up.
aoqi@0 154 * </ol>
aoqi@0 155 *
aoqi@0 156 * @author Kohsuke Kawaguchi
aoqi@0 157 */
aoqi@0 158 public final class Packet
aoqi@0 159 // Packet must continue to extend/implement deprecated interfaces until downstream
aoqi@0 160 // usage is updated.
aoqi@0 161 extends com.oracle.webservices.internal.api.message.BaseDistributedPropertySet
aoqi@0 162 implements com.oracle.webservices.internal.api.message.MessageContext, MessageMetadata {
aoqi@0 163
aoqi@0 164 /**
aoqi@0 165 * Creates a {@link Packet} that wraps a given {@link Message}.
aoqi@0 166 *
aoqi@0 167 * <p>
aoqi@0 168 * This method should be only used to create a fresh {@link Packet}.
aoqi@0 169 * To create a {@link Packet} for a reply, use {@link #createResponse(Message)}.
aoqi@0 170 *
aoqi@0 171 * @param request
aoqi@0 172 * The request {@link Message}. Can be null.
aoqi@0 173 */
aoqi@0 174 public Packet(Message request) {
aoqi@0 175 this();
aoqi@0 176 this.message = request;
aoqi@0 177 if (message != null) message.setMessageMedadata(this);
aoqi@0 178 }
aoqi@0 179
aoqi@0 180 /**
aoqi@0 181 * Creates an empty {@link Packet} that doesn't have any {@link Message}.
aoqi@0 182 */
aoqi@0 183 public Packet() {
aoqi@0 184 this.invocationProperties = new HashMap<String, Object>();
aoqi@0 185 }
aoqi@0 186
aoqi@0 187 /**
aoqi@0 188 * Used by {@link #createResponse(Message)} and {@link #copy(boolean)}.
aoqi@0 189 */
aoqi@0 190 private Packet(Packet that) {
aoqi@0 191 relatePackets(that, true);
aoqi@0 192 this.invocationProperties = that.invocationProperties;
aoqi@0 193 }
aoqi@0 194
aoqi@0 195 /**
aoqi@0 196 * Creates a copy of this {@link Packet}.
aoqi@0 197 *
aoqi@0 198 * @param copyMessage determines whether the {@link Message} from the original {@link Packet} should be copied as
aoqi@0 199 * well, or not. If the value is {@code false}, the {@link Message} in the copy of the {@link Packet} is {@code null}.
aoqi@0 200 * @return copy of the original packet
aoqi@0 201 */
aoqi@0 202 public Packet copy(boolean copyMessage) {
aoqi@0 203 // the copy constructor is originally designed for creating a response packet,
aoqi@0 204 // but so far the implementation is usable for this purpose as well, so calling the copy constructor
aoqi@0 205 // to avoid code dupliation.
aoqi@0 206 Packet copy = new Packet(this);
aoqi@0 207 if (copyMessage && this.message != null) {
aoqi@0 208 copy.message = this.message.copy();
aoqi@0 209 }
aoqi@0 210 if (copy.message != null) copy.message.setMessageMedadata(copy);
aoqi@0 211 return copy;
aoqi@0 212 }
aoqi@0 213
aoqi@0 214 private Message message;
aoqi@0 215
aoqi@0 216 /**
aoqi@0 217 * Gets the last {@link Message} set through {@link #setMessage(Message)}.
aoqi@0 218 *
aoqi@0 219 * @return may null. See the class javadoc for when it's null.
aoqi@0 220 */
aoqi@0 221 public Message getMessage() {
aoqi@0 222 if (message != null && !(message instanceof MessageWrapper)) {
aoqi@0 223 message = new MessageWrapper(this, message);
aoqi@0 224 }
aoqi@0 225 return message;
aoqi@0 226 }
aoqi@0 227
aoqi@0 228 public Message getInternalMessage() {
aoqi@0 229 return (message instanceof MessageWrapper)? ((MessageWrapper)message).delegate : message;
aoqi@0 230 }
aoqi@0 231
aoqi@0 232 public WSBinding getBinding() {
aoqi@0 233 if (endpoint != null) {
aoqi@0 234 return endpoint.getBinding();
aoqi@0 235 }
aoqi@0 236 if (proxy != null) {
aoqi@0 237 return (WSBinding) proxy.getBinding();
aoqi@0 238 }
aoqi@0 239 return null;
aoqi@0 240 }
aoqi@0 241 /**
aoqi@0 242 * Sets a {@link Message} to this packet.
aoqi@0 243 *
aoqi@0 244 * @param message Can be null.
aoqi@0 245 */
aoqi@0 246 public void setMessage(Message message) {
aoqi@0 247 this.message = message;
aoqi@0 248 if (message != null) this.message.setMessageMedadata(this);
aoqi@0 249 }
aoqi@0 250
aoqi@0 251 private WSDLOperationMapping wsdlOperationMapping = null;
aoqi@0 252
aoqi@0 253 private QName wsdlOperation;
aoqi@0 254
aoqi@0 255 /**
aoqi@0 256 * Returns the QName of the wsdl operation associated with this packet.
aoqi@0 257 * <p/>
aoqi@0 258 * Information such as Payload QName, wsa:Action header, SOAPAction HTTP header are used depending on the features
aoqi@0 259 * enabled on the particular port.
aoqi@0 260 *
aoqi@0 261 * @return null if there is no WSDL model or
aoqi@0 262 * runtime cannot uniquely identify the wsdl operation from the information in the packet.
aoqi@0 263 */
aoqi@0 264 @Property(MessageContext.WSDL_OPERATION)
aoqi@0 265 public final
aoqi@0 266 @Nullable
aoqi@0 267 QName getWSDLOperation() {
aoqi@0 268 if (wsdlOperation != null) return wsdlOperation;
aoqi@0 269 if ( wsdlOperationMapping == null) wsdlOperationMapping = getWSDLOperationMapping();
aoqi@0 270 if ( wsdlOperationMapping != null ) wsdlOperation = wsdlOperationMapping.getOperationName();
aoqi@0 271 return wsdlOperation;
aoqi@0 272 }
aoqi@0 273
aoqi@0 274 public WSDLOperationMapping getWSDLOperationMapping() {
aoqi@0 275 if (wsdlOperationMapping != null) return wsdlOperationMapping;
aoqi@0 276 OperationDispatcher opDispatcher = null;
aoqi@0 277 if (endpoint != null) {
aoqi@0 278 opDispatcher = endpoint.getOperationDispatcher();
aoqi@0 279 } else if (proxy != null) {
aoqi@0 280 opDispatcher = ((Stub) proxy).getOperationDispatcher();
aoqi@0 281 }
aoqi@0 282 //OpDispatcher is null when there is no WSDLModel
aoqi@0 283 if (opDispatcher != null) {
aoqi@0 284 try {
aoqi@0 285 wsdlOperationMapping = opDispatcher.getWSDLOperationMapping(this);
aoqi@0 286 } catch (DispatchException e) {
aoqi@0 287 //Ignore, this might be a protocol message which may not have a wsdl operation
aoqi@0 288 //LOGGER.info("Cannot resolve wsdl operation that this Packet is targeted for.");
aoqi@0 289 }
aoqi@0 290 }
aoqi@0 291 return wsdlOperationMapping;
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 /**
aoqi@0 295 * Set the wsdl operation to avoid lookup from other data.
aoqi@0 296 * This is useful in SEI based clients, where the WSDL operation can be known
aoqi@0 297 * from the associated {@link JavaMethod}
aoqi@0 298 *
aoqi@0 299 * @param wsdlOp QName
aoqi@0 300 */
aoqi@0 301 public void setWSDLOperation(QName wsdlOp) {
aoqi@0 302 this.wsdlOperation = wsdlOp;
aoqi@0 303 }
aoqi@0 304
aoqi@0 305 /**
aoqi@0 306 * True if this message came from a transport (IOW inbound),
aoqi@0 307 * and in paricular from a "secure" transport. A transport
aoqi@0 308 * needs to set this flag appropriately.
aoqi@0 309 *
aoqi@0 310 * <p>
aoqi@0 311 * This is a requirement from the security team.
aoqi@0 312 */
aoqi@0 313 // TODO: expose this as a property
aoqi@0 314 public boolean wasTransportSecure;
aoqi@0 315
aoqi@0 316 /**
aoqi@0 317 * Inbound transport headers are captured in a transport neutral way.
aoqi@0 318 * Transports are expected to fill this data after creating a Packet.
aoqi@0 319 * <p>
aoqi@0 320 * {@link SOAPMessage#getMimeHeaders()} would return these headers.
aoqi@0 321 */
aoqi@0 322 public static final String INBOUND_TRANSPORT_HEADERS = "com.sun.xml.internal.ws.api.message.packet.inbound.transport.headers";
aoqi@0 323
aoqi@0 324 /**
aoqi@0 325 * Outbound transport headers are captured in a transport neutral way.
aoqi@0 326 *
aoqi@0 327 * <p>
aoqi@0 328 * Transports may choose to ignore certain headers that interfere with
aoqi@0 329 * its correct operation, such as
aoqi@0 330 * <tt>Content-Type</tt> and <tt>Content-Length</tt>.
aoqi@0 331 */
aoqi@0 332 public static final String OUTBOUND_TRANSPORT_HEADERS = "com.sun.xml.internal.ws.api.message.packet.outbound.transport.headers";
aoqi@0 333
aoqi@0 334 /**
aoqi@0 335 *
aoqi@0 336 */
aoqi@0 337 public static final String HA_INFO = "com.sun.xml.internal.ws.api.message.packet.hainfo";
aoqi@0 338
aoqi@0 339
aoqi@0 340 /**
aoqi@0 341 * This property holds the snapshot of HandlerConfiguration
aoqi@0 342 * at the time of invocation.
aoqi@0 343 * This property is used by MUPipe and HandlerPipe implementations.
aoqi@0 344 */
aoqi@0 345 @Property(BindingProviderProperties.JAXWS_HANDLER_CONFIG)
aoqi@0 346 public HandlerConfiguration handlerConfig;
aoqi@0 347
aoqi@0 348 /**
aoqi@0 349 * If a message originates from a proxy stub that implements
aoqi@0 350 * a port interface, this field is set to point to that object.
aoqi@0 351 *
aoqi@0 352 * TODO: who's using this property?
aoqi@0 353 */
aoqi@0 354 @Property(BindingProviderProperties.JAXWS_CLIENT_HANDLE_PROPERTY)
aoqi@0 355 public BindingProvider proxy;
aoqi@0 356
aoqi@0 357 /**
aoqi@0 358 * Determines if the governing {@link Adapter} or {@link com.sun.xml.internal.ws.api.pipe.Fiber.CompletionCallback}
aoqi@0 359 * will handle delivering response messages targeted at non-anonymous endpoint
aoqi@0 360 * addresses. Prior to the introduction of this flag
aoqi@0 361 * the {@link WsaServerTube} would deliver non-anonymous responses.
aoqi@0 362 */
aoqi@0 363 public boolean isAdapterDeliversNonAnonymousResponse;
aoqi@0 364
aoqi@0 365 /**
aoqi@0 366 * During invocation of a client Stub or Dispatch a Packet is
aoqi@0 367 * created then the Stub's RequestContext is copied into the
aoqi@0 368 * Packet. On certain internal cases the Packet is created
aoqi@0 369 * *before* the invocation. In those cases we want the contents
aoqi@0 370 * of the Packet to take precedence when ever any key/value pairs
aoqi@0 371 * collide : if the Packet contains a value for a key use it,
aoqi@0 372 * otherwise copy as usual from Stub.
aoqi@0 373 */
aoqi@0 374 public boolean packetTakesPriorityOverRequestContext = false;
aoqi@0 375
aoqi@0 376 /**
aoqi@0 377 * The endpoint address to which this message is sent to.
aoqi@0 378 *
aoqi@0 379 * <p>
aoqi@0 380 * The JAX-WS spec allows this to be changed for each message,
aoqi@0 381 * so it's designed to be a property.
aoqi@0 382 *
aoqi@0 383 * <p>
aoqi@0 384 * Must not be null for a request message on the client. Otherwise
aoqi@0 385 * it's null.
aoqi@0 386 */
aoqi@0 387 public EndpointAddress endpointAddress;
aoqi@0 388
aoqi@0 389 /**
aoqi@0 390 * @deprecated
aoqi@0 391 * The programatic acccess should be done via
aoqi@0 392 * {@link #endpointAddress}. This is for JAX-WS client applications
aoqi@0 393 * that access this property via {@link BindingProvider#ENDPOINT_ADDRESS_PROPERTY}.
aoqi@0 394 */
aoqi@0 395 @Property(BindingProvider.ENDPOINT_ADDRESS_PROPERTY)
aoqi@0 396 public String getEndPointAddressString() {
aoqi@0 397 if (endpointAddress == null) {
aoqi@0 398 return null;
aoqi@0 399 } else {
aoqi@0 400 return endpointAddress.toString();
aoqi@0 401 }
aoqi@0 402 }
aoqi@0 403
aoqi@0 404 public void setEndPointAddressString(String s) {
aoqi@0 405 if (s == null) {
aoqi@0 406 this.endpointAddress = null;
aoqi@0 407 } else {
aoqi@0 408 this.endpointAddress = EndpointAddress.create(s);
aoqi@0 409 }
aoqi@0 410 }
aoqi@0 411
aoqi@0 412 /**
aoqi@0 413 * The value of {@link ContentNegotiation#PROPERTY}
aoqi@0 414 * property.
aoqi@0 415 * <p/>
aoqi@0 416 * This property is used only on the client side.
aoqi@0 417 */
aoqi@0 418 public ContentNegotiation contentNegotiation;
aoqi@0 419
aoqi@0 420 @Property(ContentNegotiation.PROPERTY)
aoqi@0 421 public String getContentNegotiationString() {
aoqi@0 422 return (contentNegotiation != null) ? contentNegotiation.toString() : null;
aoqi@0 423 }
aoqi@0 424
aoqi@0 425 public void setContentNegotiationString(String s) {
aoqi@0 426 if (s == null) {
aoqi@0 427 contentNegotiation = null;
aoqi@0 428 } else {
aoqi@0 429 try {
aoqi@0 430 contentNegotiation = ContentNegotiation.valueOf(s);
aoqi@0 431 } catch (IllegalArgumentException e) {
aoqi@0 432 // If the value is not recognized default to none
aoqi@0 433 contentNegotiation = ContentNegotiation.none;
aoqi@0 434 }
aoqi@0 435 }
aoqi@0 436 }
aoqi@0 437
aoqi@0 438 /**
aoqi@0 439 * Gives a list of Reference Parameters in the Message
aoqi@0 440 * <p>
aoqi@0 441 * Headers which have attribute wsa:IsReferenceParameter="true"
aoqi@0 442 * This is not cached as one may reset the Message.
aoqi@0 443 *<p>
aoqi@0 444 */
aoqi@0 445 @Property(MessageContext.REFERENCE_PARAMETERS)
aoqi@0 446 public
aoqi@0 447 @NotNull
aoqi@0 448 List<Element> getReferenceParameters() {
aoqi@0 449 Message msg = getMessage();
aoqi@0 450 List<Element> refParams = new ArrayList<Element>();
aoqi@0 451 if (msg == null) {
aoqi@0 452 return refParams;
aoqi@0 453 }
aoqi@0 454 MessageHeaders hl = msg.getHeaders();
aoqi@0 455 for (Header h : hl.asList()) {
aoqi@0 456 String attr = h.getAttribute(AddressingVersion.W3C.nsUri, "IsReferenceParameter");
aoqi@0 457 if (attr != null && (attr.equals("true") || attr.equals("1"))) {
aoqi@0 458 Document d = DOMUtil.createDom();
aoqi@0 459 SAX2DOMEx s2d = new SAX2DOMEx(d);
aoqi@0 460 try {
aoqi@0 461 h.writeTo(s2d, XmlUtil.DRACONIAN_ERROR_HANDLER);
aoqi@0 462 refParams.add((Element) d.getLastChild());
aoqi@0 463 } catch (SAXException e) {
aoqi@0 464 throw new WebServiceException(e);
aoqi@0 465 }
aoqi@0 466 /*
aoqi@0 467 DOMResult result = new DOMResult(d);
aoqi@0 468 XMLDOMWriterImpl domwriter = new XMLDOMWriterImpl(result);
aoqi@0 469 try {
aoqi@0 470 h.writeTo(domwriter);
aoqi@0 471 refParams.add((Element) result.getNode().getLastChild());
aoqi@0 472 } catch (XMLStreamException e) {
aoqi@0 473 throw new WebServiceException(e);
aoqi@0 474 }
aoqi@0 475 */
aoqi@0 476 }
aoqi@0 477 }
aoqi@0 478 return refParams;
aoqi@0 479 }
aoqi@0 480
aoqi@0 481 /**
aoqi@0 482 * This method is for exposing header list through {@link PropertySet#get(Object)},
aoqi@0 483 * for user applications, and should never be invoked directly from within the JAX-WS RI.
aoqi@0 484 */
aoqi@0 485 @Property(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)
aoqi@0 486 /*package*/ MessageHeaders getHeaderList() {
aoqi@0 487 Message msg = getMessage();
aoqi@0 488 if (msg == null) {
aoqi@0 489 return null;
aoqi@0 490 }
aoqi@0 491 return msg.getHeaders();
aoqi@0 492 }
aoqi@0 493
aoqi@0 494 /**
aoqi@0 495 * The list of MIME types that are acceptable to a receiver
aoqi@0 496 * of an outbound message.
aoqi@0 497 *
aoqi@0 498 * This property is used only on the server side.
aoqi@0 499 *
aoqi@0 500 * <p>The representation shall be that specified by the HTTP Accept
aoqi@0 501 * request-header field.
aoqi@0 502 *
aoqi@0 503 * <p>The list of content types will be obtained from the transport
aoqi@0 504 * meta-data of a inbound message in a request/response message exchange.
aoqi@0 505 * Hence this property will be set by the service-side transport pipe.
aoqi@0 506 */
aoqi@0 507 public String acceptableMimeTypes;
aoqi@0 508
aoqi@0 509 /**
aoqi@0 510 * When non-null, this object is consulted to
aoqi@0 511 * implement {@link WebServiceContext} methods
aoqi@0 512 * exposed to the user application.
aoqi@0 513 *
aoqi@0 514 * Used only on the server side.
aoqi@0 515 *
aoqi@0 516 * <p>
aoqi@0 517 * This property is set from the parameter
aoqi@0 518 * of {@link WSEndpoint.PipeHead#process}.
aoqi@0 519 */
aoqi@0 520 public WebServiceContextDelegate webServiceContextDelegate;
aoqi@0 521
aoqi@0 522 /**
aoqi@0 523 * Used only on the server side so that the transport
aoqi@0 524 * can close the connection early.
aoqi@0 525 *
aoqi@0 526 * <p>
aoqi@0 527 * This field can be null. While a message is being processed,
aoqi@0 528 * this field can be set explicitly to null, to prevent
aoqi@0 529 * future pipes from closing a transport (see {@link #keepTransportBackChannelOpen()})
aoqi@0 530 *
aoqi@0 531 * <p>
aoqi@0 532 * This property is set from the parameter
aoqi@0 533 * of {@link WSEndpoint.PipeHead#process}.
aoqi@0 534 */
aoqi@0 535 public
aoqi@0 536 @Nullable
aoqi@0 537 TransportBackChannel transportBackChannel;
aoqi@0 538
aoqi@0 539 /**
aoqi@0 540 * Keeps the transport back channel open (by seeting {@link #transportBackChannel} to null.)
aoqi@0 541 *
aoqi@0 542 * @return
aoqi@0 543 * The previous value of {@link #transportBackChannel}.
aoqi@0 544 */
aoqi@0 545 public TransportBackChannel keepTransportBackChannelOpen() {
aoqi@0 546 TransportBackChannel r = transportBackChannel;
aoqi@0 547 transportBackChannel = null;
aoqi@0 548 return r;
aoqi@0 549 }
aoqi@0 550
aoqi@0 551 /**
aoqi@0 552 * The governing owner of this packet. On the service-side this is the {@link Adapter} and on the client it is the {@link Stub}.
aoqi@0 553 *
aoqi@0 554 */
aoqi@0 555 public Component component;
aoqi@0 556
aoqi@0 557 /**
aoqi@0 558 * The governing {@link WSEndpoint} in which this message is floating.
aoqi@0 559 *
aoqi@0 560 * <p>
aoqi@0 561 * This property is set if and only if this is on the server side.
aoqi@0 562 */
aoqi@0 563 @Property(JAXWSProperties.WSENDPOINT)
aoqi@0 564 public WSEndpoint endpoint;
aoqi@0 565
aoqi@0 566 /**
aoqi@0 567 * The value of the SOAPAction header associated with the message.
aoqi@0 568 *
aoqi@0 569 * <p>
aoqi@0 570 * For outgoing messages, the transport may sends out this value.
aoqi@0 571 * If this field is null, the transport may choose to send <tt>""</tt>
aoqi@0 572 * (quoted empty string.)
aoqi@0 573 *
aoqi@0 574 * For incoming messages, the transport will set this field.
aoqi@0 575 * If the incoming message did not contain the SOAPAction header,
aoqi@0 576 * the transport sets this field to null.
aoqi@0 577 *
aoqi@0 578 * <p>
aoqi@0 579 * If the value is non-null, it must be always in the quoted form.
aoqi@0 580 * The value can be null.
aoqi@0 581 *
aoqi@0 582 * <p>
aoqi@0 583 * Note that the way the transport sends this value out depends on
aoqi@0 584 * transport and SOAP version.
aoqi@0 585 * <p/>
aoqi@0 586 * For HTTP transport and SOAP 1.1, BP requires that SOAPAction
aoqi@0 587 * header is present (See {@BP R2744} and {@BP R2745}.) For SOAP 1.2,
aoqi@0 588 * this is moved to the parameter of the "application/soap+xml".
aoqi@0 589 */
aoqi@0 590 @Property(BindingProvider.SOAPACTION_URI_PROPERTY)
aoqi@0 591 public String soapAction;
aoqi@0 592
aoqi@0 593 /**
aoqi@0 594 * A hint indicating that whether a transport should expect
aoqi@0 595 * a reply back from the server.
aoqi@0 596 *
aoqi@0 597 * <p>
aoqi@0 598 * This property is used on the client-side for
aoqi@0 599 * outbound messages, so that a pipeline
aoqi@0 600 * can communicate to the terminal (or intermediate) {@link Tube}s
aoqi@0 601 * about this knowledge.
aoqi@0 602 *
aoqi@0 603 * <p>
aoqi@0 604 * This property <b>MUST NOT</b> be used by 2-way transports
aoqi@0 605 * that have the transport back channel. Those transports
aoqi@0 606 * must always check a reply coming through the transport back
aoqi@0 607 * channel regardless of this value, and act accordingly.
aoqi@0 608 * (This is because the expectation of the client and
aoqi@0 609 * that of the server can be different, for example because
aoqi@0 610 * of a bug in user's configuration.)
aoqi@0 611 *
aoqi@0 612 * <p>
aoqi@0 613 * This property is for one-way transports, and more
aoqi@0 614 * specifically for the coordinator that correlates sent requests
aoqi@0 615 * and incoming replies, to decide whether to block
aoqi@0 616 * until a response is received.
aoqi@0 617 *
aoqi@0 618 * <p>
aoqi@0 619 * Also note that this property is related to
aoqi@0 620 * {@link WSDLOperation#isOneWay()} but not the same thing.
aoqi@0 621 * In fact in general, they are completely orthogonal.
aoqi@0 622 *
aoqi@0 623 * For example, the calling application can choose to invoke
aoqi@0 624 * {@link Dispatch#invoke(Object)} or {@link Dispatch#invokeOneWay(Object)}
aoqi@0 625 * with an operation (which determines the value of this property),
aoqi@0 626 * regardless of whether WSDL actually says it's one way or not.
aoqi@0 627 * So these two booleans can take any combinations.
aoqi@0 628 *
aoqi@0 629 *
aoqi@0 630 * <p>
aoqi@0 631 * When this property is {@link Boolean#FALSE}, it means that
aoqi@0 632 * the pipeline does not expect a reply from a server (and therefore
aoqi@0 633 * the correlator should not block for a reply message
aoqi@0 634 * -- if such a reply does arrive, it can be just ignored.)
aoqi@0 635 *
aoqi@0 636 * <p>
aoqi@0 637 * When this property is {@link Boolean#TRUE}, it means that
aoqi@0 638 * the pipeline expects a reply from a server (and therefore
aoqi@0 639 * the correlator should block to see if a reply message is received,
aoqi@0 640 *
aoqi@0 641 * <p>
aoqi@0 642 * This property is always set to {@link Boolean#TRUE} or
aoqi@0 643 * {@link Boolean#FALSE} when used on the request message
aoqi@0 644 * on the client side.
aoqi@0 645 * No other {@link Boolean} instances are allowed.
aoqi@0 646 * <p>
aoqi@0 647 *
aoqi@0 648 * In all other situations, this property is null.
aoqi@0 649 *
aoqi@0 650 */
aoqi@0 651 @Property(BindingProviderProperties.ONE_WAY_OPERATION)
aoqi@0 652 public Boolean expectReply;
aoqi@0 653
aoqi@0 654
aoqi@0 655 /**
aoqi@0 656 * This property will be removed in a near future.
aoqi@0 657 *
aoqi@0 658 * <p>
aoqi@0 659 * A part of what this flag represented moved to
aoqi@0 660 * {@link #expectReply} and the other part was moved
aoqi@0 661 * to {@link Message#isOneWay(WSDLPort)}. Please update
aoqi@0 662 * your code soon, or risk breaking your build!!
aoqi@0 663 */
aoqi@0 664 @Deprecated
aoqi@0 665 public Boolean isOneWay;
aoqi@0 666
aoqi@0 667 /**
aoqi@0 668 * Indicates whether is invoking a synchronous pattern. If true, no
aoqi@0 669 * async client programming model (e.g. AsyncResponse or AsyncHandler)
aoqi@0 670 * were used to make the request that created this packet.
aoqi@0 671 */
aoqi@0 672 public Boolean isSynchronousMEP;
aoqi@0 673
aoqi@0 674 /**
aoqi@0 675 * Indicates whether a non-null AsyncHandler was given at the point of
aoqi@0 676 * making the request that created this packet. This flag can be used
aoqi@0 677 * by Tube implementations to decide how to react when isSynchronousMEP
aoqi@0 678 * is false. If true, the client gave a non-null AsyncHandler instance
aoqi@0 679 * at the point of request, and will be expecting a response on that
aoqi@0 680 * handler when this request has been processed.
aoqi@0 681 */
aoqi@0 682 public Boolean nonNullAsyncHandlerGiven;
aoqi@0 683
aoqi@0 684 /**
aoqi@0 685 * USE-CASE:
aoqi@0 686 * WS-AT is enabled, but there is no WSDL available.
aoqi@0 687 * If Packet.isRequestReplyMEP() is Boolean.TRUE then WS-AT should
aoqi@0 688 * add the TX context.
aoqi@0 689 *
aoqi@0 690 * This value is exposed to users via facades at higher abstraction layers.
aoqi@0 691 * The user should NEVER use Packet directly.
aoqi@0 692 * This value should ONLY be set by users.
aoqi@0 693 */
aoqi@0 694 private Boolean isRequestReplyMEP;
aoqi@0 695 public Boolean isRequestReplyMEP() { return isRequestReplyMEP; }
aoqi@0 696 public void setRequestReplyMEP(final Boolean x) { isRequestReplyMEP = x; }
aoqi@0 697
aoqi@0 698 /**
aoqi@0 699 * Lazily created set of handler-scope property names.
aoqi@0 700 *
aoqi@0 701 * <p>
aoqi@0 702 * We expect that this is only used when handlers are present
aoqi@0 703 * and they explicitly set some handler-scope values.
aoqi@0 704 *
aoqi@0 705 * @see #getHandlerScopePropertyNames(boolean)
aoqi@0 706 */
aoqi@0 707 private Set<String> handlerScopePropertyNames;
aoqi@0 708
aoqi@0 709 /**
aoqi@0 710 * Bag to capture properties that are available for the whole
aoqi@0 711 * message invocation (namely on both requests and responses.)
aoqi@0 712 *
aoqi@0 713 * <p>
aoqi@0 714 * These properties are copied from a request to a response.
aoqi@0 715 * This is where we keep properties that are set by handlers.
aoqi@0 716 *
aoqi@0 717 * <p>
aoqi@0 718 * See <a href="#properties">class javadoc</a> for more discussion.
aoqi@0 719 *
aoqi@0 720 * @see #getHandlerScopePropertyNames(boolean)
aoqi@0 721 */
aoqi@0 722 public final Map<String, Object> invocationProperties;
aoqi@0 723
aoqi@0 724 /**
aoqi@0 725 * Gets a {@link Set} that stores handler-scope properties.
aoqi@0 726 *
aoqi@0 727 * <p>
aoqi@0 728 * These properties will not be exposed to the response context.
aoqi@0 729 * Consequently, if a {@link Tube} wishes to hide a property
aoqi@0 730 * to {@link ResponseContext}, it needs to add the property name
aoqi@0 731 * to this set.
aoqi@0 732 *
aoqi@0 733 * @param readOnly
aoqi@0 734 * Return true if the caller only intends to read the value of this set.
aoqi@0 735 * Internally, the {@link Set} is allocated lazily, and this flag helps
aoqi@0 736 * optimizing the strategy.
aoqi@0 737 *
aoqi@0 738 * @return
aoqi@0 739 * always non-null, possibly empty set that stores property names.
aoqi@0 740 */
aoqi@0 741 public final Set<String> getHandlerScopePropertyNames(boolean readOnly) {
aoqi@0 742 Set<String> o = this.handlerScopePropertyNames;
aoqi@0 743 if (o == null) {
aoqi@0 744 if (readOnly) {
aoqi@0 745 return Collections.emptySet();
aoqi@0 746 }
aoqi@0 747 o = new HashSet<String>();
aoqi@0 748 this.handlerScopePropertyNames = o;
aoqi@0 749 }
aoqi@0 750 return o;
aoqi@0 751 }
aoqi@0 752
aoqi@0 753 /**
aoqi@0 754 * This method no longer works.
aoqi@0 755 *
aoqi@0 756 * @deprecated
aoqi@0 757 * Use {@link #getHandlerScopePropertyNames(boolean)}.
aoqi@0 758 * To be removed once Tango components are updated.
aoqi@0 759 */
aoqi@0 760 public final Set<String> getApplicationScopePropertyNames(boolean readOnly) {
aoqi@0 761 assert false;
aoqi@0 762 return new HashSet<String>();
aoqi@0 763 }
aoqi@0 764
aoqi@0 765 /**
aoqi@0 766 * Creates a response {@link Packet} from a request packet ({@code this}).
aoqi@0 767 *
aoqi@0 768 * <p>
aoqi@0 769 * When a {@link Packet} for a reply is created, some properties need to be
aoqi@0 770 * copied over from a request to a response, and this method handles it correctly.
aoqi@0 771 *
aoqi@0 772 * @deprecated
aoqi@0 773 * Use createClientResponse(Message) for client side and
aoqi@0 774 * createServerResponse(Message, String) for server side response
aoqi@0 775 * creation.
aoqi@0 776 *
aoqi@0 777 * @param msg
aoqi@0 778 * The {@link Message} that represents a reply. Can be null.
aoqi@0 779 */
aoqi@0 780 @Deprecated
aoqi@0 781 public Packet createResponse(Message msg) {
aoqi@0 782 Packet response = new Packet(this);
aoqi@0 783 response.setMessage(msg);
aoqi@0 784 return response;
aoqi@0 785 }
aoqi@0 786
aoqi@0 787 /**
aoqi@0 788 * Creates a response {@link Packet} from a request packet ({@code this}).
aoqi@0 789 *
aoqi@0 790 * <p>
aoqi@0 791 * When a {@link Packet} for a reply is created, some properties need to be
aoqi@0 792 * copied over from a request to a response, and this method handles it correctly.
aoqi@0 793 *
aoqi@0 794 * @param msg
aoqi@0 795 * The {@link Message} that represents a reply. Can be null.
aoqi@0 796 */
aoqi@0 797 public Packet createClientResponse(Message msg) {
aoqi@0 798 Packet response = new Packet(this);
aoqi@0 799 response.setMessage(msg);
aoqi@0 800 finishCreateRelateClientResponse(response);
aoqi@0 801 return response;
aoqi@0 802 }
aoqi@0 803
aoqi@0 804 /**
aoqi@0 805 * For use cases that start with an existing Packet.
aoqi@0 806 */
aoqi@0 807 public Packet relateClientResponse(final Packet response) {
aoqi@0 808 response.relatePackets(this, true);
aoqi@0 809 finishCreateRelateClientResponse(response);
aoqi@0 810 return response;
aoqi@0 811 }
aoqi@0 812
aoqi@0 813 private void finishCreateRelateClientResponse(final Packet response) {
aoqi@0 814 response.soapAction = null; // de-initializing
aoqi@0 815 response.setState(State.ClientResponse);
aoqi@0 816 }
aoqi@0 817
aoqi@0 818 /**
aoqi@0 819 * Creates a server-side response {@link Packet} from a request
aoqi@0 820 * packet ({@code this}). If WS-Addressing is enabled, a default Action
aoqi@0 821 * Message Addressing Property is obtained using <code>wsdlPort</code> {@link WSDLPort}
aoqi@0 822 * and <code>binding</code> {@link WSBinding}.
aoqi@0 823 * <p><p>
aoqi@0 824 * This method should be called to create application response messages
aoqi@0 825 * since they are associated with a {@link WSBinding} and {@link WSDLPort}.
aoqi@0 826 * For creating protocol messages that require a non-default Action, use
aoqi@0 827 * {@link #createServerResponse(Message, com.sun.xml.internal.ws.api.addressing.AddressingVersion, com.sun.xml.internal.ws.api.SOAPVersion, String)}.
aoqi@0 828 *
aoqi@0 829 * @param responseMessage The {@link Message} that represents a reply. Can be null.
aoqi@0 830 * @param wsdlPort The response WSDL port.
aoqi@0 831 * @param binding The response Binding. Cannot be null.
aoqi@0 832 * @return response packet
aoqi@0 833 */
aoqi@0 834 public Packet createServerResponse(@Nullable Message responseMessage, @Nullable WSDLPort wsdlPort, @Nullable SEIModel seiModel, @NotNull WSBinding binding) {
aoqi@0 835 Packet r = createClientResponse(responseMessage);
aoqi@0 836 return relateServerResponse(r, wsdlPort, seiModel, binding);
aoqi@0 837 }
aoqi@0 838
aoqi@0 839 /**
aoqi@0 840 * Copy all properties from ({@code this}) packet into a input {@link Packet}
aoqi@0 841 * @param response packet
aoqi@0 842 */
aoqi@0 843 public void copyPropertiesTo(@Nullable Packet response){
aoqi@0 844 relatePackets(response, false);
aoqi@0 845 }
aoqi@0 846
aoqi@0 847
aoqi@0 848 /**
aoqi@0 849 * A common method to make members related between input packet and this packet
aoqi@0 850 *
aoqi@0 851 * @param packet
aoqi@0 852 * @param isCopy 'true' means copying all properties from input packet;
aoqi@0 853 * 'false' means copying all properties from this packet to input packet.
aoqi@0 854 */
aoqi@0 855 private void relatePackets(@Nullable Packet packet, boolean isCopy)
aoqi@0 856 {
aoqi@0 857 Packet request;
aoqi@0 858 Packet response;
aoqi@0 859
aoqi@0 860 if (!isCopy) { //is relate
aoqi@0 861 request = this;
aoqi@0 862 response = packet;
aoqi@0 863
aoqi@0 864 // processing specific properties
aoqi@0 865 response.soapAction = null;
aoqi@0 866 response.invocationProperties.putAll(request.invocationProperties);
aoqi@0 867 if (this.getState().equals(State.ServerRequest)) {
aoqi@0 868 response.setState(State.ServerResponse);
aoqi@0 869 }
aoqi@0 870 } else { //is copy constructor
aoqi@0 871 request = packet;
aoqi@0 872 response = this;
aoqi@0 873
aoqi@0 874 // processing specific properties
aoqi@0 875 response.soapAction = request.soapAction;
aoqi@0 876 response.setState(request.getState());
aoqi@0 877 }
aoqi@0 878
aoqi@0 879 request.copySatelliteInto(response);
aoqi@0 880 response.isAdapterDeliversNonAnonymousResponse = request.isAdapterDeliversNonAnonymousResponse;
aoqi@0 881 response.handlerConfig = request.handlerConfig;
aoqi@0 882 response.handlerScopePropertyNames = request.handlerScopePropertyNames;
aoqi@0 883 response.contentNegotiation = request.contentNegotiation;
aoqi@0 884 response.wasTransportSecure = request.wasTransportSecure;
aoqi@0 885 response.transportBackChannel = request.transportBackChannel;
aoqi@0 886 response.endpointAddress = request.endpointAddress;
aoqi@0 887 response.wsdlOperation = request.wsdlOperation;
aoqi@0 888 response.wsdlOperationMapping = request.wsdlOperationMapping;
aoqi@0 889 response.acceptableMimeTypes = request.acceptableMimeTypes;
aoqi@0 890 response.endpoint = request.endpoint;
aoqi@0 891 response.proxy = request.proxy;
aoqi@0 892 response.webServiceContextDelegate = request.webServiceContextDelegate;
aoqi@0 893 response.expectReply = request.expectReply;
aoqi@0 894 response.component = request.component;
aoqi@0 895 response.mtomAcceptable = request.mtomAcceptable;
aoqi@0 896 response.mtomRequest = request.mtomRequest;
aoqi@0 897 // copy other properties that need to be copied. is there any?
aoqi@0 898 }
aoqi@0 899
aoqi@0 900
aoqi@0 901 public Packet relateServerResponse(@Nullable Packet r, @Nullable WSDLPort wsdlPort, @Nullable SEIModel seiModel, @NotNull WSBinding binding) {
aoqi@0 902 relatePackets(r, false);
aoqi@0 903 r.setState(State.ServerResponse);
aoqi@0 904 AddressingVersion av = binding.getAddressingVersion();
aoqi@0 905 // populate WS-A headers only if WS-A is enabled
aoqi@0 906 if (av == null) {
aoqi@0 907 return r;
aoqi@0 908 }
aoqi@0 909
aoqi@0 910 if (getMessage() == null) {
aoqi@0 911 return r;
aoqi@0 912 }
aoqi@0 913
aoqi@0 914 //populate WS-A headers only if the request has addressing headers
aoqi@0 915 String inputAction = AddressingUtils.getAction(getMessage().getHeaders(), av, binding.getSOAPVersion());
aoqi@0 916 if (inputAction == null) {
aoqi@0 917 return r;
aoqi@0 918 }
aoqi@0 919 // if one-way, then dont populate any WS-A headers
aoqi@0 920 if (r.getMessage() == null || (wsdlPort != null && getMessage().isOneWay(wsdlPort))) {
aoqi@0 921 return r;
aoqi@0 922 }
aoqi@0 923
aoqi@0 924 // otherwise populate WS-Addressing headers
aoqi@0 925 populateAddressingHeaders(binding, r, wsdlPort, seiModel);
aoqi@0 926 return r;
aoqi@0 927 }
aoqi@0 928
aoqi@0 929 /**
aoqi@0 930 * Creates a server-side response {@link Packet} from a request
aoqi@0 931 * packet ({@code this}). If WS-Addressing is enabled, <code>action</code>
aoqi@0 932 * is used as Action Message Addressing Property.
aoqi@0 933 * <p><p>
aoqi@0 934 * This method should be called only for creating protocol response messages
aoqi@0 935 * that require a particular value of Action since they are not associated
aoqi@0 936 * with a {@link WSBinding} and {@link WSDLPort} but do know the {@link AddressingVersion}
aoqi@0 937 * and {@link SOAPVersion}.
aoqi@0 938 *
aoqi@0 939 * @param responseMessage The {@link Message} that represents a reply. Can be null.
aoqi@0 940 * @param addressingVersion The WS-Addressing version of the response message.
aoqi@0 941 * @param soapVersion The SOAP version of the response message.
aoqi@0 942 * @param action The response Action Message Addressing Property value.
aoqi@0 943 * @return response packet
aoqi@0 944 */
aoqi@0 945 public Packet createServerResponse(@Nullable Message responseMessage, @NotNull AddressingVersion addressingVersion, @NotNull SOAPVersion soapVersion, @NotNull String action) {
aoqi@0 946 Packet responsePacket = createClientResponse(responseMessage);
aoqi@0 947 responsePacket.setState(State.ServerResponse);
aoqi@0 948 // populate WS-A headers only if WS-A is enabled
aoqi@0 949 if (addressingVersion == null) {
aoqi@0 950 return responsePacket;
aoqi@0 951 }
aoqi@0 952 //populate WS-A headers only if the request has addressing headers
aoqi@0 953 String inputAction = AddressingUtils.getAction(this.getMessage().getHeaders(), addressingVersion, soapVersion);
aoqi@0 954 if (inputAction == null) {
aoqi@0 955 return responsePacket;
aoqi@0 956 }
aoqi@0 957
aoqi@0 958 populateAddressingHeaders(responsePacket, addressingVersion, soapVersion, action, false);
aoqi@0 959 return responsePacket;
aoqi@0 960 }
aoqi@0 961
aoqi@0 962 /**
aoqi@0 963 * Overwrites the {@link Message} of the response packet ({@code this}) by the given {@link Message}.
aoqi@0 964 * Unlike {@link #setMessage(Message)}, fill in the addressing headers correctly, and this process
aoqi@0 965 * requires the access to the request packet.
aoqi@0 966 *
aoqi@0 967 * <p>
aoqi@0 968 * This method is useful when the caller needs to swap a response message completely to a new one.
aoqi@0 969 *
aoqi@0 970 * @see #createServerResponse(Message, AddressingVersion, SOAPVersion, String)
aoqi@0 971 */
aoqi@0 972 public void setResponseMessage(@NotNull Packet request, @Nullable Message responseMessage, @NotNull AddressingVersion addressingVersion, @NotNull SOAPVersion soapVersion, @NotNull String action) {
aoqi@0 973 Packet temp = request.createServerResponse(responseMessage, addressingVersion, soapVersion, action);
aoqi@0 974 setMessage(temp.getMessage());
aoqi@0 975 }
aoqi@0 976
aoqi@0 977 private void populateAddressingHeaders(Packet responsePacket, AddressingVersion av, SOAPVersion sv, String action, boolean mustUnderstand) {
aoqi@0 978 // populate WS-A headers only if WS-A is enabled
aoqi@0 979 if (av == null) return;
aoqi@0 980
aoqi@0 981 // if one-way, then dont populate any WS-A headers
aoqi@0 982 if (responsePacket.getMessage() == null)
aoqi@0 983 return;
aoqi@0 984
aoqi@0 985 MessageHeaders hl = responsePacket.getMessage().getHeaders();
aoqi@0 986
aoqi@0 987 WsaPropertyBag wpb = getSatellite(WsaPropertyBag.class);
aoqi@0 988 Message msg = getMessage();
aoqi@0 989 // wsa:To
aoqi@0 990 WSEndpointReference replyTo = null;
aoqi@0 991 Header replyToFromRequestMsg = AddressingUtils.getFirstHeader(msg.getHeaders(), av.replyToTag, true, sv);
aoqi@0 992 Header replyToFromResponseMsg = hl.get(av.toTag, false);
aoqi@0 993 boolean replaceToTag = true;
aoqi@0 994 try{
aoqi@0 995 if (replyToFromRequestMsg != null){
aoqi@0 996 replyTo = replyToFromRequestMsg.readAsEPR(av);
aoqi@0 997 }
aoqi@0 998 if (replyToFromResponseMsg != null && replyTo == null) {
aoqi@0 999 replaceToTag = false;
aoqi@0 1000 }
aoqi@0 1001 } catch (XMLStreamException e) {
aoqi@0 1002 throw new WebServiceException(AddressingMessages.REPLY_TO_CANNOT_PARSE(), e);
aoqi@0 1003 }
aoqi@0 1004 if (replyTo == null) {
aoqi@0 1005 replyTo = AddressingUtils.getReplyTo(msg.getHeaders(), av, sv);
aoqi@0 1006 }
aoqi@0 1007
aoqi@0 1008 // wsa:Action, add if the message doesn't already contain it,
aoqi@0 1009 // generally true for SEI case where there is SEIModel or WSDLModel
aoqi@0 1010 // false for Provider with no wsdl, Expects User to set the coresponding header on the Message.
aoqi@0 1011 if (AddressingUtils.getAction(responsePacket.getMessage().getHeaders(), av, sv) == null) {
aoqi@0 1012 //wsa:Action header is not set in the message, so use the wsa:Action passed as the parameter.
aoqi@0 1013 hl.add(new StringHeader(av.actionTag, action, sv, mustUnderstand));
aoqi@0 1014 }
aoqi@0 1015
aoqi@0 1016 // wsa:MessageID
aoqi@0 1017 if (responsePacket.getMessage().getHeaders().get(av.messageIDTag, false) == null) {
aoqi@0 1018 // if header doesn't exist, method getID creates a new random id
aoqi@0 1019 String newID = Message.generateMessageID();
aoqi@0 1020 hl.add(new StringHeader(av.messageIDTag, newID));
aoqi@0 1021 }
aoqi@0 1022
aoqi@0 1023 // wsa:RelatesTo
aoqi@0 1024 String mid = null;
aoqi@0 1025 if (wpb != null) {
aoqi@0 1026 mid = wpb.getMessageID();
aoqi@0 1027 }
aoqi@0 1028 if (mid == null) {
aoqi@0 1029 mid = AddressingUtils.getMessageID(msg.getHeaders(), av, sv);
aoqi@0 1030 }
aoqi@0 1031 if (mid != null) {
aoqi@0 1032 hl.addOrReplace(new RelatesToHeader(av.relatesToTag, mid));
aoqi@0 1033 }
aoqi@0 1034
aoqi@0 1035
aoqi@0 1036 // populate reference parameters
aoqi@0 1037 WSEndpointReference refpEPR = null;
aoqi@0 1038 if (responsePacket.getMessage().isFault()) {
aoqi@0 1039 // choose FaultTo
aoqi@0 1040 if (wpb != null) {
aoqi@0 1041 refpEPR = wpb.getFaultToFromRequest();
aoqi@0 1042 }
aoqi@0 1043 if (refpEPR == null) {
aoqi@0 1044 refpEPR = AddressingUtils.getFaultTo(msg.getHeaders(), av, sv);
aoqi@0 1045 }
aoqi@0 1046 // if FaultTo is null, then use ReplyTo
aoqi@0 1047 if (refpEPR == null) {
aoqi@0 1048 refpEPR = replyTo;
aoqi@0 1049 }
aoqi@0 1050 } else {
aoqi@0 1051 // choose ReplyTo
aoqi@0 1052 refpEPR = replyTo;
aoqi@0 1053 }
aoqi@0 1054 if (replaceToTag && refpEPR != null) {
aoqi@0 1055 hl.addOrReplace(new StringHeader(av.toTag, refpEPR.getAddress()));
aoqi@0 1056 refpEPR.addReferenceParametersToList(hl);
aoqi@0 1057 }
aoqi@0 1058 }
aoqi@0 1059
aoqi@0 1060 private void populateAddressingHeaders(WSBinding binding, Packet responsePacket, WSDLPort wsdlPort, SEIModel seiModel) {
aoqi@0 1061 AddressingVersion addressingVersion = binding.getAddressingVersion();
aoqi@0 1062
aoqi@0 1063 if (addressingVersion == null) {
aoqi@0 1064 return;
aoqi@0 1065 }
aoqi@0 1066
aoqi@0 1067 WsaTubeHelper wsaHelper = addressingVersion.getWsaHelper(wsdlPort, seiModel, binding);
aoqi@0 1068 String action = responsePacket.getMessage().isFault() ?
aoqi@0 1069 wsaHelper.getFaultAction(this, responsePacket) :
aoqi@0 1070 wsaHelper.getOutputAction(this);
aoqi@0 1071 if (action == null) {
aoqi@0 1072 LOGGER.info("WSA headers are not added as value for wsa:Action cannot be resolved for this message");
aoqi@0 1073 return;
aoqi@0 1074 }
aoqi@0 1075 populateAddressingHeaders(responsePacket, addressingVersion, binding.getSOAPVersion(), action, AddressingVersion.isRequired(binding));
aoqi@0 1076 }
aoqi@0 1077
aoqi@0 1078 public String toShortString() {
aoqi@0 1079 return super.toString();
aoqi@0 1080 }
aoqi@0 1081
aoqi@0 1082 // For use only in a debugger
aoqi@0 1083 @Override
aoqi@0 1084 public String toString() {
aoqi@0 1085 StringBuilder buf = new StringBuilder();
aoqi@0 1086 buf.append(super.toString());
aoqi@0 1087 String content;
aoqi@0 1088 try {
aoqi@0 1089 Message msg = getMessage();
aoqi@0 1090 if (msg != null) {
aoqi@0 1091 ByteArrayOutputStream baos = new ByteArrayOutputStream();
aoqi@0 1092 XMLStreamWriter xmlWriter = XMLStreamWriterFactory.create(baos, "UTF-8");
aoqi@0 1093 msg.copy().writeTo(xmlWriter);
aoqi@0 1094 xmlWriter.flush();
aoqi@0 1095 xmlWriter.close();
aoqi@0 1096 baos.flush();
aoqi@0 1097 XMLStreamWriterFactory.recycle(xmlWriter);
aoqi@0 1098
aoqi@0 1099 byte[] bytes = baos.toByteArray();
aoqi@0 1100 //message = Messages.create(XMLStreamReaderFactory.create(null, new ByteArrayInputStream(bytes), "UTF-8", true));
aoqi@0 1101 content = new String(bytes, "UTF-8");
aoqi@0 1102 } else {
aoqi@0 1103 content = "<none>";
aoqi@0 1104 }
aoqi@0 1105 } catch (Throwable t) {
aoqi@0 1106 throw new WebServiceException(t);
aoqi@0 1107 }
aoqi@0 1108 buf.append(" Content: ").append(content);
aoqi@0 1109 return buf.toString();
aoqi@0 1110 }
aoqi@0 1111
aoqi@0 1112 // completes TypedMap
aoqi@0 1113 private static final PropertyMap model;
aoqi@0 1114
aoqi@0 1115 static {
aoqi@0 1116 model = parse(Packet.class);
aoqi@0 1117 }
aoqi@0 1118
aoqi@0 1119 @Override
aoqi@0 1120 protected PropertyMap getPropertyMap() {
aoqi@0 1121 return model;
aoqi@0 1122 }
aoqi@0 1123
aoqi@0 1124 public Map<String, Object> asMapIncludingInvocationProperties() {
aoqi@0 1125 final Map<String, Object> asMap = asMap();
aoqi@0 1126 return new AbstractMap<String, Object>() {
aoqi@0 1127 @Override
aoqi@0 1128 public Object get(Object key) {
aoqi@0 1129 Object o = asMap.get(key);
aoqi@0 1130 if (o != null)
aoqi@0 1131 return o;
aoqi@0 1132
aoqi@0 1133 return invocationProperties.get(key);
aoqi@0 1134 }
aoqi@0 1135
aoqi@0 1136 @Override
aoqi@0 1137 public int size() {
aoqi@0 1138 return asMap.size() + invocationProperties.size();
aoqi@0 1139 }
aoqi@0 1140
aoqi@0 1141 @Override
aoqi@0 1142 public boolean containsKey(Object key) {
aoqi@0 1143 if (asMap.containsKey(key))
aoqi@0 1144 return true;
aoqi@0 1145 return invocationProperties.containsKey(key);
aoqi@0 1146 }
aoqi@0 1147
aoqi@0 1148 @Override
aoqi@0 1149 public Set<Entry<String, Object>> entrySet() {
aoqi@0 1150 final Set<Entry<String, Object>> asMapEntries = asMap.entrySet();
aoqi@0 1151 final Set<Entry<String, Object>> ipEntries = invocationProperties.entrySet();
aoqi@0 1152
aoqi@0 1153 return new AbstractSet<Entry<String, Object>>() {
aoqi@0 1154 @Override
aoqi@0 1155 public Iterator<Entry<String, Object>> iterator() {
aoqi@0 1156 final Iterator<Entry<String, Object>> asMapIt = asMapEntries.iterator();
aoqi@0 1157 final Iterator<Entry<String, Object>> ipIt = ipEntries.iterator();
aoqi@0 1158
aoqi@0 1159 return new Iterator<Entry<String, Object>>() {
aoqi@0 1160 @Override
aoqi@0 1161 public boolean hasNext() {
aoqi@0 1162 return asMapIt.hasNext() || ipIt.hasNext();
aoqi@0 1163 }
aoqi@0 1164
aoqi@0 1165 @Override
aoqi@0 1166 public java.util.Map.Entry<String, Object> next() {
aoqi@0 1167 if (asMapIt.hasNext())
aoqi@0 1168 return asMapIt.next();
aoqi@0 1169 return ipIt.next();
aoqi@0 1170 }
aoqi@0 1171
aoqi@0 1172 @Override
aoqi@0 1173 public void remove() {
aoqi@0 1174 throw new UnsupportedOperationException();
aoqi@0 1175 }
aoqi@0 1176 };
aoqi@0 1177 }
aoqi@0 1178
aoqi@0 1179 @Override
aoqi@0 1180 public int size() {
aoqi@0 1181 return asMap.size() + invocationProperties.size();
aoqi@0 1182 }
aoqi@0 1183 };
aoqi@0 1184 }
aoqi@0 1185
aoqi@0 1186 @Override
aoqi@0 1187 public Object put(String key, Object value) {
aoqi@0 1188 if (supports(key))
aoqi@0 1189 return asMap.put(key, value);
aoqi@0 1190
aoqi@0 1191 return invocationProperties.put(key, value);
aoqi@0 1192 }
aoqi@0 1193
aoqi@0 1194 @Override
aoqi@0 1195 public void clear() {
aoqi@0 1196 asMap.clear();
aoqi@0 1197 invocationProperties.clear();
aoqi@0 1198 }
aoqi@0 1199
aoqi@0 1200 @Override
aoqi@0 1201 public Object remove(Object key) {
aoqi@0 1202 if (supports(key))
aoqi@0 1203 return asMap.remove(key);
aoqi@0 1204
aoqi@0 1205 return invocationProperties.remove(key);
aoqi@0 1206 }
aoqi@0 1207 };
aoqi@0 1208 }
aoqi@0 1209
aoqi@0 1210 private static final Logger LOGGER = Logger.getLogger(Packet.class.getName());
aoqi@0 1211
aoqi@0 1212 @Override
aoqi@0 1213 public SOAPMessage getSOAPMessage() throws SOAPException {
aoqi@0 1214 return getAsSOAPMessage();
aoqi@0 1215 }
aoqi@0 1216
aoqi@0 1217 //TODO replace the message to a SAAJMEssage issue - JRFSAAJMessage or SAAJMessage?
aoqi@0 1218 @Override
aoqi@0 1219 public SOAPMessage getAsSOAPMessage() throws SOAPException {
aoqi@0 1220 Message msg = this.getMessage();
aoqi@0 1221 if (msg == null)
aoqi@0 1222 return null;
aoqi@0 1223 if (msg instanceof MessageWritable)
aoqi@0 1224 ((MessageWritable) msg).setMTOMConfiguration(mtomFeature);
aoqi@0 1225 return msg.readAsSOAPMessage(this, this.getState().isInbound());
aoqi@0 1226 }
aoqi@0 1227
aoqi@0 1228 public
aoqi@0 1229 Codec codec = null;
aoqi@0 1230 public Codec getCodec() {
aoqi@0 1231 if (codec != null) {
aoqi@0 1232 return codec;
aoqi@0 1233 }
aoqi@0 1234 if (endpoint != null) {
aoqi@0 1235 codec = endpoint.createCodec();
aoqi@0 1236 }
aoqi@0 1237 WSBinding wsb = getBinding();
aoqi@0 1238 if (wsb != null) {
aoqi@0 1239 codec = wsb.getBindingId().createEncoder(wsb);
aoqi@0 1240 }
aoqi@0 1241 return codec;
aoqi@0 1242 }
aoqi@0 1243
aoqi@0 1244 @Override
aoqi@0 1245 public com.oracle.webservices.internal.api.message.ContentType writeTo( OutputStream out ) throws IOException {
aoqi@0 1246 Message msg = getInternalMessage();
aoqi@0 1247 if (msg instanceof MessageWritable) {
aoqi@0 1248 ((MessageWritable) msg).setMTOMConfiguration(mtomFeature);
aoqi@0 1249 return ((MessageWritable)msg).writeTo(out);
aoqi@0 1250 }
aoqi@0 1251 return getCodec().encode(this, out);
aoqi@0 1252 }
aoqi@0 1253
aoqi@0 1254 public com.oracle.webservices.internal.api.message.ContentType writeTo( WritableByteChannel buffer ) {
aoqi@0 1255 return getCodec().encode(this, buffer);
aoqi@0 1256 }
aoqi@0 1257
aoqi@0 1258 private ContentType contentType;
aoqi@0 1259
aoqi@0 1260 /**
aoqi@0 1261 * If the request's Content-Type is multipart/related; type=application/xop+xml, then this set to to true
aoqi@0 1262 *
aoqi@0 1263 * Used on server-side, for encoding the repsonse.
aoqi@0 1264 */
aoqi@0 1265 private Boolean mtomRequest;
aoqi@0 1266
aoqi@0 1267 /**
aoqi@0 1268 * Based on request's Accept header this is set.
aoqi@0 1269 * Currently only set if MTOMFeature is enabled.
aoqi@0 1270 *
aoqi@0 1271 * Should be used on server-side, for encoding the response.
aoqi@0 1272 */
aoqi@0 1273 private Boolean mtomAcceptable;
aoqi@0 1274
aoqi@0 1275 private MTOMFeature mtomFeature;
aoqi@0 1276
aoqi@0 1277 public Boolean getMtomRequest() {
aoqi@0 1278 return mtomRequest;
aoqi@0 1279 }
aoqi@0 1280
aoqi@0 1281 public void setMtomRequest(Boolean mtomRequest) {
aoqi@0 1282 this.mtomRequest = mtomRequest;
aoqi@0 1283 }
aoqi@0 1284
aoqi@0 1285 public Boolean getMtomAcceptable() {
aoqi@0 1286 return mtomAcceptable;
aoqi@0 1287 }
aoqi@0 1288
aoqi@0 1289 Boolean checkMtomAcceptable;
aoqi@0 1290 public void checkMtomAcceptable() {
aoqi@0 1291 if (checkMtomAcceptable == null) {
aoqi@0 1292 if (acceptableMimeTypes == null || isFastInfosetDisabled) {
aoqi@0 1293 checkMtomAcceptable = false;
aoqi@0 1294 } else {
aoqi@0 1295 checkMtomAcceptable = (acceptableMimeTypes.indexOf(MtomCodec.XOP_XML_MIME_TYPE) != -1);
aoqi@0 1296 // StringTokenizer st = new StringTokenizer(acceptableMimeTypes, ",");
aoqi@0 1297 // while (st.hasMoreTokens()) {
aoqi@0 1298 // final String token = st.nextToken().trim();
aoqi@0 1299 // if (token.toLowerCase().contains(MtomCodec.XOP_XML_MIME_TYPE)) {
aoqi@0 1300 // mtomAcceptable = true;
aoqi@0 1301 // }
aoqi@0 1302 // }
aoqi@0 1303 // if (mtomAcceptable == null) mtomAcceptable = false;
aoqi@0 1304 }
aoqi@0 1305 }
aoqi@0 1306 mtomAcceptable = checkMtomAcceptable;
aoqi@0 1307 }
aoqi@0 1308
aoqi@0 1309 private Boolean fastInfosetAcceptable;
aoqi@0 1310
aoqi@0 1311 public Boolean getFastInfosetAcceptable(String fiMimeType) {
aoqi@0 1312 if (fastInfosetAcceptable == null) {
aoqi@0 1313 if (acceptableMimeTypes == null || isFastInfosetDisabled) {
aoqi@0 1314 fastInfosetAcceptable = false;
aoqi@0 1315 } else {
aoqi@0 1316 fastInfosetAcceptable = (acceptableMimeTypes.indexOf(fiMimeType) != -1);
aoqi@0 1317 }
aoqi@0 1318 // if (accept == null || isFastInfosetDisabled) return false;
aoqi@0 1319 //
aoqi@0 1320 // StringTokenizer st = new StringTokenizer(accept, ",");
aoqi@0 1321 // while (st.hasMoreTokens()) {
aoqi@0 1322 // final String token = st.nextToken().trim();
aoqi@0 1323 // if (token.equalsIgnoreCase(fiMimeType)) {
aoqi@0 1324 // return true;
aoqi@0 1325 // }
aoqi@0 1326 // }
aoqi@0 1327 // return false;
aoqi@0 1328 }
aoqi@0 1329 return fastInfosetAcceptable;
aoqi@0 1330 }
aoqi@0 1331
aoqi@0 1332
aoqi@0 1333 public void setMtomFeature(MTOMFeature mtomFeature) {
aoqi@0 1334 this.mtomFeature = mtomFeature;
aoqi@0 1335 }
aoqi@0 1336
aoqi@0 1337 public MTOMFeature getMtomFeature() {
aoqi@0 1338 //If we have a binding, use that in preference to an explicitly
aoqi@0 1339 //set MTOMFeature
aoqi@0 1340 WSBinding binding = getBinding();
aoqi@0 1341 if (binding != null) {
aoqi@0 1342 return binding.getFeature(MTOMFeature.class);
aoqi@0 1343 }
aoqi@0 1344 return mtomFeature;
aoqi@0 1345 }
aoqi@0 1346
aoqi@0 1347 @Override
aoqi@0 1348 public com.oracle.webservices.internal.api.message.ContentType getContentType() {
aoqi@0 1349 if (contentType == null) {
aoqi@0 1350 contentType = getInternalContentType();
aoqi@0 1351 }
aoqi@0 1352 if (contentType == null) {
aoqi@0 1353 contentType = getCodec().getStaticContentType(this);
aoqi@0 1354 }
aoqi@0 1355 if (contentType == null) {
aoqi@0 1356 //TODO write to buffer
aoqi@0 1357 }
aoqi@0 1358 return contentType;
aoqi@0 1359 }
aoqi@0 1360
aoqi@0 1361 public ContentType getInternalContentType() {
aoqi@0 1362 Message msg = getInternalMessage();
aoqi@0 1363 if (msg instanceof MessageWritable) {
aoqi@0 1364 return ((MessageWritable)msg).getContentType();
aoqi@0 1365 }
aoqi@0 1366 return contentType;
aoqi@0 1367 }
aoqi@0 1368
aoqi@0 1369 public void setContentType(ContentType contentType) {
aoqi@0 1370 this.contentType = contentType;
aoqi@0 1371 }
aoqi@0 1372
aoqi@0 1373 public enum Status {
aoqi@0 1374 Request, Response, Unknown;
aoqi@0 1375 public boolean isRequest() { return Request.equals(this); }
aoqi@0 1376 public boolean isResponse() { return Response.equals(this); }
aoqi@0 1377 }
aoqi@0 1378
aoqi@0 1379 public enum State {
aoqi@0 1380 ServerRequest(true), ClientRequest(false), ServerResponse(false), ClientResponse(true);
aoqi@0 1381 private boolean inbound;
aoqi@0 1382 State(boolean inbound) {
aoqi@0 1383 this.inbound = inbound;
aoqi@0 1384 }
aoqi@0 1385 public boolean isInbound() {
aoqi@0 1386 return inbound;
aoqi@0 1387 }
aoqi@0 1388 }
aoqi@0 1389
aoqi@0 1390 // private Status status = Status.Unknown;
aoqi@0 1391
aoqi@0 1392 //Default state is ServerRequest - some custom adapters may not set the value of state
aoqi@0 1393 //upon server request - all other code paths should set it
aoqi@0 1394 private State state = State.ServerRequest;
aoqi@0 1395
aoqi@0 1396 // public Status getStatus() { return status; }
aoqi@0 1397
aoqi@0 1398 public State getState() { return state; }
aoqi@0 1399 public void setState(State state) { this.state = state; }
aoqi@0 1400
aoqi@0 1401 public boolean shouldUseMtom() {
aoqi@0 1402 if (getState().isInbound()) {
aoqi@0 1403 return isMtomContentType();
aoqi@0 1404 } else {
aoqi@0 1405 return shouldUseMtomOutbound();
aoqi@0 1406 }
aoqi@0 1407 }
aoqi@0 1408
aoqi@0 1409 private boolean shouldUseMtomOutbound() {
aoqi@0 1410 //Use the getter to make sure all the logic is executed correctly
aoqi@0 1411 MTOMFeature myMtomFeature = getMtomFeature();
aoqi@0 1412 if(myMtomFeature != null && myMtomFeature.isEnabled()) {
aoqi@0 1413 //On client, always use XOP encoding if MTOM is enabled
aoqi@0 1414 //On Server, mtomAcceptable and mtomRequest will be set - use XOP encoding
aoqi@0 1415 //if either request is XOP encoded (mtomRequest) or
aoqi@0 1416 //client accepts XOP encoding (mtomAcceptable)
aoqi@0 1417 if (getMtomAcceptable() == null && getMtomRequest() == null) {
aoqi@0 1418 return true;
aoqi@0 1419 } else {
aoqi@0 1420 if (getMtomAcceptable() != null && getMtomAcceptable() && getState().equals(State.ServerResponse)) {
aoqi@0 1421 return true;
aoqi@0 1422 }
aoqi@0 1423 if (getMtomRequest() != null && getMtomRequest() && getState().equals(State.ServerResponse)) {
aoqi@0 1424 return true;
aoqi@0 1425 }
aoqi@0 1426 if (getMtomRequest() != null && getMtomRequest() && getState().equals(State.ClientRequest)) {
aoqi@0 1427 return true;
aoqi@0 1428 }
aoqi@0 1429 }
aoqi@0 1430 }
aoqi@0 1431 return false;
aoqi@0 1432 }
aoqi@0 1433
aoqi@0 1434 private boolean isMtomContentType() {
aoqi@0 1435 return (getInternalContentType() != null) &&
aoqi@0 1436 (getInternalContentType().getContentType().contains("application/xop+xml"));
aoqi@0 1437 }
aoqi@0 1438
aoqi@0 1439 /**
aoqi@0 1440 * @deprecated
aoqi@0 1441 */
aoqi@0 1442 public void addSatellite(@NotNull com.sun.xml.internal.ws.api.PropertySet satellite) {
aoqi@0 1443 super.addSatellite(satellite);
aoqi@0 1444 }
aoqi@0 1445
aoqi@0 1446 /**
aoqi@0 1447 * @deprecated
aoqi@0 1448 */
aoqi@0 1449 public void addSatellite(@NotNull Class keyClass, @NotNull com.sun.xml.internal.ws.api.PropertySet satellite) {
aoqi@0 1450 super.addSatellite(keyClass, satellite);
aoqi@0 1451 }
aoqi@0 1452
aoqi@0 1453 /**
aoqi@0 1454 * @deprecated
aoqi@0 1455 */
aoqi@0 1456 public void copySatelliteInto(@NotNull com.sun.xml.internal.ws.api.DistributedPropertySet r) {
aoqi@0 1457 super.copySatelliteInto(r);
aoqi@0 1458 }
aoqi@0 1459
aoqi@0 1460 /**
aoqi@0 1461 * @deprecated
aoqi@0 1462 */
aoqi@0 1463 public void removeSatellite(com.sun.xml.internal.ws.api.PropertySet satellite) {
aoqi@0 1464 super.removeSatellite(satellite);
aoqi@0 1465 }
aoqi@0 1466
aoqi@0 1467 /**
aoqi@0 1468 * This is propogated from SOAPBindingCodec and will affect isMtomAcceptable and isFastInfosetAcceptable
aoqi@0 1469 */
aoqi@0 1470 private boolean isFastInfosetDisabled;
aoqi@0 1471
aoqi@0 1472 public void setFastInfosetDisabled(boolean b) {
aoqi@0 1473 isFastInfosetDisabled = b;
aoqi@0 1474 }
aoqi@0 1475 }

mercurial