| /* |
| * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Sun designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Sun in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| * CA 95054 USA or visit www.sun.com if you need additional information or |
| * have any questions. |
| */ |
| package com.sun.xml.internal.ws.api.message; |
| |
| import com.sun.istack.internal.NotNull; |
| import com.sun.istack.internal.Nullable; |
| import com.sun.xml.internal.bind.marshaller.SAX2DOMEx; |
| import com.sun.xml.internal.ws.addressing.WsaTubeHelper; |
| import com.sun.xml.internal.ws.addressing.model.InvalidMapException; |
| import com.sun.xml.internal.ws.api.DistributedPropertySet; |
| import com.sun.xml.internal.ws.api.EndpointAddress; |
| import com.sun.xml.internal.ws.api.PropertySet; |
| import com.sun.xml.internal.ws.api.SOAPVersion; |
| import com.sun.xml.internal.ws.api.WSBinding; |
| import com.sun.xml.internal.ws.api.addressing.AddressingVersion; |
| import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; |
| import com.sun.xml.internal.ws.api.model.wsdl.WSDLOperation; |
| import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; |
| import com.sun.xml.internal.ws.api.model.SEIModel; |
| import com.sun.xml.internal.ws.api.pipe.Tube; |
| import com.sun.xml.internal.ws.api.server.TransportBackChannel; |
| import com.sun.xml.internal.ws.api.server.WSEndpoint; |
| import com.sun.xml.internal.ws.api.server.WebServiceContextDelegate; |
| import com.sun.xml.internal.ws.client.BindingProviderProperties; |
| import com.sun.xml.internal.ws.client.ContentNegotiation; |
| import com.sun.xml.internal.ws.client.HandlerConfiguration; |
| import com.sun.xml.internal.ws.client.ResponseContext; |
| import com.sun.xml.internal.ws.developer.JAXWSProperties; |
| import com.sun.xml.internal.ws.message.RelatesToHeader; |
| import com.sun.xml.internal.ws.message.StringHeader; |
| import com.sun.xml.internal.ws.util.DOMUtil; |
| import com.sun.xml.internal.ws.util.xml.XmlUtil; |
| import com.sun.xml.internal.ws.model.JavaMethodImpl; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.xml.sax.SAXException; |
| |
| import javax.xml.soap.SOAPMessage; |
| import javax.xml.ws.BindingProvider; |
| import javax.xml.ws.Dispatch; |
| import javax.xml.ws.WebServiceContext; |
| import javax.xml.ws.WebServiceException; |
| import javax.xml.ws.handler.LogicalMessageContext; |
| import javax.xml.ws.handler.MessageContext; |
| import javax.xml.ws.handler.soap.SOAPMessageContext; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * Represents a container of a {@link Message}. |
| * |
| * <h2>What is a {@link Packet}?</h2> |
| * <p> |
| * A packet can be thought of as a frame/envelope/package that wraps |
| * a {@link Message}. A packet keeps track of optional metadata (properties) |
| * about a {@link Message} that doesn't go across the wire. |
| * This roughly corresponds to {@link MessageContext} in the JAX-WS API. |
| * |
| * <p> |
| * Usually a packet contains a {@link Message} in it, but sometimes |
| * (such as for a reply of an one-way operation), a packet may |
| * float around without a {@link Message} in it. |
| * |
| * |
| * <a name="properties"></a> |
| * <h2>Properties</h2> |
| * <p> |
| * Information frequently used inside the JAX-WS RI |
| * is stored in the strongly-typed fields. Other information is stored |
| * in terms of a generic {@link Map} (see |
| * {@link #invocationProperties}.) |
| * |
| * <p> |
| * Some properties need to be retained between request and response, |
| * some don't. For strongly typed fields, this characteristic is |
| * statically known for each of them, and propagation happens accordingly. |
| * For generic information stored in {@link Map}, {@link #invocationProperties} |
| * stores per-invocation scope information (which carries over to |
| * the response.) |
| * |
| * <p> |
| * This object is used as the backing store of {@link MessageContext}, and |
| * {@link LogicalMessageContext} and {@link SOAPMessageContext} will |
| * be delegating to this object for storing/retrieving values. |
| * |
| * |
| * <h3>Relationship to request/response context</h3> |
| * <p> |
| * {@link BindingProvider#getRequestContext() Request context} is used to |
| * seed the initial values of {@link Packet}. |
| * Some of those values go to strongly-typed fields, and others go to |
| * {@link #invocationProperties}, as they need to be retained in the reply message. |
| * |
| * <p> |
| * Similarly, {@link BindingProvider#getResponseContext() response context} |
| * is constructed from {@link Packet} (or rather it's just a view of {@link Packet}.) |
| * by using properties from {@link #invocationProperties}, |
| * modulo properties named explicitly in {@link #getHandlerScopePropertyNames(boolean)}. |
| * IOW, properties added to {@link #invocationProperties} |
| * are exposed to the response context by default. |
| * |
| * |
| * |
| * <h3>TODO</h3> |
| * <ol> |
| * <li>this class needs to be cloneable since Message is copiable. |
| * <li>The three live views aren't implemented correctly. It will be |
| * more work to do so, although I'm sure it's possible. |
| * <li>{@link Property} annotation is to make it easy |
| * for {@link MessageContext} to export properties on this object, |
| * but it probably needs some clean up. |
| * </ol> |
| * |
| * @author Kohsuke Kawaguchi |
| */ |
| public final class Packet extends DistributedPropertySet { |
| |
| /** |
| * Creates a {@link Packet} that wraps a given {@link Message}. |
| * |
| * <p> |
| * This method should be only used to create a fresh {@link Packet}. |
| * To create a {@link Packet} for a reply, use {@link #createResponse(Message)}. |
| * |
| * @param request |
| * The request {@link Message}. Can be null. |
| */ |
| public Packet(Message request) { |
| this(); |
| this.message = request; |
| } |
| |
| /** |
| * Creates an empty {@link Packet} that doesn't have any {@link Message}. |
| */ |
| public Packet() { |
| this.invocationProperties = new HashMap<String,Object>(); |
| } |
| |
| /** |
| * Used by {@link #createResponse(Message)}. |
| */ |
| private Packet(Packet that) { |
| that.copySatelliteInto(this); |
| this.handlerConfig = that.handlerConfig; |
| this.invocationProperties = that.invocationProperties; |
| this.handlerScopePropertyNames = that.handlerScopePropertyNames; |
| this.contentNegotiation = that.contentNegotiation; |
| this.wasTransportSecure = that.wasTransportSecure; |
| // copy other properties that need to be copied. is there any? |
| } |
| |
| private Message message; |
| |
| /** |
| * Gets the last {@link Message} set through {@link #setMessage(Message)}. |
| * |
| * @return |
| * may null. See the class javadoc for when it's null. |
| */ |
| public Message getMessage() { |
| return message; |
| } |
| |
| /** |
| * Sets a {@link Message} to this packet. |
| * |
| * @param message |
| * Can be null. |
| */ |
| public void setMessage(Message message) { |
| this.message = message; |
| } |
| |
| /** |
| * True if this message came from a transport (IOW inbound), |
| * and in paricular from a "secure" transport. A transport |
| * needs to set this flag appropriately. |
| * |
| * <p> |
| * This is a requirement from the security team. |
| */ |
| // TODO: expose this as a property |
| public boolean wasTransportSecure; |
| |
| /** |
| * Inbound transport headers are captured in a transport neutral way. |
| * Transports are expected to fill this data after creating a Packet. |
| * <p> |
| * {@link SOAPMessage#getMimeHeaders()} would return these headers. |
| * |
| */ |
| public static final String INBOUND_TRANSPORT_HEADERS = "com.sun.xml.internal.ws.api.message.packet.inbound.transport.headers"; |
| |
| /** |
| * Outbound transport headers are captured in a transport neutral way. |
| * |
| * <p> |
| * Transports may choose to ignore certain headers that interfere with |
| * its correct operation, such as |
| * <tt>Content-Type</tt> and <tt>Content-Length</tt>. |
| */ |
| public static final String OUTBOUND_TRANSPORT_HEADERS = "com.sun.xml.internal.ws.api.message.packet.outbound.transport.headers"; |
| |
| |
| /** |
| * This property holds the snapshot of HandlerConfiguration |
| * at the time of invocation. |
| * This property is used by MUPipe and HandlerPipe implementations. |
| */ |
| @Property(BindingProviderProperties.JAXWS_HANDLER_CONFIG) |
| public HandlerConfiguration handlerConfig; |
| |
| /** |
| * If a message originates from a proxy stub that implements |
| * a port interface, this field is set to point to that object. |
| * |
| * TODO: who's using this property? |
| */ |
| @Property(BindingProviderProperties.JAXWS_CLIENT_HANDLE_PROPERTY) |
| public BindingProvider proxy; |
| |
| /** |
| * The endpoint address to which this message is sent to. |
| * |
| * <p> |
| * The JAX-WS spec allows this to be changed for each message, |
| * so it's designed to be a property. |
| * |
| * <p> |
| * Must not be null for a request message on the client. Otherwise |
| * it's null. |
| */ |
| public EndpointAddress endpointAddress; |
| |
| /** |
| * @deprecated |
| * The programatic acccess should be done via |
| * {@link #endpointAddress}. This is for JAX-WS client applications |
| * that access this property via {@link BindingProvider#ENDPOINT_ADDRESS_PROPERTY}. |
| */ |
| @Property(BindingProvider.ENDPOINT_ADDRESS_PROPERTY) |
| public String getEndPointAddressString() { |
| if(endpointAddress==null) |
| return null; |
| else |
| return endpointAddress.toString(); |
| } |
| |
| public void setEndPointAddressString(String s) { |
| if(s==null) |
| this.endpointAddress = null; |
| else |
| this.endpointAddress = EndpointAddress.create(s); |
| } |
| |
| /** |
| * The value of {@link ContentNegotiation#PROPERTY} |
| * property. |
| * |
| * This property is used only on the client side. |
| */ |
| public ContentNegotiation contentNegotiation; |
| |
| @Property(ContentNegotiation.PROPERTY) |
| public String getContentNegotiationString() { |
| return (contentNegotiation != null) ? contentNegotiation.toString() : null; |
| } |
| |
| public void setContentNegotiationString(String s) { |
| if(s==null) |
| contentNegotiation = null; |
| else { |
| try { |
| contentNegotiation = ContentNegotiation.valueOf(s); |
| } catch (IllegalArgumentException e) { |
| // If the value is not recognized default to none |
| contentNegotiation = ContentNegotiation.none; |
| } |
| } |
| } |
| |
| /** |
| * Gives a list of Reference Parameters in the Message |
| * <p> |
| * Headers which have attribute wsa:IsReferenceParameter="true" |
| * This is not cached as one may reset the Message. |
| *<p> |
| */ |
| @Property(MessageContext.REFERENCE_PARAMETERS) |
| public @NotNull List<Element> getReferenceParameters() { |
| List<Element> refParams = new ArrayList<Element>(); |
| HeaderList hl = message.getHeaders(); |
| for(Header h :hl) { |
| String attr = h.getAttribute(AddressingVersion.W3C.nsUri,"IsReferenceParameter"); |
| if(attr!=null && (attr.equals("true") || attr.equals("1"))) { |
| Document d = DOMUtil.createDom(); |
| SAX2DOMEx s2d = new SAX2DOMEx(d); |
| try { |
| h.writeTo(s2d, XmlUtil.DRACONIAN_ERROR_HANDLER); |
| refParams.add((Element) d.getLastChild()); |
| } catch (SAXException e) { |
| throw new WebServiceException(e); |
| } |
| /* |
| DOMResult result = new DOMResult(d); |
| XMLDOMWriterImpl domwriter = new XMLDOMWriterImpl(result); |
| try { |
| h.writeTo(domwriter); |
| refParams.add((Element) result.getNode().getLastChild()); |
| } catch (XMLStreamException e) { |
| throw new WebServiceException(e); |
| } |
| */ |
| } |
| } |
| return refParams; |
| } |
| |
| /** |
| * @deprecated |
| * This method is for exposing header list through {@link PropertySet#get(Object)}, |
| * for user applications, and should never be invoked directly from within the JAX-WS RI. |
| */ |
| @Property(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY) |
| /*package*/ HeaderList getHeaderList() { |
| if(message==null) return null; |
| return message.getHeaders(); |
| } |
| |
| /** |
| * The list of MIME types that are acceptable to a receiver |
| * of an outbound message. |
| * |
| * This property is used only on the server side. |
| * |
| * <p>The representation shall be that specified by the HTTP Accept |
| * request-header field. |
| * |
| * <p>The list of content types will be obtained from the transport |
| * meta-data of a inbound message in a request/response message exchange. |
| * Hence this property will be set by the service-side transport pipe. |
| * |
| */ |
| public String acceptableMimeTypes; |
| |
| /** |
| * When non-null, this object is consulted to |
| * implement {@link WebServiceContext} methods |
| * exposed to the user application. |
| * |
| * Used only on the server side. |
| * |
| * <p> |
| * This property is set from the parameter |
| * of {@link WSEndpoint.PipeHead#process}. |
| */ |
| public WebServiceContextDelegate webServiceContextDelegate; |
| |
| /** |
| * Used only on the server side so that the transport |
| * can close the connection early. |
| * |
| * <p> |
| * This field can be null. While a message is being processed, |
| * this field can be set explicitly to null, to prevent |
| * future pipes from closing a transport. |
| * |
| * <p> |
| * This property is set from the parameter |
| * of {@link WSEndpoint.PipeHead#process}. |
| */ |
| public @Nullable TransportBackChannel transportBackChannel; |
| |
| /** |
| * The governing {@link WSEndpoint} in which this message is floating. |
| * |
| * <p> |
| * This property is set if and only if this is on the server side. |
| */ |
| public WSEndpoint endpoint; |
| |
| /** |
| * The value of the SOAPAction header associated with the message. |
| * |
| * <p> |
| * For outgoing messages, the transport may sends out this value. |
| * If this field is null, the transport may choose to send <tt>""</tt> |
| * (quoted empty string.) |
| * |
| * For incoming messages, the transport will set this field. |
| * If the incoming message did not contain the SOAPAction header, |
| * the transport sets this field to null. |
| * |
| * <p> |
| * If the value is non-null, it must be always in the quoted form. |
| * The value can be null. |
| * |
| * <p> |
| * Note that the way the transport sends this value out depends on |
| * transport and SOAP version. |
| * |
| * For HTTP transport and SOAP 1.1, BP requires that SOAPAction |
| * header is present (See {@BP R2744} and {@BP R2745}.) For SOAP 1.2, |
| * this is moved to the parameter of the "application/soap+xml". |
| */ |
| @Property(BindingProvider.SOAPACTION_URI_PROPERTY) |
| public String soapAction; |
| |
| /** |
| * A hint indicating that whether a transport should expect |
| * a reply back from the server. |
| * |
| * <p> |
| * This property is used on the client-side for |
| * outbound messages, so that a pipeline |
| * can communicate to the terminal (or intermediate) {@link Tube}s |
| * about this knowledge. |
| * |
| * <p> |
| * This property <b>MUST NOT</b> be used by 2-way transports |
| * that have the transport back channel. Those transports |
| * must always check a reply coming through the transport back |
| * channel regardless of this value, and act accordingly. |
| * (This is because the expectation of the client and |
| * that of the server can be different, for example because |
| * of a bug in user's configuration.) |
| * |
| * <p> |
| * This property is for one-way transports, and more |
| * specifically for the coordinator that correlates sent requests |
| * and incoming replies, to decide whether to block |
| * until a response is received. |
| * |
| * <p> |
| * Also note that this property is related to |
| * {@link WSDLOperation#isOneWay()} but not the same thing. |
| * In fact in general, they are completely orthogonal. |
| * |
| * For example, the calling application can choose to invoke |
| * {@link Dispatch#invoke(Object)} or {@link Dispatch#invokeOneWay(Object)} |
| * with an operation (which determines the value of this property), |
| * regardless of whether WSDL actually says it's one way or not. |
| * So these two booleans can take any combinations. |
| * |
| * |
| * <p> |
| * When this property is {@link Boolean#TRUE}, it means that |
| * the pipeline does not expect a reply from a server (and therefore |
| * the correlator should not block for a reply message |
| * -- if such a reply does arrive, it can be just ignored.) |
| * |
| * <p> |
| * When this property is {@link Boolean#FALSE}, it means that |
| * the pipeline expects a reply from a server (and therefore |
| * the correlator should block to see if a reply message is received, |
| * |
| * <p> |
| * This property is always set to {@link Boolean#TRUE} or |
| * {@link Boolean#FALSE} when used on the request message |
| * on the client side. |
| * No other {@link Boolean} instances are allowed. |
| * <p> |
| * |
| * In all other situations, this property is null. |
| * |
| */ |
| @Property(BindingProviderProperties.ONE_WAY_OPERATION) |
| public Boolean expectReply; |
| |
| |
| /** |
| * This property will be removed in a near future. |
| * |
| * <p> |
| * A part of what this flag represented moved to |
| * {@link #expectReply} and the other part was moved |
| * to {@link Message#isOneWay(WSDLPort)}. Please update |
| * your code soon, or risk breaking your build!! |
| */ |
| @Deprecated |
| public Boolean isOneWay; |
| |
| /** |
| * Lazily created set of handler-scope property names. |
| * |
| * <p> |
| * We expect that this is only used when handlers are present |
| * and they explicitly set some handler-scope values. |
| * |
| * @see #getHandlerScopePropertyNames(boolean) |
| */ |
| private Set<String> handlerScopePropertyNames; |
| |
| /** |
| * Bag to capture properties that are available for the whole |
| * message invocation (namely on both requests and responses.) |
| * |
| * <p> |
| * These properties are copied from a request to a response. |
| * This is where we keep properties that are set by handlers. |
| * |
| * <p> |
| * See <a href="#properties">class javadoc</a> for more discussion. |
| * |
| * @see #getHandlerScopePropertyNames(boolean) |
| */ |
| public final Map<String,Object> invocationProperties; |
| |
| /** |
| * Gets a {@link Set} that stores handler-scope properties. |
| * |
| * <p> |
| * These properties will not be exposed to the response context. |
| * Consequently, if a {@link Tube} wishes to hide a property |
| * to {@link ResponseContext}, it needs to add the property name |
| * to this set. |
| * |
| * @param readOnly |
| * Return true if the caller only intends to read the value of this set. |
| * Internally, the {@link Set} is allocated lazily, and this flag helps |
| * optimizing the strategy. |
| * |
| * @return |
| * always non-null, possibly empty set that stores property names. |
| */ |
| public final Set<String> getHandlerScopePropertyNames( boolean readOnly ) { |
| Set<String> o = this.handlerScopePropertyNames; |
| if(o==null) { |
| if(readOnly) |
| return Collections.emptySet(); |
| o = new HashSet<String>(); |
| this.handlerScopePropertyNames = o; |
| } |
| return o; |
| } |
| |
| /** |
| * This method no longer works. |
| * |
| * @deprecated |
| * Use {@link #getHandlerScopePropertyNames(boolean)}. |
| * To be removed once Tango components are updated. |
| */ |
| public final Set<String> getApplicationScopePropertyNames( boolean readOnly ) { |
| assert false; |
| return new HashSet<String>(); |
| } |
| |
| /** |
| * Creates a response {@link Packet} from a request packet ({@code this}). |
| * |
| * <p> |
| * When a {@link Packet} for a reply is created, some properties need to be |
| * copied over from a request to a response, and this method handles it correctly. |
| * |
| * @deprecated |
| * Use createClientResponse(Message) for client side and |
| * createServerResponse(Message, String) for server side response |
| * creation. |
| * |
| * @param msg |
| * The {@link Message} that represents a reply. Can be null. |
| */ |
| @Deprecated |
| public Packet createResponse(Message msg) { |
| Packet response = new Packet(this); |
| response.setMessage(msg); |
| return response; |
| } |
| |
| /** |
| * Creates a response {@link Packet} from a request packet ({@code this}). |
| * |
| * <p> |
| * When a {@link Packet} for a reply is created, some properties need to be |
| * copied over from a request to a response, and this method handles it correctly. |
| * |
| * @param msg |
| * The {@link Message} that represents a reply. Can be null. |
| */ |
| public Packet createClientResponse(Message msg) { |
| Packet response = new Packet(this); |
| response.setMessage(msg); |
| return response; |
| } |
| |
| /** |
| * Creates a server-side response {@link Packet} from a request |
| * packet ({@code this}). If WS-Addressing is enabled, a default Action |
| * Message Addressing Property is obtained using <code>wsdlPort</code> {@link WSDLPort} |
| * and <code>binding</code> {@link WSBinding}. |
| * <p><p> |
| * This method should be called to create application response messages |
| * since they are associated with a {@link WSBinding} and {@link WSDLPort}. |
| * For creating protocol messages that require a non-default Action, use |
| * {@link #createServerResponse(Message, com.sun.xml.internal.ws.api.addressing.AddressingVersion, com.sun.xml.internal.ws.api.SOAPVersion, String)}. |
| * |
| * @param responseMessage The {@link Message} that represents a reply. Can be null. |
| * @param wsdlPort The response WSDL port. |
| * @param binding The response Binding. Cannot be null. |
| * @return response packet |
| */ |
| public Packet createServerResponse(@Nullable Message responseMessage, @Nullable WSDLPort wsdlPort, @Nullable SEIModel seiModel, @NotNull WSBinding binding) { |
| Packet r = createClientResponse(responseMessage); |
| |
| AddressingVersion av = binding.getAddressingVersion(); |
| // populate WS-A headers only if WS-A is enabled |
| if (av == null) |
| return r; |
| //populate WS-A headers only if the request has addressing headers |
| String inputAction = this.getMessage().getHeaders().getAction(av, binding.getSOAPVersion()); |
| if (inputAction == null) { |
| return r; |
| } |
| // if one-way, then dont populate any WS-A headers |
| if (message == null || (wsdlPort != null && message.isOneWay(wsdlPort))) |
| return r; |
| |
| // otherwise populate WS-Addressing headers |
| return populateAddressingHeaders(binding, r, wsdlPort,seiModel); |
| |
| } |
| |
| /** |
| * Creates a server-side response {@link Packet} from a request |
| * packet ({@code this}). If WS-Addressing is enabled, <code>action</code> |
| * is used as Action Message Addressing Property. |
| * <p><p> |
| * This method should be called only for creating protocol response messages |
| * that require a particular value of Action since they are not associated |
| * with a {@link WSBinding} and {@link WSDLPort} but do know the {@link AddressingVersion} |
| * and {@link SOAPVersion}. |
| * |
| * @param responseMessage The {@link Message} that represents a reply. Can be null. |
| * @param addressingVersion The WS-Addressing version of the response message. |
| * @param soapVersion The SOAP version of the response message. |
| * @param action The response Action Message Addressing Property value. |
| * @return response packet |
| */ |
| public Packet createServerResponse(@Nullable Message responseMessage, @NotNull AddressingVersion addressingVersion, @NotNull SOAPVersion soapVersion, @NotNull String action) { |
| Packet responsePacket = createClientResponse(responseMessage); |
| |
| // populate WS-A headers only if WS-A is enabled |
| if (addressingVersion == null) |
| return responsePacket; |
| //populate WS-A headers only if the request has addressing headers |
| String inputAction = this.getMessage().getHeaders().getAction(addressingVersion, soapVersion); |
| if (inputAction == null) { |
| return responsePacket; |
| } |
| |
| return populateAddressingHeaders(responsePacket, |
| addressingVersion, |
| soapVersion, |
| action); |
| } |
| |
| private Packet populateAddressingHeaders(Packet responsePacket, AddressingVersion av, SOAPVersion sv, String action) { |
| // populate WS-A headers only if WS-A is enabled |
| if (av == null) |
| return responsePacket; |
| |
| // if one-way, then dont populate any WS-A headers |
| if (responsePacket.getMessage() == null) |
| return responsePacket; |
| |
| HeaderList hl = responsePacket.getMessage().getHeaders(); |
| |
| // wsa:To |
| WSEndpointReference replyTo; |
| try { |
| replyTo = message.getHeaders().getReplyTo(av, sv); |
| if (replyTo != null) |
| hl.add(new StringHeader(av.toTag, replyTo.getAddress())); |
| } catch (InvalidMapException e) { |
| replyTo = null; |
| } |
| |
| // wsa:Action |
| hl.add(new StringHeader(av.actionTag, action)); |
| |
| // wsa:MessageID |
| hl.add(new StringHeader(av.messageIDTag, responsePacket.getMessage().getID(av, sv))); |
| |
| // wsa:RelatesTo |
| // TODO: this property is defined in WsaServerTube.REQUEST_MESSAGE_ID |
| String mid = (String)responsePacket.invocationProperties.get("com.sun.xml.internal.ws.addressing.request.messageID"); |
| if (mid != null) |
| hl.add(new RelatesToHeader(av.relatesToTag, mid)); |
| |
| // populate reference parameters |
| WSEndpointReference refpEPR; |
| if (responsePacket.getMessage().isFault()) { |
| // choose FaultTo |
| refpEPR = message.getHeaders().getFaultTo(av, sv); |
| |
| // if FaultTo is null, then use ReplyTo |
| if (refpEPR == null) |
| refpEPR = replyTo; |
| } else { |
| // choose ReplyTo |
| refpEPR = replyTo; |
| } |
| if (refpEPR != null) { |
| refpEPR.addReferenceParameters(hl); |
| } |
| |
| return responsePacket; |
| } |
| |
| private Packet populateAddressingHeaders(WSBinding binding, Packet responsePacket, WSDLPort wsdlPort, SEIModel seiModel) { |
| AddressingVersion addressingVersion = binding.getAddressingVersion(); |
| |
| if (addressingVersion == null) |
| return responsePacket; |
| |
| WsaTubeHelper wsaHelper = addressingVersion.getWsaHelper(wsdlPort,seiModel, binding); |
| String action = responsePacket.message.isFault() ? |
| wsaHelper.getFaultAction(this, responsePacket) : |
| wsaHelper.getOutputAction(this); |
| |
| return populateAddressingHeaders(responsePacket, addressingVersion, binding.getSOAPVersion(), action); |
| } |
| |
| // completes TypedMap |
| private static final PropertyMap model; |
| |
| static { |
| model = parse(Packet.class); |
| } |
| |
| protected PropertyMap getPropertyMap() { |
| return model; |
| } |
| } |