/*
 * 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 (dug@us.ibm.com)
 * @author Jacek Kopecky (jacek@idoox.com)
 */
public class MessageContext implements SOAPMessageContext {
    /** The <code>Log</code> 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 <code>ClassLoader</code> 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 <code>null</code>
     */
    public  OperationDesc getOperation()
    {
        return currentOperation;
    }

    /**
     * Set the current operation.
     *
     * @param operation  the <code>Operation</code> 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 <code>TypeMappingRegistry</code>
     */
    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 <code>SOAPConstants</code> used by this message context.
     *
     * @return the soap constants
     */
    public SOAPConstants getSOAPConstants() {
        return soapConstants;
    }

    /**
     * Set the <code>SOAPConstants</code> 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 <code>SchemaVersion</code> in use
     */
    public SchemaVersion getSchemaVersion() {
        return schemaVersion;
    }

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

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

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

    /**
     * Indicates if the opration is encoded.
     *
     * @return <code>true</code> if it is encoded, <code>false</code> 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 <code>true</code> to maintain sessions
     */
    public void setMaintainSession (boolean yesno) {
        maintainSession = yesno;
    }

    /**
     * Discover if we are maintaining session state.
     *
     * @return <code>true</code> if we are maintaining state, <code>false</code>
     *              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 <code>Message</code>
     */
    public Message getCurrentMessage()
    {
        return (havePassedPivot ? responseMessage : requestMessage);
    }

    /**
     *  Gets the SOAPMessage from this message context.
     *
     *  @return the <code>SOAPMessage</code>, <code>null</code> if no request
     *          <code>SOAPMessage</code> is present in this
     *          <code>SOAPMessageContext</code>
     */
    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 <code>Message</code> to assign
     */
    public void setCurrentMessage(Message curMsg)
    {
        curMsg.setMessageContext(this);

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

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

    /**
     * Determine when we've passed the pivot.
     *
     * @return <code>true</code> if we have, <code>false</code> 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 <code>ClassLoader</code> or <code>null</code>
     */
    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 <code>null</code> 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.
     * <p>
     * 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 <code>SOAPService</code> used to handle services in this
     * context.
     *
     * @return the service handler
     */
    public SOAPService getService() {
        return  serviceHandler;
    }

    /**
     * Set the <code>SOAPService</code> used to handle services in this
     * context. This method configures a wide range of
     * <code>MessageContext</code> 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 <code>String</code> 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
     *              <code>String</code> value
     */
    public String getStrProp(String propName) {
        return (String) getProperty(propName);
    }

    /**
     * Tests to see if the named property is set in the 'bag', returning
     * <code>false</code> if it is not present at all.
     * This is equivalent to <code>isPropertyTrue(propName, false)</code>.
     *
     * @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'.
     * <ul>
     * <li>If not there then <code>defaultVal</code> is returned.</li>
     * <li>If there, then...<ul>
     *   <li>if its a <code>Boolean</code>, we'll return booleanValue()</li>
     *   <li>if its an <code>Integer</code>,  we'll return <code>false</code>
     *   if its <code>0</code> else <code>true</code></li>
     *   <li>if its a <code>String</code> we'll return <code>false</code> if its
     *   <code>"false"</code>" or <code>"0"</code> else <code>true</code></li>
     *   <li>All other types return <code>true</code></li>
     * </ul></li>
     * </ul>
     *
     * @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 <code>Iterator</code> view of the names of the properties in
     * this <code>MessageContext</code>.
     *
     * @return an <code>Iterator</code> 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 <code>String</code>
     */
    public String getUsername() {
        return username;
    } // getUsername

    /**
     * Set the password.
     *
     * @param password  a <code>String</code> containing the new password
     */
    public void setPassword(String password) {
        this.password = password;
    } // setPassword

    /**
     * Get the password.
     *
     * @return the current password <code>String</code>
     */
    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, <code>Style.RPC</code>.
     *
     * @return the <code>Style</code> 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 <code>Use</code>
     */
    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  <code>true</code> if soap action URI information
     *              should be used, <code>false</code> 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 <code>true</code> if it is, <code>false</code> 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 <code>String</code> 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.
     * <p>
     * Some behavior may be apropreate for high fidelity contexts that is not
     * relevant for low fidelity ones or vica-versa.
     *
     * @return <code>true</code> if the context is high fidelity,
     *              <code>false</code> otherwise
     */
    public boolean isHighFidelity() {
        return highFidelity;
    }

    /**
     * Set the high fidelity propert.
     * <p>
     * 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
     * <code>HandlerChain</code> and its contained <code>Handler</code>
     * instances.
     * <p>
     * <i>Not (yet) implemented method in the SOAPMessageContext interface</i>.
     * <p>
     * <b>Note:</b> SOAP actor roles apply to the SOAP node and are managed
     * using <code>HandlerChain.setRoles()</code> and
     * <code>HandlerChain.getRoles()</code>. Handler instances in the
     * <code>HandlerChain</code> 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
     * <code>HandlerChain</code>.
     *
     * @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
     * <code>CodeHandlerChain</code> and its contained <code>Handler</code>
     * instances.
     *
     * @param roles an array of <code>String</code> 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;
        }
    }
}
