/* * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.xml.internal.ws.client; import com.oracle.webservices.internal.api.message.BaseDistributedPropertySet; import com.sun.istack.internal.NotNull; import com.sun.xml.internal.ws.api.EndpointAddress; import com.sun.xml.internal.ws.api.message.Packet; import com.sun.xml.internal.ws.transport.Headers; import javax.xml.ws.BindingProvider; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.logging.Logger; import static javax.xml.ws.BindingProvider.*; import static javax.xml.ws.handler.MessageContext.HTTP_REQUEST_HEADERS; /** * Request context implementation. * *
* The JAX-WS spec exposes properties as a {@link Map}, but if we just use * an ordinary {@link HashMap} for this, it doesn't work as fast as we'd like * it to be. Hence we have this class. * *
* We expect the user to set a few properties and then use that same * setting to make a bunch of invocations. So we'd like to take some hit * when the user actually sets a property to do some computation, * then use that computed value during a method invocation again and again. * *
* For this goal, we use {@link com.sun.xml.internal.ws.api.PropertySet} and implement some properties * as virtual properties backed by methods. This allows us to do the computation * in the setter, and store it in a field. * *
* These fields are used by {@link Stub#process} to populate a {@link Packet}. * *
* For better performance, we wan't use strongly typed field as much as possible * to avoid reflection and unnecessary collection iterations; * * Using {@link com.oracle.webservices.internal.api.message.BasePropertySet.MapView} implementation allows client to use {@link Map} interface * in a way that all the strongly typed properties are reflected to the fields * right away. Any additional (extending) properties can be added by client as well; * those would be processed using iterating the {@link MapView} and their processing, * of course, would be slower. *
* The previous implementation with fallback mode has been removed to simplify * the code and remove the bugs. * * @author Kohsuke Kawaguchi */ @SuppressWarnings({"SuspiciousMethodCalls"}) public final class RequestContext extends BaseDistributedPropertySet { private static final Logger LOGGER = Logger.getLogger(RequestContext.class.getName()); /** * The default value to be use for {@link #contentNegotiation} obtained * from a system property. *
* This enables content negotiation to be easily switched on by setting * a system property on the command line for testing purposes tests. */ private static ContentNegotiation defaultContentNegotiation = ContentNegotiation.obtainFromSystemProperty(); /** * @deprecated */ public void addSatellite(@NotNull com.sun.xml.internal.ws.api.PropertySet satellite) { super.addSatellite(satellite); } /** * The endpoint address to which this message is sent to. * *
* This is the actual data store for {@link BindingProvider#ENDPOINT_ADDRESS_PROPERTY}. */ private @NotNull EndpointAddress endpointAddress; /** * Creates {@link BindingProvider#ENDPOINT_ADDRESS_PROPERTY} view * on top of {@link #endpointAddress}. * * @deprecated * always access {@link #endpointAddress}. */ @Property(ENDPOINT_ADDRESS_PROPERTY) public String getEndPointAddressString() { return endpointAddress != null ? endpointAddress.toString() : null; } public void setEndPointAddressString(String s) { if (s == null) { throw new IllegalArgumentException(); } else { this.endpointAddress = EndpointAddress.create(s); } } public void setEndpointAddress(@NotNull EndpointAddress epa) { this.endpointAddress = epa; } public @NotNull EndpointAddress getEndpointAddress() { return endpointAddress; } /** * The value of {@link ContentNegotiation#PROPERTY} * property. */ public ContentNegotiation contentNegotiation = defaultContentNegotiation; @Property(ContentNegotiation.PROPERTY) public String getContentNegotiationString() { return contentNegotiation.toString(); } public void setContentNegotiationString(String s) { if (s == null) { contentNegotiation = ContentNegotiation.none; } else { try { contentNegotiation = ContentNegotiation.valueOf(s); } catch (IllegalArgumentException e) { // If the value is not recognized default to none contentNegotiation = ContentNegotiation.none; } } } /** * The value of the SOAPAction header associated with the message. * *
* For outgoing messages, the transport may sends out this value. * If this field is null, the transport may choose to send "" * (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. * *
* If the value is non-null, it must be always in the quoted form. * The value can be null. * *
* 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".
*/
private String soapAction;
@Property(SOAPACTION_URI_PROPERTY)
public String getSoapAction() {
return soapAction;
}
public void setSoapAction(String sAction) {
soapAction = sAction;
}
/**
* This controls whether BindingProvider.SOAPACTION_URI_PROPERTY is used.
* See BindingProvider.SOAPACTION_USE_PROPERTY for details.
*
* This only control whether value of BindingProvider.SOAPACTION_URI_PROPERTY is used or not and not
* if it can be sent if it can be obtained by other means such as WSDL binding
*/
private Boolean soapActionUse;
@Property(SOAPACTION_USE_PROPERTY)
public Boolean getSoapActionUse() {
return soapActionUse;
}
public void setSoapActionUse(Boolean sActionUse) {
soapActionUse = sActionUse;
}
/**
* Creates an empty {@link RequestContext}.
*/
RequestContext() {
}
/**
* Copy constructor.
*/
private RequestContext(RequestContext that) {
for (Map.Entry