All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.axis.MessageContext Maven / Gradle / Ivy

There is a newer version: 7.4.3.112-ga112
Show newest version
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.axis ;

import org.apache.axis.attachments.Attachments;
import org.apache.axis.client.AxisClient;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.description.OperationDesc;
import org.apache.axis.description.ServiceDesc;
import org.apache.axis.encoding.TypeMapping;
import org.apache.axis.encoding.TypeMappingRegistry;
import org.apache.axis.constants.Style;
import org.apache.axis.constants.Use;
import org.apache.axis.handlers.soap.SOAPService;
import org.apache.axis.schema.SchemaVersion;
import org.apache.axis.session.Session;
import org.apache.axis.soap.SOAPConstants;
import org.apache.axis.utils.JavaUtils;
import org.apache.axis.utils.LockableHashtable;
import org.apache.axis.utils.Messages;
import org.apache.commons.logging.Log;

import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;

// fixme: fields are declared throughout this class, some at the top, and some
//  near to where they are used. We should move all field declarations into a
//  single block - it makes it easier to see what is decalred in this class and
//  what is inherited. It also makes it easier to find them.
/**
 * A MessageContext is the Axis implementation of the javax
 * SOAPMessageContext class, and is core to message processing
 * in handlers and other parts of the system.
 *
 * This class also contains constants for accessing some
 * well-known properties. Using a hierarchical namespace is
 * strongly suggested in order to lower the chance for
 * conflicts.
 *
 * (These constants should be viewed as an explicit list of well
 *  known and widely used context keys, there's nothing wrong
 *  with directly using the key strings. This is the reason for
 *  the hierarchical constant namespace.
 *
 *  Actually I think we might just list the keys in the docs and
 *  provide no such constants since they create yet another
 *  namespace, but we'd have no compile-time checks then.
 *
 *  Whaddya think? - todo by Jacek)
 *
 *
 * @author Doug Davis ([email protected])
 * @author Jacek Kopecky ([email protected])
 */
public class MessageContext implements SOAPMessageContext {
    /** The Log used for logging all messages. */
    protected static Log log =
            LogFactory.getLog(MessageContext.class.getName());

    /**
     * The request message.  If we're on the client, this is the outgoing
     * message heading to the server.  If we're on the server, this is the
     * incoming message we've received from the client.
     */
    private Message      requestMessage;

    /**
     * The response message.  If we're on the server, this is the outgoing
     * message heading back to the client.  If we're on the client, this is the
     * incoming message we've received from the server.
     */
    private Message      responseMessage;

    /**
     * That unique key/name that the next router/dispatch handler should use
     * to determine what to do next.
     */
    private String       targetService;

    /**
     * The name of the Transport which this message was received on (or is
     * headed to, for the client).
     */
    private String       transportName;

    /**
     * The default ClassLoader that this service should use.
     */
    private ClassLoader  classLoader;

    /**
     * The AxisEngine which this context is involved with.
     */
    private AxisEngine   axisEngine;

    /**
     * A Session associated with this request.
     */
    private Session      session;

    /**
     * Should we track session state, or not?
     * default is not.
     * Could potentially refactor this so that
     * maintainSession iff session != null...
     */
    private boolean      maintainSession = false;

    // fixme: ambiguity here due to lac of docs - havePassedPivot vs
    //  request/response, vs sending/processing & recieving/responding
    //  I may have just missed the key bit of text
    /**
     * Are we doing request stuff, or response stuff? True if processing
     * response (I think).
     */
    private boolean      havePassedPivot = false;

    /**
     * Maximum amount of time to wait on a request, in milliseconds.
     */
    private int          timeout = Constants.DEFAULT_MESSAGE_TIMEOUT;

    /**
     * An indication of whether we require "high fidelity" recording of
     * deserialized messages for this interaction.  Defaults to true for
     * now, and can be set to false, usually at service-dispatch time.
     */
    private boolean      highFidelity = true;

    /**
     * Storage for an arbitrary bag of properties associated with this
     * MessageContext.
     */
    private LockableHashtable bag = new LockableHashtable();

    /*
     * These variables are logically part of the bag, but are separated
     * because they are used often and the Hashtable is more expensive.
     *
     * fixme: this may be fixed by moving to a plain Map impl like HashMap.
     *  Alternatively, we could hide all this magic behind a custom Map impl -
     *  is synchronization on the map needed? these properties aren't
     *  synchronized so I'm guessing not.
     */
    private String  username       = null;
    private String  password       = null;
    private String  encodingStyle  = Use.ENCODED.getEncoding();
    private boolean useSOAPAction  = false;
    private String  SOAPActionURI  = null;

    /**
     * SOAP Actor roles.
     */
    private String[] roles;

    /** Our SOAP namespaces and such. */
    private SOAPConstants soapConstants = Constants.DEFAULT_SOAP_VERSION;

    /** Schema version information - defaults to 2001. */
    private SchemaVersion schemaVersion = SchemaVersion.SCHEMA_2001;

    /** Our current operation. */
    private OperationDesc currentOperation = null;

    /**
     * The current operation.
     *
     * @return the current operation; may be null
     */
    public  OperationDesc getOperation()
    {
        return currentOperation;
    }

    /**
     * Set the current operation.
     *
     * @param operation  the Operation this context is executing
     */
    public void setOperation(OperationDesc operation)
    {
        currentOperation = operation;
    }

    /**
     * Returns a list of operation descriptors that could may
     * possibly match a body containing an element of the given QName.
     * For non-DOCUMENT, the list of operation descriptors that match
     * the name is returned.  For DOCUMENT, all the operations that have
     * qname as a parameter are returned
     *
     * @param qname of the first element in the body
     * @return list of operation descriptions
     * @throws AxisFault if the operation names could not be looked up
     */
    public OperationDesc [] getPossibleOperationsByQName(QName qname) throws AxisFault
    {
        if (currentOperation != null) {
            return new OperationDesc [] { currentOperation };
        }

        OperationDesc [] possibleOperations = null;

        if (serviceHandler == null) {
            try {
                if (log.isDebugEnabled()) {
                    log.debug(Messages.getMessage("dispatching00",
                                                   qname.getNamespaceURI()));
                }

                // Try looking this QName up in our mapping table...
                setService(axisEngine.getConfig().
                           getServiceByNamespaceURI(qname.getNamespaceURI()));
            } catch (ConfigurationException e) {
                // Didn't find one...
            }

        }

        if (serviceHandler != null) {
            ServiceDesc desc = serviceHandler.getInitializedServiceDesc(this);

            if (desc != null) {
                if (desc.getStyle() != Style.DOCUMENT) {
                    possibleOperations = desc.getOperationsByQName(qname);
                } else {
                    // DOCUMENT Style
                    // Get all of the operations that have qname as
                    // a possible parameter QName
                    ArrayList allOperations = desc.getOperations();
                    ArrayList foundOperations = new ArrayList();
                    for (int i=0; i < allOperations.size(); i++ ) {
                        OperationDesc tryOp =
                            (OperationDesc) allOperations.get(i);
                        if (tryOp.getParamByQName(qname) != null) {
                            foundOperations.add(tryOp);
                        }
                    }
                    if (foundOperations.size() > 0) {
                        possibleOperations = (OperationDesc[])
                            JavaUtils.convert(foundOperations,
                                              OperationDesc[].class);
                    }
                }
            }
        }
        return possibleOperations;
    }

    /**
     * get the first possible operation that could match a
     * body containing an element of the given QName. Sets the currentOperation
     * field in the process; if that field is already set then its value
     * is returned instead
     * @param qname name of the message body
     * @return an operation or null
     * @throws AxisFault
     */
    public OperationDesc getOperationByQName(QName qname) throws AxisFault
    {
        if (currentOperation == null) {
            OperationDesc [] possibleOperations = getPossibleOperationsByQName(qname);
            if (possibleOperations != null && possibleOperations.length > 0) {
                currentOperation = possibleOperations[0];
            }
        }

        return currentOperation;
    }

    /**
     * Get the active message context.
     *
     * @return the current active message context
     */
    public static MessageContext getCurrentContext() {
       return AxisEngine.getCurrentMessageContext();
    }

    /**
     * Temporary directory to store attachments.
     */
    protected static String systemTempDir= null;
    /**
     * set the temp dir
     * TODO: move this piece of code out of this class and into a utilities
     * class.
     */
    static {
        try {
            //get the temp dir from the engine
            systemTempDir=AxisProperties.getProperty(AxisEngine.ENV_ATTACHMENT_DIR);
        } catch(Throwable t) {
            systemTempDir= null;
        }

        if(systemTempDir== null) {
            try {
                //or create and delete a file in the temp dir to make
                //sure we have write access to it.
                File tf= File.createTempFile("Axis", ".tmp");
                File dir= tf.getParentFile();
                if (tf.exists()) {
                    tf.delete();
                }
                if (dir != null) {
                  systemTempDir= dir.getCanonicalPath();
                }
            } catch(Throwable t) {
                log.debug("Unable to find a temp dir with write access");
                systemTempDir= null;
            }
        }
    }

    /**
     * Create a message context.
     * @param engine the controlling axis engine. Null is actually accepted here,
     * though passing a null engine in is strongly discouraged as many of the methods
     * assume that it is in fact defined.
     */
    public MessageContext(AxisEngine engine) {
        this.axisEngine = engine;

        if(null != engine){
            java.util.Hashtable opts= engine.getOptions();
            String attachmentsdir= null;
            if(null!=opts) {
                attachmentsdir= (String) opts.get(AxisEngine.PROP_ATTACHMENT_DIR);
            }
            if(null == attachmentsdir) {
                attachmentsdir= systemTempDir;
            }
            if(attachmentsdir != null){
                setProperty(ATTACHMENTS_DIR, attachmentsdir);
            }

            // If SOAP 1.2 has been specified as the default for the engine,
            // switch the constants over.
            String defaultSOAPVersion = (String)engine.getOption(
                                                 AxisEngine.PROP_SOAP_VERSION);
            if (defaultSOAPVersion != null && "1.2".equals(defaultSOAPVersion)) {
                setSOAPConstants(SOAPConstants.SOAP12_CONSTANTS);
            }

            String singleSOAPVersion = (String)engine.getOption(
                                        AxisEngine.PROP_SOAP_ALLOWED_VERSION);
            if (singleSOAPVersion != null) {
                if ("1.2".equals(singleSOAPVersion)) {
                    setProperty(Constants.MC_SINGLE_SOAP_VERSION,
                                SOAPConstants.SOAP12_CONSTANTS);
                } else if ("1.1".equals(singleSOAPVersion)) {
                    setProperty(Constants.MC_SINGLE_SOAP_VERSION,
                                SOAPConstants.SOAP11_CONSTANTS);
                }
            }
        }
    }

    /**
     * during finalization, the dispose() method is called.
     * @see #dispose()
     */
    protected void finalize() {
        dispose();
    }

    /**
     * Mappings of QNames to serializers/deserializers (and therfore
     * to Java types).
     */
    private TypeMappingRegistry mappingRegistry = null;

    /**
     * Replace the engine's type mapping registry with a local one. This will
     * have no effect on any type mappings obtained before this call.
     *
     * @param reg  the new TypeMappingRegistry
     */
    public void setTypeMappingRegistry(TypeMappingRegistry reg) {
        mappingRegistry = reg;
    }

    /**
     * Get the currently in-scope type mapping registry.
     *
     * By default, will return a reference to the AxisEngine's TMR until
     * someone sets our local one (usually as a result of setting the
     * serviceHandler).
     *
     * @return the type mapping registry to use for this request.
     */
    public TypeMappingRegistry getTypeMappingRegistry() {
        if (mappingRegistry == null) {
            return axisEngine.getTypeMappingRegistry();
        }

        return mappingRegistry;
    }

    /**
     * Return the type mapping currently in scope for our encoding style.
     *
     * @return the type mapping
     */
    public TypeMapping getTypeMapping()
    {
        return (TypeMapping)getTypeMappingRegistry().
                getTypeMapping(encodingStyle);
    }

    /**
     * The name of the transport for this context.
     *
     * @return the transport name
     */
    public String getTransportName()
    {
        return transportName;
    }

    // fixme: the transport names should be a type-safe e-num, or the range
    //  of legal values should be specified in the documentation and validated
    //  in the method (raising IllegalArgumentException)
    /**
     * Set the transport name for this context.
     *
     * @param transportName the name of the transport
     */
    public void setTransportName(String transportName)
    {
        this.transportName = transportName;
    }

    /**
     * Get the SOAPConstants used by this message context.
     *
     * @return the soap constants
     */
    public SOAPConstants getSOAPConstants() {
        return soapConstants;
    }

    /**
     * Set the SOAPConstants used by this message context.
     * This may also affect the encoding style.
     *
     * @param soapConstants  the new soap constants to use
     */
    public void setSOAPConstants(SOAPConstants soapConstants) {
        // when changing SOAP versions, remember to keep the encodingURI
        // in synch.
        if (this.soapConstants.getEncodingURI().equals(encodingStyle)) {
            encodingStyle = soapConstants.getEncodingURI();
        }

        this.soapConstants = soapConstants;
    }

    /**
     * Get the XML schema version information.
     *
     * @return the SchemaVersion in use
     */
    public SchemaVersion getSchemaVersion() {
        return schemaVersion;
    }

    /**
     * Set the XML schema version this message context will use.
     *
     * @param schemaVersion  the new SchemaVersion
     */
    public void setSchemaVersion(SchemaVersion schemaVersion) {
        this.schemaVersion = schemaVersion;
    }

    /**
     * Get the current session.
     *
     * @return the Session this message context is within
     */
    public Session getSession()
    {
        return session;
    }

    /**
     * Set the current session.
     *
     * @param session  the new Session
     */
    public void setSession(Session session)
    {
        this.session = session;
    }

    /**
     * Indicates if the opration is encoded.
     *
     * @return true if it is encoded, false otherwise
     */
    public boolean isEncoded() {
        return (getOperationUse() == Use.ENCODED);
        //return soapConstants.getEncodingURI().equals(encodingStyle);
    }

    /**
     * Set whether we are maintaining session state.
     *
     * @param yesno flag to set to true to maintain sessions
     */
    public void setMaintainSession (boolean yesno) {
        maintainSession = yesno;
    }

    /**
     * Discover if we are maintaining session state.
     *
     * @return true if we are maintaining state, false
     *              otherwise
     */
    public boolean getMaintainSession () {
        return maintainSession;
    }

    /**
     * Get the request message.
     *
     * @return the request message (may be null).
     */
    public Message getRequestMessage() {
        return requestMessage ;
    }

    /**
     * Set the request message, and make sure that message is associated
     * with this MessageContext.
     *
     * @param reqMsg the new request Message.
     */
    public void setRequestMessage(Message reqMsg) {
        requestMessage = reqMsg ;
        if (requestMessage != null) {
            requestMessage.setMessageContext(this);
        }
    }

    /**
     * Get the response message.
     *
     * @return the response message (may be null).
     */
    public Message getResponseMessage() { return responseMessage ; }

    /**
     * Set the response message, and make sure that message is associated
     * with this MessageContext.
     *
     * @param respMsg the new response Message.
     */
    public void setResponseMessage(Message respMsg) {
        responseMessage = respMsg;
        if (responseMessage != null) {
            responseMessage.setMessageContext(this);

            //if we have received attachments of a particular type
            // than that should be the default type to send.
            Message reqMsg = getRequestMessage();
            if (null != reqMsg) {
                Attachments reqAttch = reqMsg.getAttachmentsImpl();
                Attachments respAttch = respMsg.getAttachmentsImpl();
                if (null != reqAttch && null != respAttch) {
                    if (respAttch.getSendType() == Attachments.SEND_TYPE_NOTSET)
                        //only if not explicity set.
                        respAttch.setSendType(reqAttch.getSendType());
                }
            }
        }
    }

    /**
     * Return the current (i.e. request before the pivot, response after)
     * message.
     *
     * @return the current Message
     */
    public Message getCurrentMessage()
    {
        return (havePassedPivot ? responseMessage : requestMessage);
    }

    /**
     *  Gets the SOAPMessage from this message context.
     *
     *  @return the SOAPMessage, null if no request
     *          SOAPMessage is present in this
     *          SOAPMessageContext
     */
    public javax.xml.soap.SOAPMessage getMessage() {
        return getCurrentMessage();
    }

    /**
     * Set the current message. This will set the request before the pivot,
     * and the response afterwards, as guaged by the passedPivod property.
     *
     * @param curMsg  the Message to assign
     */
    public void setCurrentMessage(Message curMsg)
    {
        if ( curMsg != null )
            curMsg.setMessageContext(this);

        if (havePassedPivot) {
            responseMessage = curMsg;
        } else {
            requestMessage = curMsg;
        }
    }

    /**
     * Sets the SOAPMessage for this message context.
     * This is equivalent to casting message to
     * Message and then passing it on to
     * setCurrentMessage().
     *
     * @param message  the SOAPMessage this context is for
     */
    public void setMessage(javax.xml.soap.SOAPMessage message) {
        setCurrentMessage((Message)message);
    }

    /**
     * Determine when we've passed the pivot.
     *
     * @return true if we have, false otherwise
     */
    public boolean getPastPivot()
    {
        return havePassedPivot;
    }

    // fixme: is there any legitimate case where we could pass the pivot and
    //  then go back again? Is there documentation about the life-cycle of a
    //  MessageContext, and in particular the re-use of instances that would be
    //  relevant?
    /**
     * Indicate when we've passed the pivot.
     *
     * @param pastPivot  true if we are past the pivot point, false otherwise
     */
    public void setPastPivot(boolean pastPivot)
    {
        havePassedPivot = pastPivot;
    }

    /**
     * Set timeout in our MessageContext.
     *
     * @param value the maximum amount of time, in milliseconds
     */
    public void setTimeout (int value) {
        timeout = value;
    }

    /**
     * Get timeout from our MessageContext.
     *
     * @return value the maximum amount of time, in milliseconds
     */
    public int getTimeout () {
        return timeout;
    }

    /**
     * Get the classloader, implicitly binding to the thread context
     * classloader if an override has not been supplied.
     *
     * @return the class loader
     */
    public ClassLoader getClassLoader() {
        if ( classLoader == null ) {
            classLoader = Thread.currentThread().getContextClassLoader();
        }
        return( classLoader );
    }

    /**
     * Set a new classloader. Setting to null will result in getClassLoader()
     * binding back to the thread context class loader.
     *
     * @param cl    the new ClassLoader or null
     */
    public void setClassLoader(ClassLoader cl ) {
        classLoader = cl ;
    }

    /**
     * Get the name of the targed service for this message.
     *
     * @return the target service
     */
    public String getTargetService() {
        return targetService;
    }

    /**
     * Get the axis engine. This will be null if the message was
     * created outside an engine
     *
     * @return the current axis engine
     */
    public AxisEngine getAxisEngine()
    {
        return axisEngine;
    }

    /**
     * Set the target service for this message.
     * 

* This looks up the named service in the registry, and has * the side effect of setting our TypeMappingRegistry to the * service's. * * @param tServ the name of the target service * @throws AxisFault if anything goes wrong in resolving or setting the * service */ public void setTargetService(String tServ) throws AxisFault { log.debug("MessageContext: setTargetService(" + tServ+")"); if (tServ == null) { setService(null); } else { try { setService(getAxisEngine().getService(tServ)); } catch (AxisFault fault) { // If we're on the client, don't throw this fault... if (!isClient()) { throw fault; } } } targetService = tServ; } /** ServiceHandler is the handler that is the "service". This handler * can (and probably will actually be a chain that contains the * service specific request/response/pivot point handlers */ private SOAPService serviceHandler ; /** * Get the SOAPService used to handle services in this * context. * * @return the service handler */ public SOAPService getService() { return serviceHandler; } /** * Set the SOAPService used to handle services in this * context. This method configures a wide range of * MessageContext properties to suit the handler. * * @param sh the new service handler * @throws AxisFault if the service could not be set */ public void setService(SOAPService sh) throws AxisFault { log.debug("MessageContext: setServiceHandler("+sh+")"); serviceHandler = sh; if (sh != null) { if(!sh.isRunning()) { throw new AxisFault(Messages.getMessage("disabled00")); } targetService = sh.getName(); SOAPService service = sh; TypeMappingRegistry tmr = service.getTypeMappingRegistry(); setTypeMappingRegistry(tmr); // styles are not "soap version aware" so compensate... setEncodingStyle(service.getUse().getEncoding()); // This MessageContext should now defer properties it can't find // to the Service's options. bag.setParent(sh.getOptions()); // Note that we need (or don't need) high-fidelity SAX recording // of deserialized messages according to the setting on the // new service. highFidelity = service.needsHighFidelityRecording(); service.getInitializedServiceDesc(this); } } /** * Let us know whether this is the client or the server. * * @return true if we are a client */ public boolean isClient() { return (axisEngine instanceof AxisClient); } // fixme: public final statics tend to go in a block at the top of the // class deffinition, not marooned in the middle // fixme: chose public static final /or/ public final static /** Contains an instance of Handler, which is the * ServiceContext and the entrypoint of this service. * * (if it has been so configured - will our deployment * tool do this by default? - todo by Jacek) */ public static final String ENGINE_HANDLER = "engine.handler"; /** This String is the URL that the message came to. */ public static final String TRANS_URL = "transport.url"; /** Has a quit been requested? Hackish... but useful... -- RobJ */ public static final String QUIT_REQUESTED = "quit.requested"; /** Place to store an AuthenticatedUser. */ public static final String AUTHUSER = "authenticatedUser"; /** If on the client - this is the Call object. */ public static final String CALL = "call_object" ; /** Are we doing Msg vs RPC? - For Java Binding. */ public static final String IS_MSG = "isMsg" ; /** The directory where in coming attachments are created. */ public static final String ATTACHMENTS_DIR = "attachments.directory" ; /** A boolean param, to control whether we accept missing parameters * as nulls or refuse to acknowledge them. */ public final static String ACCEPTMISSINGPARAMS = "acceptMissingParams"; /** The value of the property is used by service WSDL generation (aka ?WSDL) * For the service's interface namespace if not set TRANS_URL property is used. */ public static final String WSDLGEN_INTFNAMESPACE = "axis.wsdlgen.intfnamespace"; /** The value of the property is used by service WSDL generation (aka ?WSDL). * For the service's location if not set TRANS_URL property is used. * (helps provide support through proxies. */ public static final String WSDLGEN_SERV_LOC_URL = "axis.wsdlgen.serv.loc.url"; // fixme: should this be a type-safe e-num? /** The value of the property is used by service WSDL generation (aka ?WSDL). * Set this property to request a certain level of HTTP. * The values MUST use org.apache.axis.transport.http.HTTPConstants.HEADER_PROTOCOL_10 * for HTTP 1.0 * The values MUST use org.apache.axis.transport.http.HTTPConstants.HEADER_PROTOCOL_11 * for HTTP 1.1 */ public static final String HTTP_TRANSPORT_VERSION = "axis.transport.version"; // fixme: is this the name of a security provider, or the name of a security // provider class, or the actualy class of a security provider, or // something else? /** * The security provider. */ public static final String SECURITY_PROVIDER = "securityProvider"; /* * IMPORTANT. * If adding any new constants to this class. Make them final. The * ones above are left non-final for compatibility reasons. */ /** * Get a String property by name. * * @param propName the name of the property to fetch * @return the value of the named property * @throws ClassCastException if the property named does not have a * String value */ public String getStrProp(String propName) { return (String) getProperty(propName); } /** * Tests to see if the named property is set in the 'bag', returning * false if it is not present at all. * This is equivalent to isPropertyTrue(propName, false). * * @param propName the name of the property to check * @return true or false, depending on the value of the property */ public boolean isPropertyTrue(String propName) { return isPropertyTrue(propName, false); } /** * Test if a property is set to something we consider to be true in the * 'bag'. *

    *
  • If not there then defaultVal is returned.
  • *
  • If there, then...
      *
    • if its a Boolean, we'll return booleanValue()
    • *
    • if its an Integer, we'll return false * if its 0 else true
    • *
    • if its a String we'll return false if its * "false"" or "0" else true
    • *
    • All other types return true
    • *
  • *
* * @param propName the name of the property to check * @param defaultVal the default value * @return true or false, depending on the value of the property */ public boolean isPropertyTrue(String propName, boolean defaultVal) { return JavaUtils.isTrue(getProperty(propName), defaultVal); } /** * Allows you to set a named property to the passed in value. * There are a few known properties (like username, password, etc) * that are variables in Call. The rest of the properties are * stored in a Hashtable. These common properties should be * accessed via the accessors for speed/type safety, but they may * still be obtained via this method. It's up to one of the * Handlers (or the Axis engine itself) to go looking for * one of them. * * @param name Name of the property * @param value Value of the property */ public void setProperty(String name, Object value) { if (name == null || value == null) { return; // Is this right? Shouldn't we throw an exception like: // throw new IllegalArgumentException(msg); } else if (name.equals(Call.USERNAME_PROPERTY)) { if (!(value instanceof String)) { throw new IllegalArgumentException( Messages.getMessage("badProp00", new String[] { name, "java.lang.String", value.getClass().getName()})); } setUsername((String) value); } else if (name.equals(Call.PASSWORD_PROPERTY)) { if (!(value instanceof String)) { throw new IllegalArgumentException( Messages.getMessage("badProp00", new String[] { name, "java.lang.String", value.getClass().getName()})); } setPassword((String) value); } else if (name.equals(Call.SESSION_MAINTAIN_PROPERTY)) { if (!(value instanceof Boolean)) { throw new IllegalArgumentException( Messages.getMessage("badProp00", new String[] {name, "java.lang.Boolean", value.getClass().getName()})); } setMaintainSession(((Boolean) value).booleanValue()); } else if (name.equals(Call.SOAPACTION_USE_PROPERTY)) { if (!(value instanceof Boolean)) { throw new IllegalArgumentException( Messages.getMessage("badProp00", new String[] {name, "java.lang.Boolean", value.getClass().getName()})); } setUseSOAPAction(((Boolean) value).booleanValue()); } else if (name.equals(Call.SOAPACTION_URI_PROPERTY)) { if (!(value instanceof String)) { throw new IllegalArgumentException( Messages.getMessage("badProp00", new String[] {name, "java.lang.String", value.getClass().getName()})); } setSOAPActionURI((String) value); } else if (name.equals(Call.ENCODINGSTYLE_URI_PROPERTY)) { if (!(value instanceof String)) { throw new IllegalArgumentException( Messages.getMessage("badProp00", new String[] {name, "java.lang.String", value.getClass().getName()})); } setEncodingStyle((String) value); } else { bag.put(name, value); } } // setProperty /** * Returns true if the MessageContext contains a property with the specified name. * @param name Name of the property whose presense is to be tested * @return Returns true if the MessageContext contains the property; otherwise false */ public boolean containsProperty(String name) { Object propertyValue = getProperty(name); return (propertyValue != null); } /** * Returns an Iterator view of the names of the properties in * this MessageContext. * * @return an Iterator over all property names */ public java.util.Iterator getPropertyNames() { // fixme: this is potentially unsafe for the caller - changing the // properties will kill the iterator. Consider iterating over a copy: // return new HashSet(bag.keySet()).iterator(); return bag.keySet().iterator(); } /** * Returns an Iterator view of the names of the properties * in this MessageContext and any parents of the LockableHashtable * @return Iterator for the property names */ public java.util.Iterator getAllPropertyNames() { return bag.getAllKeys().iterator(); } /** * Returns the value associated with the named property - or null if not * defined/set. * * @param name the property name * @return Object value of the property - or null */ public Object getProperty(String name) { if (name != null) { if (name.equals(Call.USERNAME_PROPERTY)) { return getUsername(); } else if (name.equals(Call.PASSWORD_PROPERTY)) { return getPassword(); } else if (name.equals(Call.SESSION_MAINTAIN_PROPERTY)) { return getMaintainSession() ? Boolean.TRUE : Boolean.FALSE; } else if (name.equals(Call.OPERATION_STYLE_PROPERTY)) { return (getOperationStyle() == null) ? null : getOperationStyle().getName(); } else if (name.equals(Call.SOAPACTION_USE_PROPERTY)) { return useSOAPAction() ? Boolean.TRUE : Boolean.FALSE; } else if (name.equals(Call.SOAPACTION_URI_PROPERTY)) { return getSOAPActionURI(); } else if (name.equals(Call.ENCODINGSTYLE_URI_PROPERTY)) { return getEncodingStyle(); } else if (bag == null) { return null; } else { return bag.get(name); } } else { return null; } } // fixme: this makes no copy of parent, so later modifications to parent // can alter this context - is this intended? If so, it needs documenting. // If not, it needs fixing. /** * Set the Hashtable that contains the default values for our * properties. * * @param parent */ public void setPropertyParent(Hashtable parent) { bag.setParent(parent); } /** * Set the username. * * @param username the new user name */ public void setUsername(String username) { this.username = username; } // setUsername /** * Get the user name. * * @return the user name as a String */ public String getUsername() { return username; } // getUsername /** * Set the password. * * @param password a String containing the new password */ public void setPassword(String password) { this.password = password; } // setPassword /** * Get the password. * * @return the current password String */ public String getPassword() { return password; } // getPassword /** * Get the operation style. This is either the style of the current * operation or if that is not set, the style of the service handler, or * if that is not set, Style.RPC. * * @return the Style of this message */ public Style getOperationStyle() { if (currentOperation != null) { return currentOperation.getStyle(); } if (serviceHandler != null) { return serviceHandler.getStyle(); } return Style.RPC; } // getOperationStyle /** * Get the operation use. * * @return the operation Use */ public Use getOperationUse() { if (currentOperation != null) { return currentOperation.getUse(); } if (serviceHandler != null) { return serviceHandler.getUse(); } return Use.ENCODED; } // getOperationUse /** * Enable or dissable the use of soap action information. When enabled, * the message context will attempt to use the soap action URI * information during binding of soap messages to service methods. When * dissabled, it will make no such attempt. * * @param useSOAPAction true if soap action URI information * should be used, false otherwise */ public void setUseSOAPAction(boolean useSOAPAction) { this.useSOAPAction = useSOAPAction; } // setUseSOAPAction // fixme: this doesn't follow beany naming conventions - should be // isUseSOAPActions or getUseSOAPActions or something prettier /** * Indicates wether the soap action URI is being used or not. * * @return true if it is, false otherwise */ public boolean useSOAPAction() { return useSOAPAction; } // useSOAPAction // fixme: this throws IllegalArgumentException but never raises it - // perhaps in a sub-class? // fixme: IllegalArgumentException is unchecked. Best practice says you // should document unchecked exceptions, but not list them in throws /** * Set the soapAction URI. * * @param SOAPActionURI a String giving the new soap action * URI * @throws IllegalArgumentException if the URI is not liked */ public void setSOAPActionURI(String SOAPActionURI) throws IllegalArgumentException { this.SOAPActionURI = SOAPActionURI; } // setSOAPActionURI /** * Get the soapAction URI. * * @return the URI of this soap action */ public String getSOAPActionURI() { return SOAPActionURI; } // getSOAPActionURI /** * Sets the encoding style to the URI passed in. * * @param namespaceURI URI of the encoding to use. */ public void setEncodingStyle(String namespaceURI) { if (namespaceURI == null) { namespaceURI = Constants.URI_LITERAL_ENC; } else if (Constants.isSOAP_ENC(namespaceURI)) { namespaceURI = soapConstants.getEncodingURI(); } encodingStyle = namespaceURI; } // setEncodingStype /** * Returns the encoding style as a URI that should be used for the SOAP * message. * * @return String URI of the encoding style to use */ public String getEncodingStyle() { return encodingStyle; } // getEncodingStyle public void removeProperty(String propName) { if (bag != null) { bag.remove(propName); } } /** * Return this context to a clean state. */ public void reset() { if (bag != null) { bag.clear(); } serviceHandler = null; havePassedPivot = false; currentOperation = null; } /** * Read the high fidelity property. *

* Some behavior may be apropreate for high fidelity contexts that is not * relevant for low fidelity ones or vica-versa. * * @return true if the context is high fidelity, * false otherwise */ public boolean isHighFidelity() { return highFidelity; } /** * Set the high fidelity propert. *

* Users of the context may be changing what they do based upon this flag. * * @param highFidelity the new value of the highFidelity property */ public void setHighFidelity(boolean highFidelity) { this.highFidelity = highFidelity; } /** * Gets the SOAP actor roles associated with an execution of the * HandlerChain and its contained Handler * instances. *

* Not (yet) implemented method in the SOAPMessageContext interface. *

* Note: SOAP actor roles apply to the SOAP node and are managed * using HandlerChain.setRoles() and * HandlerChain.getRoles(). Handler instances in the * HandlerChain use this information about the SOAP actor roles * to process the SOAP header blocks. Note that the SOAP actor roles are * invariant during the processing of SOAP message through the * HandlerChain. * * @return an array of URIs for SOAP actor roles * @see javax.xml.rpc.handler.HandlerChain#setRoles(java.lang.String[]) HandlerChain.setRoles(java.lang.String[]) * @see javax.xml.rpc.handler.HandlerChain#getRoles() HandlerChain.getRoles() */ public String[] getRoles() { //TODO: Flesh this out. return roles; } /** * Set the SOAP actor roles associated with an executioni of * CodeHandlerChain and its contained Handler * instances. * * @param roles an array of String instances, each representing * the URI for a SOAP actor role */ public void setRoles( String[] roles) { this.roles = roles; } /** * if a message (or subclass) has any disposal needs, this method * is where it goes. Subclasses *must* call super.dispose(), and * be prepared to be called from the finalizer as well as earlier */ public synchronized void dispose() { log.debug("disposing of message context"); if(requestMessage!=null) { requestMessage.dispose(); requestMessage=null; } if(responseMessage!=null) { responseMessage.dispose(); responseMessage=null; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy