/*
 * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/params/HttpConnectionManagerParams.java,v 1.9 2004/09/13 16:25:20 olegk Exp $
 * $Revision: 480424 $
 * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
 *
 * ====================================================================
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.commons.httpclient.params;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;

/**
 * This class represents a collection of HTTP protocol parameters applicable to 
 * {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection managers}. 
 * Protocol parameters may be linked together to form a hierarchy. If a particular 
 * parameter value has not been explicitly defined in the collection itself, its 
 * value will be drawn from the parent collection of parameters.
 * 
 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
 * @author Michael Becke
 * 
 * @version $Revision: 480424 $
 * 
 * @since 3.0
 */
public class HttpConnectionManagerParams extends HttpConnectionParams {

    /** 
     * Defines the maximum number of connections allowed per host configuration. 
     * These values only apply to the number of connections from a particular instance 
     * of HttpConnectionManager.
     * <p>
     * This parameter expects a value of type {@link java.util.Map}.  The value
     * should map instances of {@link org.apache.commons.httpclient.HostConfiguration}
     * to {@link Integer integers}.  The default value can be specified using
     * {@link org.apache.commons.httpclient.HostConfiguration#ANY_HOST_CONFIGURATION}.
     * </p>
     */
    public static final String MAX_HOST_CONNECTIONS = "http.connection-manager.max-per-host";

    /** 
     * Defines the maximum number of connections allowed overall. This value only applies
     * to the number of connections from a particular instance of HttpConnectionManager.
     * <p>
     * This parameter expects a value of type {@link Integer}.
     * </p>
     */
    public static final String MAX_TOTAL_CONNECTIONS = "http.connection-manager.max-total";
    
    /**
     * Sets the default maximum number of connections allowed for a given
     * host config.
     *
     * @param maxHostConnections The default maximum.
     * 
     * @see #MAX_HOST_CONNECTIONS
     */
    public void setDefaultMaxConnectionsPerHost(int maxHostConnections) {
        setMaxConnectionsPerHost(HostConfiguration.ANY_HOST_CONFIGURATION, maxHostConnections);
    }

    /**
     * Sets the maximum number of connections to be used for the given host config.
     * 
     * @param hostConfiguration The host config to set the maximum for.  Use 
     * {@link HostConfiguration#ANY_HOST_CONFIGURATION} to configure the default value
     * per host.
     * @param maxHostConnections The maximum number of connections, <code>> 0</code>
     * 
     * @see #MAX_HOST_CONNECTIONS
     */
    public void setMaxConnectionsPerHost(
        HostConfiguration hostConfiguration,
        int maxHostConnections) {
        
        if (maxHostConnections <= 0) {
            throw new IllegalArgumentException("maxHostConnections must be greater than 0");
        }
        
        Map currentValues = (Map) getParameter(MAX_HOST_CONNECTIONS);
        // param values are meant to be immutable so we'll make a copy
        // to modify
        Map newValues = null;
        if (currentValues == null) {
            newValues = new HashMap();
        } else {
            newValues = new HashMap(currentValues);
        }
        newValues.put(hostConfiguration, new Integer(maxHostConnections));
        setParameter(MAX_HOST_CONNECTIONS, newValues);
    }
    
    /**
     * Gets the default maximum number of connections allowed for a given
     * host config.
     *
     * @return The default maximum.
     * 
     * @see #MAX_HOST_CONNECTIONS
     */
    public int getDefaultMaxConnectionsPerHost() {
        return getMaxConnectionsPerHost(HostConfiguration.ANY_HOST_CONFIGURATION);
    }

    /**
     * Gets the maximum number of connections to be used for a particular host config.  If
     * the value has not been specified for the given host the default value will be
     * returned.
     * 
     * @param hostConfiguration The host config.
     * @return The maximum number of connections to be used for the given host config.
     * 
     * @see #MAX_HOST_CONNECTIONS
     */
    public int getMaxConnectionsPerHost(HostConfiguration hostConfiguration) {
        
        Map m = (Map) getParameter(MAX_HOST_CONNECTIONS);
        if (m == null) {
            // MAX_HOST_CONNECTIONS have not been configured, using the default value
            return MultiThreadedHttpConnectionManager.DEFAULT_MAX_HOST_CONNECTIONS;
        } else {
            Integer max = (Integer) m.get(hostConfiguration);
            if (max == null && hostConfiguration != HostConfiguration.ANY_HOST_CONFIGURATION) {
                // the value has not been configured specifically for this host config,
                // use the default value
                return getMaxConnectionsPerHost(HostConfiguration.ANY_HOST_CONFIGURATION);
            } else {
                return (
                        max == null 
                        ? MultiThreadedHttpConnectionManager.DEFAULT_MAX_HOST_CONNECTIONS 
                        : max.intValue()
                    );
            }
        }
    }

    /**
     * Sets the maximum number of connections allowed.
     *
     * @param maxTotalConnections The maximum number of connections allowed.
     * 
     * @see #MAX_TOTAL_CONNECTIONS
     */
    public void setMaxTotalConnections(int maxTotalConnections) {
        setIntParameter(
            HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS,
            maxTotalConnections);
    }

    /**
     * Gets the maximum number of connections allowed.
     *
     * @return The maximum number of connections allowed.
     * 
     * @see #MAX_TOTAL_CONNECTIONS
     */
    public int getMaxTotalConnections() {
        return getIntParameter(
            HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS,
            MultiThreadedHttpConnectionManager.DEFAULT_MAX_TOTAL_CONNECTIONS);
    }

}
