alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (RequestContext.java)

This example Java source code file (RequestContext.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

boolean, contentnegotiation, endpointaddress, headers, illegalargumentexception, list, log, logger, logging, map, object, override, property, requestcontext, string, suppresswarnings, util, xml

The RequestContext.java Java example source code

/*
 * 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.
 *
 * <h2>Why a custom map?
 * <p>
 * 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.
 *
 * <p>
 * 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.
 *
 * <p>
 * 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.
 *
 * <p>
 * These fields are used by {@link Stub#process} to populate a {@link Packet}.
 *
 * <h2>How it works?
 * <p>
 * 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.
 * <p>
 * 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.
     * <p>
     * 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.
     *
     * <p>
     * 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.
     *
     * <p>
     * For outgoing messages, the transport may sends out this value.
     * If this field is null, the transport may choose to send <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".
     */

    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<String, Object> entry : that.asMapLocal().entrySet()) {
            if (!propMap.containsKey(entry.getKey())) {
                asMap().put(entry.getKey(), entry.getValue());
            }
        }
        endpointAddress = that.endpointAddress;
        soapAction = that.soapAction;
        soapActionUse = that.soapActionUse;
        contentNegotiation = that.contentNegotiation;
        that.copySatelliteInto(this);
    }

    /**
     * The efficient get method that reads from {@link RequestContext}.
     */
    @Override
    public Object get(Object key) {
        if(supports(key)) {
            return super.get(key);
        } else {
            // use mapView to get extending property
            return asMap().get(key);
        }
    }

    /**
     * The efficient put method that updates {@link RequestContext}.
     */
    @Override
    public Object put(String key, Object value) {

        if(supports(key)) {
            return super.put(key,value);
        } else {
            // use mapView to put extending property (if the map allows that)
            return asMap().put(key, value);
        }
    }

    /**
     * Fill a {@link Packet} with values of this {@link RequestContext}.
     *
     * @param packet              to be filled with context values
     * @param isAddressingEnabled flag if addressing enabled (to provide warning if necessary)
     */
    @SuppressWarnings("unchecked")
    public void fill(Packet packet, boolean isAddressingEnabled) {

        // handling as many properties as possible (all in propMap.keySet())
        // to avoid slow Packet.put()
        if (endpointAddress != null) {
            packet.endpointAddress = endpointAddress;
        }
        packet.contentNegotiation = contentNegotiation;
        fillSOAPAction(packet, isAddressingEnabled);
        mergeRequestHeaders(packet);

        Set<String> handlerScopeNames = new HashSet();

        copySatelliteInto(packet);

        // extending properties ...
        for (String key : asMapLocal().keySet()) {

            //if it is not standard property it defaults to Scope.HANDLER
            if (!supportsLocal(key)) {
                handlerScopeNames.add(key);
            }

            // to avoid slow Packet.put(), handle as small number of props as possible
            // => only properties not from RequestContext object
            if (!propMap.containsKey(key)) {
                Object value = asMapLocal().get(key);
                if (packet.supports(key)) {
                    // very slow operation - try to avoid it!
                    packet.put(key, value);
                } else {
                    packet.invocationProperties.put(key, value);
                }
            }
        }

        if (!handlerScopeNames.isEmpty()) {
            packet.getHandlerScopePropertyNames(false).addAll(handlerScopeNames);
        }
    }

    @SuppressWarnings("unchecked")
    private void mergeRequestHeaders(Packet packet) {
        //for bug 12883765
        //retrieve headers which is set in soap message
        Headers packetHeaders = (Headers) packet.invocationProperties.get(HTTP_REQUEST_HEADERS);
        //retrieve headers from request context
        Map<String, List myHeaders = (Map>) asMap().get(HTTP_REQUEST_HEADERS);
        if ((packetHeaders != null) && (myHeaders != null)) {
            //update the headers set in soap message with those in request context
            for (Entry<String, List entry : myHeaders.entrySet()) {
                String key = entry.getKey();
                if (key != null && key.trim().length() != 0) {
                    List<String> listFromPacket = packetHeaders.get(key);
                    //if the two headers contain the same key, combine the value
                    if (listFromPacket != null) {
                        listFromPacket.addAll(entry.getValue());
                    } else {
                        //add the headers  in request context to those set in soap message
                        packetHeaders.put(key, myHeaders.get(key));
                    }
                }
            }
            // update headers in request context with those set in soap message since it may contain other properties..
            asMap().put(HTTP_REQUEST_HEADERS, packetHeaders);
        }
    }

    private void fillSOAPAction(Packet packet, boolean isAddressingEnabled) {
        final boolean p = packet.packetTakesPriorityOverRequestContext;
        final String  localSoapAction    = p ? packet.soapAction : soapAction;
        final Boolean localSoapActionUse = p ? (Boolean) packet.invocationProperties.get(BindingProvider.SOAPACTION_USE_PROPERTY)
                                             : soapActionUse;

        //JAX-WS-596: Check the semantics of SOAPACTION_USE_PROPERTY before using the SOAPACTION_URI_PROPERTY for
        // SoapAction as specified in the javadoc of BindingProvider. The spec seems to be little contradicting with
        //  javadoc and says that the use property effects the sending of SOAPAction property.
        // Since the user has the capability to set the value as "" if needed, implement the javadoc behavior.
        if ((localSoapActionUse != null && localSoapActionUse) || (localSoapActionUse == null && isAddressingEnabled)) {
            if (localSoapAction != null) {
                packet.soapAction = localSoapAction;
            }
        }

        if ((!isAddressingEnabled && (localSoapActionUse == null || !localSoapActionUse)) && localSoapAction != null) {
            LOGGER.warning("BindingProvider.SOAPACTION_URI_PROPERTY is set in the RequestContext but is ineffective," +
                    " Either set BindingProvider.SOAPACTION_USE_PROPERTY to true or enable AddressingFeature");
        }
    }

    public RequestContext copy() {
        return new RequestContext(this);
    }

    @Override
    protected PropertyMap getPropertyMap() {
        return propMap;
    }

    private static final PropertyMap propMap = parse(RequestContext.class);

    @Override
    protected boolean mapAllowsAdditionalProperties() {
        return true;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java RequestContext.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.