aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.client; aoqi@0: aoqi@0: import com.oracle.webservices.internal.api.message.BaseDistributedPropertySet; aoqi@0: import com.sun.istack.internal.NotNull; aoqi@0: import com.sun.xml.internal.ws.api.EndpointAddress; aoqi@0: import com.sun.xml.internal.ws.api.message.Packet; aoqi@0: import com.sun.xml.internal.ws.transport.Headers; aoqi@0: aoqi@0: import javax.xml.ws.BindingProvider; aoqi@0: import java.util.HashMap; aoqi@0: import java.util.HashSet; aoqi@0: import java.util.List; aoqi@0: import java.util.Map; aoqi@0: import java.util.Map.Entry; aoqi@0: import java.util.Set; aoqi@0: import java.util.logging.Logger; aoqi@0: aoqi@0: aoqi@0: import static javax.xml.ws.BindingProvider.*; aoqi@0: import static javax.xml.ws.handler.MessageContext.HTTP_REQUEST_HEADERS; aoqi@0: aoqi@0: /** aoqi@0: * Request context implementation. aoqi@0: * aoqi@0: *
aoqi@0: * The JAX-WS spec exposes properties as a {@link Map}, but if we just use aoqi@0: * an ordinary {@link HashMap} for this, it doesn't work as fast as we'd like aoqi@0: * it to be. Hence we have this class. aoqi@0: * aoqi@0: *
aoqi@0: * We expect the user to set a few properties and then use that same aoqi@0: * setting to make a bunch of invocations. So we'd like to take some hit aoqi@0: * when the user actually sets a property to do some computation, aoqi@0: * then use that computed value during a method invocation again and again. aoqi@0: * aoqi@0: *
aoqi@0: * For this goal, we use {@link com.sun.xml.internal.ws.api.PropertySet} and implement some properties aoqi@0: * as virtual properties backed by methods. This allows us to do the computation aoqi@0: * in the setter, and store it in a field. aoqi@0: * aoqi@0: *
aoqi@0: * These fields are used by {@link Stub#process} to populate a {@link Packet}. aoqi@0: * aoqi@0: *
aoqi@0: * For better performance, we wan't use strongly typed field as much as possible aoqi@0: * to avoid reflection and unnecessary collection iterations; aoqi@0: * aoqi@0: * Using {@link com.oracle.webservices.internal.api.message.BasePropertySet.MapView} implementation allows client to use {@link Map} interface aoqi@0: * in a way that all the strongly typed properties are reflected to the fields aoqi@0: * right away. Any additional (extending) properties can be added by client as well; aoqi@0: * those would be processed using iterating the {@link MapView} and their processing, aoqi@0: * of course, would be slower. aoqi@0: *
aoqi@0: * The previous implementation with fallback mode has been removed to simplify aoqi@0: * the code and remove the bugs. aoqi@0: * aoqi@0: * @author Kohsuke Kawaguchi aoqi@0: */ aoqi@0: @SuppressWarnings({"SuspiciousMethodCalls"}) aoqi@0: public final class RequestContext extends BaseDistributedPropertySet { aoqi@0: private static final Logger LOGGER = Logger.getLogger(RequestContext.class.getName()); aoqi@0: aoqi@0: /** aoqi@0: * The default value to be use for {@link #contentNegotiation} obtained aoqi@0: * from a system property. aoqi@0: *
aoqi@0: * This enables content negotiation to be easily switched on by setting aoqi@0: * a system property on the command line for testing purposes tests. aoqi@0: */ aoqi@0: private static ContentNegotiation defaultContentNegotiation = aoqi@0: ContentNegotiation.obtainFromSystemProperty(); aoqi@0: aoqi@0: /** aoqi@0: * @deprecated aoqi@0: */ aoqi@0: public void addSatellite(@NotNull com.sun.xml.internal.ws.api.PropertySet satellite) { aoqi@0: super.addSatellite(satellite); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The endpoint address to which this message is sent to. aoqi@0: * aoqi@0: *
aoqi@0: * This is the actual data store for {@link BindingProvider#ENDPOINT_ADDRESS_PROPERTY}. aoqi@0: */ aoqi@0: private @NotNull EndpointAddress endpointAddress; aoqi@0: aoqi@0: /** aoqi@0: * Creates {@link BindingProvider#ENDPOINT_ADDRESS_PROPERTY} view aoqi@0: * on top of {@link #endpointAddress}. aoqi@0: * aoqi@0: * @deprecated aoqi@0: * always access {@link #endpointAddress}. aoqi@0: */ aoqi@0: @Property(ENDPOINT_ADDRESS_PROPERTY) aoqi@0: public String getEndPointAddressString() { aoqi@0: return endpointAddress != null ? endpointAddress.toString() : null; aoqi@0: } aoqi@0: aoqi@0: public void setEndPointAddressString(String s) { aoqi@0: if (s == null) { aoqi@0: throw new IllegalArgumentException(); aoqi@0: } else { aoqi@0: this.endpointAddress = EndpointAddress.create(s); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public void setEndpointAddress(@NotNull EndpointAddress epa) { aoqi@0: this.endpointAddress = epa; aoqi@0: } aoqi@0: aoqi@0: public @NotNull EndpointAddress getEndpointAddress() { aoqi@0: return endpointAddress; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The value of {@link ContentNegotiation#PROPERTY} aoqi@0: * property. aoqi@0: */ aoqi@0: public ContentNegotiation contentNegotiation = defaultContentNegotiation; aoqi@0: aoqi@0: @Property(ContentNegotiation.PROPERTY) aoqi@0: public String getContentNegotiationString() { aoqi@0: return contentNegotiation.toString(); aoqi@0: } aoqi@0: aoqi@0: public void setContentNegotiationString(String s) { aoqi@0: if (s == null) { aoqi@0: contentNegotiation = ContentNegotiation.none; aoqi@0: } else { aoqi@0: try { aoqi@0: contentNegotiation = ContentNegotiation.valueOf(s); aoqi@0: } catch (IllegalArgumentException e) { aoqi@0: // If the value is not recognized default to none aoqi@0: contentNegotiation = ContentNegotiation.none; aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The value of the SOAPAction header associated with the message. aoqi@0: * aoqi@0: *
aoqi@0: * For outgoing messages, the transport may sends out this value. aoqi@0: * If this field is null, the transport may choose to send "" aoqi@0: * (quoted empty string.) aoqi@0: * aoqi@0: * For incoming messages, the transport will set this field. aoqi@0: * If the incoming message did not contain the SOAPAction header, aoqi@0: * the transport sets this field to null. aoqi@0: * aoqi@0: *
aoqi@0: * If the value is non-null, it must be always in the quoted form. aoqi@0: * The value can be null. aoqi@0: * aoqi@0: *
aoqi@0: * Note that the way the transport sends this value out depends on
aoqi@0: * transport and SOAP version.
aoqi@0: *
aoqi@0: * For HTTP transport and SOAP 1.1, BP requires that SOAPAction
aoqi@0: * header is present (See {@BP R2744} and {@BP R2745}.) For SOAP 1.2,
aoqi@0: * this is moved to the parameter of the "application/soap+xml".
aoqi@0: */
aoqi@0:
aoqi@0: private String soapAction;
aoqi@0:
aoqi@0: @Property(SOAPACTION_URI_PROPERTY)
aoqi@0: public String getSoapAction() {
aoqi@0: return soapAction;
aoqi@0: }
aoqi@0:
aoqi@0: public void setSoapAction(String sAction) {
aoqi@0: soapAction = sAction;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * This controls whether BindingProvider.SOAPACTION_URI_PROPERTY is used.
aoqi@0: * See BindingProvider.SOAPACTION_USE_PROPERTY for details.
aoqi@0: *
aoqi@0: * This only control whether value of BindingProvider.SOAPACTION_URI_PROPERTY is used or not and not
aoqi@0: * if it can be sent if it can be obtained by other means such as WSDL binding
aoqi@0: */
aoqi@0: private Boolean soapActionUse;
aoqi@0:
aoqi@0: @Property(SOAPACTION_USE_PROPERTY)
aoqi@0: public Boolean getSoapActionUse() {
aoqi@0: return soapActionUse;
aoqi@0: }
aoqi@0:
aoqi@0: public void setSoapActionUse(Boolean sActionUse) {
aoqi@0: soapActionUse = sActionUse;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Creates an empty {@link RequestContext}.
aoqi@0: */
aoqi@0: RequestContext() {
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Copy constructor.
aoqi@0: */
aoqi@0: private RequestContext(RequestContext that) {
aoqi@0: for (Map.Entry