/*
 * 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.components.logger.LogFactory;
import org.apache.axis.encoding.TypeMappingRegistry;
import org.apache.axis.encoding.TypeMappingImpl;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.handlers.soap.SOAPService;
import org.apache.axis.session.Session;
import org.apache.axis.session.SimpleSession;
import org.apache.axis.utils.JavaUtils;
import org.apache.axis.utils.Messages;
import org.apache.axis.utils.cache.ClassCache;
import org.apache.commons.logging.Log;

import javax.xml.namespace.QName;
import javax.xml.rpc.server.ServiceLifecycle;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;


/**
 * An <code>AxisEngine</code> is the base class for AxisClient and
 * AxisServer.  Handles common functionality like dealing with the
 * handler/service registries and loading properties.
 *
 * @author Glen Daniels (gdaniels@apache.org)
 * @author Glyn Normington (glyn@apache.org)
 */
public abstract class AxisEngine extends BasicHandler
{
    /**
     * The <code>Log</code> for all message logging.
     */
    protected static Log log =
        LogFactory.getLog(AxisEngine.class.getName());

    // Engine property names
    public static final String PROP_XML_DECL = "sendXMLDeclaration";
    public static final String PROP_DEBUG_LEVEL = "debugLevel";
    public static final String PROP_DEBUG_FILE = "debugFile";
    public static final String PROP_DOMULTIREFS = "sendMultiRefs";
    public static final String PROP_DISABLE_PRETTY_XML = "disablePrettyXML";
    public static final String PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION = "enableNamespacePrefixOptimization";
    public static final String PROP_PASSWORD = "adminPassword";
    public static final String PROP_SYNC_CONFIG = "syncConfiguration";
    public static final String PROP_SEND_XSI = "sendXsiTypes";
    public static final String PROP_ATTACHMENT_DIR = "attachments.Directory";
    public static final String PROP_ATTACHMENT_IMPLEMENTATION  = "attachments.implementation" ;
    public static final String PROP_ATTACHMENT_CLEANUP = "attachment.DirectoryCleanUp";
    public static final String PROP_DEFAULT_CONFIG_CLASS = "axis.engineConfigClass";
    public static final String PROP_SOAP_VERSION = "defaultSOAPVersion";
    public static final String PROP_SOAP_ALLOWED_VERSION = "singleSOAPVersion";
    public static final String PROP_TWOD_ARRAY_ENCODING = "enable2DArrayEncoding";
    public static final String PROP_XML_ENCODING = "axis.xmlEncoding";
    public static final String PROP_XML_REUSE_SAX_PARSERS = "axis.xml.reuseParsers";
    public static final String PROP_BYTE_BUFFER_BACKING = "axis.byteBuffer.backing";
    public static final String PROP_BYTE_BUFFER_CACHE_INCREMENT = "axis.byteBuffer.cacheIncrement";
    public static final String PROP_BYTE_BUFFER_RESIDENT_MAX_SIZE = "axis.byteBuffer.residentMaxSize";
    public static final String PROP_BYTE_BUFFER_WORK_BUFFER_SIZE = "axis.byteBuffer.workBufferSize";
    public static final String PROP_EMIT_ALL_TYPES = "emitAllTypesInWSDL";
    /**
     * Set this property to 'true' when you want Axis to avoid soap encoded
     * types to work around a .NET problem where it wont accept soap encoded
     * types for a (soap encoded!) array.
     */
    public static final String PROP_DOTNET_SOAPENC_FIX = "dotNetSoapEncFix";
    /** Compliance with WS-I Basic Profile. */
    public static final String PROP_BP10_COMPLIANCE = "ws-i.bp10Compliance";

    public static final String DEFAULT_ATTACHMENT_IMPL="org.apache.axis.attachments.AttachmentsImpl";

    public static final String ENV_ATTACHMENT_DIR = "axis.attachments.Directory";
    public static final String ENV_SERVLET_REALPATH = "servlet.realpath";
    public static final String ENV_SERVLET_CONTEXT = "servletContext";

    // Default admin. password
    private static final String DEFAULT_ADMIN_PASSWORD = "admin";


    /** Our go-to guy for configuration... */
    protected EngineConfiguration config;

    /** Has the user changed the password yet? True if they have. */
    protected boolean _hasSafePassword = false;

    /**
     * Should we save the engine config each time we modify it? True if we
     * should.
     */
    protected boolean shouldSaveConfig = false;

    /** Java class cache. */
    protected transient ClassCache classCache = new ClassCache();

    /**
     * This engine's Session.  This Session supports "application scope"
     * in the Apache SOAP sense... if you have a service with "application
     * scope", have it store things in this Session.
     */
    private Session session = new SimpleSession();

    /**
     * What actor URIs hold for the entire engine? Find them here.
     */
    private ArrayList actorURIs = new ArrayList();

    /**
     * Thread local storage used for locating the active message context.
     * This information is only valid for the lifetime of this request.
     */
    private static ThreadLocal currentMessageContext = new ThreadLocal();

    /**
     * Set the active message context.
     *
     * @param mc - the new active message context.
     */
    protected static void setCurrentMessageContext(MessageContext mc) {
        currentMessageContext.set(mc);
    }

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

    /**
     * Construct an AxisEngine using the specified engine configuration.
     *
     * @param config the EngineConfiguration for this engine
     */
    public AxisEngine(EngineConfiguration config)
    {
        this.config = config;
        init();
    }

    /**
     * Initialize the engine. Multiple calls will (may?) return the engine to
     * the intialized state.
     */
    public void init() {
        if (log.isDebugEnabled()) {
            log.debug("Enter: AxisEngine::init");
        }

        // The SOAP/XSD stuff is in the default TypeMapping of the TypeMappingRegistry.
        //getTypeMappingRegistry().setParent(SOAPTypeMappingRegistry.getSingletonDelegate());

        try {
            config.configureEngine(this);
        } catch (Exception e) {
            throw new InternalException(e);
        }

        /*Set the default attachment implementation */
        setOptionDefault(PROP_ATTACHMENT_IMPLEMENTATION,
                         AxisProperties.getProperty("axis." + PROP_ATTACHMENT_IMPLEMENTATION  ));

        setOptionDefault(PROP_ATTACHMENT_IMPLEMENTATION, DEFAULT_ATTACHMENT_IMPL);

        // Check for the property "dotnetsoapencfix" which will turn
        // off soap encoded types to work around a bug in .NET where
        // it wont accept soap encoded array types.
        final Object dotnet = getOption(PROP_DOTNET_SOAPENC_FIX);
        if (JavaUtils.isTrue(dotnet)) {
            // This is a static property of the type mapping
            // that will ignore SOAPENC types when looking up
            // QNames of java types.
            TypeMappingImpl.dotnet_soapenc_bugfix = true;
        }

        if (log.isDebugEnabled()) {
            log.debug("Exit: AxisEngine::init");
        }

    }

    /**
     * Cleanup routine removes application scoped objects.
     *
     * There is a small risk of this being called more than once
     * so the cleanup should be designed to resist that event.
     */
    public void cleanup() {
        super.cleanup();

        // Let any application-scoped service objects know that we're going
        // away...
        Enumeration keys = session.getKeys();
        if (keys != null) {
            while (keys.hasMoreElements()) {
                String key = (String)keys.nextElement();
                Object obj = session.get(key);
                if (obj != null && obj instanceof ServiceLifecycle) {
                    ((ServiceLifecycle)obj).destroy();
                }
                session.remove(key);
            }
        }
    }

    /** Write out our engine configuration.
     */
    public void saveConfiguration()
    {
        if (!shouldSaveConfig)
            return;

        try {
            config.writeEngineConfig(this);
        } catch (Exception e) {
            log.error(Messages.getMessage("saveConfigFail00"), e);
        }
    }

    /**
     * Get the <code>EngineConfiguration</code> used throughout this
     * <code>AxisEngine</code> instance.
     *
     * @return the engine configuration instance
     */
    public EngineConfiguration getConfig() {
        return config;
    }

    /**
     * Discover if this <code>AxisEngine</code> has a safe password.
     *
     * @return  true if it is safe, false otherwise
     */
    public boolean hasSafePassword()
    {
        return _hasSafePassword;
    }

    /**
     * Set the administration password.
     *
     * @param pw  the literal value of the password as a <code>String</code>
     */
    public void setAdminPassword(String pw)
    {
        setOption(PROP_PASSWORD, pw);
        _hasSafePassword = true;
        saveConfiguration();
    }

    /**
     * Set the flag that controls if the configuration should be saved.
     *
     * @param shouldSaveConfig  true if the configuration should be changed,
     *              false otherwise
     */
    public void setShouldSaveConfig(boolean shouldSaveConfig)
    {
        this.shouldSaveConfig = shouldSaveConfig;
    }

    // fixme: could someone who knows double-check I've got the semantics of
    //   this right?
    /**
     * Get the <code>Handler</code> for a particular local name.
     *
     * @param name  the local name of the request type
     * @return      the <code>Handler</code> for this request type
     * @throws AxisFault
     */
    public Handler getHandler(String name) throws AxisFault
    {
        try {
            return config.getHandler(new QName(null, name));
        } catch (ConfigurationException e) {
            throw new AxisFault(e);
        }
    }

    // fixme: could someone who knows double-check I've got the semantics of
    //   this right?
    /**
     * Get the <code>SOAPService</code> for a particular local name.
     *
     * @param name  the local name of the request type
     * @return      the <code>SOAPService</code> for this request type
     * @throws AxisFault
     */
    public SOAPService getService(String name) throws AxisFault
    {
        try {
            return config.getService(new QName(null, name));
        } catch (ConfigurationException e) {
            try {
                return config.getServiceByNamespaceURI(name);
            } catch (ConfigurationException e1) {
                throw new AxisFault(e);
            }
        }
    }

    /**
     * Get the <code>Handler</code> that implements the transport for a local
     * name.
     *
     * @param name  the local name to fetch the transport for
     * @return  a <code>Handler</code> for this local name
     * @throws AxisFault
     */
    public Handler getTransport(String name) throws AxisFault
    {
        try {
            return config.getTransport(new QName(null, name));
        } catch (ConfigurationException e) {
            throw new AxisFault(e);
        }
    }

    /**
     * Get the <code>TypeMappingRegistry</code> for this axis engine.
     *
     * @return the <code>TypeMappingRegistry</code> if possible, or null if
     *              there is any error resolving it
     */
    public TypeMappingRegistry getTypeMappingRegistry()
    {
        TypeMappingRegistry tmr = null;
        try {
            tmr = config.getTypeMappingRegistry();
        } catch (ConfigurationException e) {
            log.error(Messages.getMessage("axisConfigurationException00"), e);
        }

        return tmr;
    }

    /**
     * Get the global request <code>Handler</code>.
     *
     * @return the <code>Handler</code> used for global requests
     * @throws ConfigurationException
     */
    public Handler getGlobalRequest()
        throws ConfigurationException
    {
        return config.getGlobalRequest();
    }

    /**
     * Get the global respones <code>Handler</code>.
     *
     * @return the <code>Handler</code> used for global responses
     * @throws ConfigurationException
     */
    public Handler getGlobalResponse()
        throws ConfigurationException
    {
        return config.getGlobalResponse();
    }

    // fixme: publishing this as ArrayList prevents us moving to another
    //   List impl later
    /**
     * Get a list of actor URIs that hold for the entire engine.
     *
     * @return an <code>ArrayList</code> of all actor URIs as
     *              <code>Strings</code>
     */
    public ArrayList getActorURIs()
    {
        return (ArrayList)actorURIs.clone();
    }

    /**
     * Add an actor by uri that will hold for the entire engine.
     *
     * @param uri  a <code>String</code> giving the uri of the actor to add
     */
    public void addActorURI(String uri)
    {
        actorURIs.add(uri);
    }

    /**
     * Remove an actor by uri that will hold for the entire engine.
     *
     * @param uri  a <code>String</code> giving the uri of the actor to remove
     */
    public void removeActorURI(String uri)
    {
        actorURIs.remove(uri);
    }

    /**
     * Client engine access.
     * <p>
     * An AxisEngine may define another specific AxisEngine to be used
     * by newly created Clients.  For instance, a server may
     * create an AxisClient and allow deployment to it.  Then
     * the server's services may access the AxisClient's deployed
     * handlers and transports.
     *
     * @return an <code>AxisEngine</code> that is the client engine
     */

    public abstract AxisEngine getClientEngine ();

   /**
    * Administration and management APIs
    *
    * These can get called by various admin adapters, such as JMX MBeans,
    * our own Admin client, web applications, etc...
    *
    */

    /**
     * List of options which should be converted from Strings to Booleans
     * automatically. Note that these options are common to all XML
     * web services.
     */
    private static final String [] BOOLEAN_OPTIONS = new String [] {
                        PROP_DOMULTIREFS, PROP_SEND_XSI, PROP_XML_DECL,
                        PROP_DISABLE_PRETTY_XML,
                        PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION
    };

    /**
     * Normalise the engine's options.
     * <p>
     * Convert boolean options from String to Boolean and default
     * any ommitted boolean options to TRUE. Default the admin.
     * password.
     *
     * @param handler  the <code>Handler</code> to normalise; instances of
     *              <code>AxisEngine</code> get extra data normalised
     */
    public static void normaliseOptions(Handler handler) {
        // Convert boolean options to Booleans so we don't need to use
        // string comparisons.  Default is "true".

        for (int i = 0; i < BOOLEAN_OPTIONS.length; i++) {
            Object val = handler.getOption(BOOLEAN_OPTIONS[i]);
            if (val != null) {
                if (val instanceof Boolean)
                    continue;
                if (JavaUtils.isFalse(val)) {
                    handler.setOption(BOOLEAN_OPTIONS[i], Boolean.FALSE);
                    continue;
                }
            } else {
                if (!(handler instanceof AxisEngine))
                    continue;
            }
            // If it was null or not "false"...
            handler.setOption(BOOLEAN_OPTIONS[i], Boolean.TRUE);
        }

        // Deal with admin password's default value.
        if (handler instanceof AxisEngine) {
            AxisEngine engine = (AxisEngine)handler;
            if (!engine.setOptionDefault(PROP_PASSWORD,
                                         DEFAULT_ADMIN_PASSWORD)) {
                engine.setAdminPassword(
                        (String)engine.getOption(PROP_PASSWORD));
            }
        }
    }

    /**
     * (Re-)load the global options from the registry.
     *
     * @throws ConfigurationException
     */
    public void refreshGlobalOptions() throws ConfigurationException {
        Hashtable globalOptions = config.getGlobalOptions();
        if (globalOptions != null)
            setOptions(globalOptions);

        normaliseOptions(this);

        // fixme: If we change actorURIs to List, this copy constructor can
        //        go away...
        actorURIs = new ArrayList(config.getRoles());
    }

    /**
     * Get the <code>Session</code> object associated with the application
     * session.
     *
     * @return a <code>Session</code> scoped to the application
     */
    public Session getApplicationSession () {
        return session;
    }

    /**
     * Get the <code>ClassCache</code> associated with this engine.
     *
     * @return the class cache
     */
    public ClassCache getClassCache() {
        return classCache;
    }

}
