diff -r 88b85470e72c -r f50545b5e2f1 src/share/jaxws_classes/com/sun/xml/internal/ws/client/RequestContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/client/RequestContext.java Tue Mar 06 16:09:35 2012 -0800 @@ -0,0 +1,453 @@ +/* + * Copyright (c) 1997, 2010, 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.sun.istack.internal.NotNull; +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.message.Packet; +import com.sun.xml.internal.ws.transport.Headers; + +import javax.xml.ws.BindingProvider; +import javax.xml.ws.handler.MessageContext; + +import java.util.Collection; +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; + +/** + * 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 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}. + * + * + * + *
+ * We make an assumption that a request context is mostly used to just + * get and put values, not really for things like enumerating or size. + * + *
+ * So we start by maintaining state as a combination of {@link #others} + * bag and strongly-typed fields. As long as the application uses + * just {@link Map#put}, {@link Map#get}, and {@link Map#putAll}, we can + * do things in this way. In this mode a {@link Map} we return works as + * a view into {@link RequestContext}, and by itself it maintains no state. + * + *
+ * If {@link RequestContext} is in this mode, its state can be copied + * efficiently into {@link Packet}. + * + *
+ * Once the application uses any other {@link Map} method, we move to + * the "fallback" mode, where the data is actually stored in a {@link HashMap}, + * this is necessary for implementing the map interface contract correctly. + * + *
+ * To be safe, once we fallback, we'll never come back to the efficient state. + * + * + * + *
+ * Once we are in the fallback mode, none of the strongly typed field will + * be used, and they may contain stale values. So the only method + * the code outside this class can safely use is {@link #copy()}, + * {@link #fill(Packet)}, and constructors. Do not access the strongly + * typed fields nor {@link #others} directly. + * + * @author Kohsuke Kawaguchi + */ +@SuppressWarnings({"SuspiciousMethodCalls"}) +public final class RequestContext extends DistributedPropertySet { + 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();
+
+ /**
+ * Stores properties that don't fit the strongly-typed fields.
+ */
+ private final Map
+ * 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(BindingProvider.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(BindingProvider.SOAPACTION_URI_PROPERTY)
+ public String getSoapAction(){
+ return soapAction;
+ }
+ public void setSoapAction(String sAction){
+ if(sAction == null) {
+ throw new IllegalArgumentException("SOAPAction value cannot be null");
+ }
+ 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(BindingProvider.SOAPACTION_USE_PROPERTY)
+ public Boolean getSoapActionUse(){
+ return soapActionUse;
+ }
+ public void setSoapActionUse(Boolean sActionUse){
+ soapActionUse = sActionUse;
+ }
+
+ /**
+ * {@link Map} exposed to the user application.
+ */
+ private final MapView mapView = new MapView();
+
+ /**
+ * Creates an empty {@link RequestContext}.
+ */
+ /*package*/ RequestContext() {
+ others = new HashMap