/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * ObjectWeb Connector: an implementation of JCA Sun specification along
 *                      with some extensions of this specification.
 * Copyright (C) 2001-2002 France Telecom R&D - INRIA
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Release: 1.0
 *
 * Author: E. Hardesty
 *
 * Based on Pool api in ObjectWeb common
 *
 */

/**
 * Package definition.
 */
package org.objectweb.jonas.resource.pool.api;

import javax.resource.spi.ManagedConnection;
import javax.transaction.Transaction;
import java.util.Map;

/**
 * The interface <b>Pool</b> defines an object that pools resources of any
 * kind. Resources must be requested (getResource) and released
 * (releaseResource) on demand. A Pool object can be parameterized along
 * different dimensions. All these dimensions are represented by accessor
 * methods (getters and setters) assigned to each of them:
 * <ul>
 * <li>
 * A <b>Timeout</b> can be assigned to a Pool. It is used when no more
 * resources are available and when the Pool has reached its maximum size.
 * This is the timeout to wait for a free resource until exiting with an
 * exception. It defaults to 0, which means waiting forever until a
 * resource is freed. Its value should be greater or equal to 0 ; negative
 * values are ignored (setTimeOut(-1) => NOP).
 * </li>
 * <li>
 * A <b>MinSize</b> can be assigned to a Pool. Its value should be greater or
 * equal to 0, and smaller or equal to MaxSize. Values that do not match these
 * conditions are ignored (e.g., setMinSize(-1) => NOP).
 * This size means that there is always MinSize PoolResource allocated in this
 * Pool. If PoolResource needs to be allocated when setting this size,
 * "getPoolMatchFactory().createResource(null)" is called. Its default value
 * is 0.
 * </li>
 * <li>
 * A <b>MatchFactory</b> (i.e., a PoolMatchFactory object) must be assigned to
 * a Pool. It defines the way new PoolResource are created and the way a
 * PoolResource of a Pool matches some "hints" properties when requested. It is
 * mandatory for the Pool to be fully functional.
 * </li>
 * <li>
 * A <b>MaxSize</b> can be assigned to a Pool. Its value should be greater or
 * equal to 0, and greater or equal to MinSize. Values that do not match these
 * conditions are ignored (e.g., setMaxSize(-1) => NOP). Its default value
 * is 0, thus it is mandatory to set this value for making the Poll functional.
 * </li>
 * </ul>
 */
public interface Pool {
    /**
     * <b>adjust</b> checks the age of the entries and removes them if
     * they are too old
     *
     * @throws Exception if an error occurs
     */
    void adjust() throws Exception;

    /**
     * Close all connections in the pool when server is shutting down.
     */
    void closeAllConnections();

    /**
     * <b>getJdbcConnLevel</b> gets the jdbc connection level
     *
     * @return int jdbc connection level specified
     */
    public int getJdbcConnLevel();

    /**
     * <b>getJdbcTestStatement</b> gets the JDBC test statement for this pool
     *
     * @return String JDBC test statement
     */
    public String getJdbcTestStatement();
    
    /**
     * <b>getMatchFactory</b> retrieves the PoolMatchFactory assigned to this
     * Pool.
     * @return        The PoolMatchFactory currently assigned to this Pool.
     */
    PoolMatchFactory getMatchFactory();

    /**
     * <b>getMaxAge</b> gets the max age for a pool entry
     *
     * @return int max number of minutes to keep a connection
     *              in the pool.
     */
    int getMaxAge();

    /**
     * <b>getMaxOpentime</b> gets the max age for a pool entry
     *
     * @return int max number of minutes to keep a connection
     *              in the pool.
     */
    int getMaxOpentime();

    /**
     * <b>getMaxSize</b> retrieves the maximum size assigned to this Pool.
     * @return        The maximum size currently assigned to this Pool.
     */
    int getMaxSize();

    /**
     * <b>getMaxWaiters</b> gets the maximum number of waiters for a connection
     *    in this Pool.
     *
     * @return int maximum number of waiters
     */
    int getMaxWaiters();

    /**
     * <b>getMaxWaitTime</b> gets the maximum number of seconds to wait for a
     *    connection in this Pool.
     *
     * @return int maximum number of seconds to wait
     */
    int getMaxWaitTime();

    /**
     * <b>getMinSize</b> retrieves the minimum size assigned to this Pool.
     * @return        The minimum size currently assigned to this Pool.
     */
    int getMinSize();

    /**
     * <b>getResource</b> is used to allocate a Object from the Pool.
     * Some hints are passed in order to specialise the matching or creation
     * of Object.
     * @param hints        Some properties to specialise the matching or the creation
     *                                of Object.
     * @return                The Object allocated from the Pool.
     * @throws Exception if an error occurs
     */
    Object getResource(Object hints) throws Exception;

    /**
     * <b>getSamplingPeriod</b> gets the number of seconds between statistics
     *    sampling for this Pool.
     *
     * @return int number of seconds between samplings
     */
    int getSamplingPeriod();

    /**
     * <b>getTimeout</b> retrieves the timeout assigned to this Pool.
     * @return        The timeout currently assigned to this Pool.
     */
    long getTimeout();

    /**
     * <b>getSize</b> retrieves the current size of this Pool.
     * @return        The current size of this Pool.
     */
    int getSize();

    /**
     * @return init The pool init size.
     */
    int getInitSize();

    /**
     * <b>releaseResource</b> releases a Object in order to allow the
     * Pool to recycle this Object.
     * @param resource        The Object to be released.
     * @param destroy         boolean to remove the object from the pool and
     *                         destroy it
     * @param adjustment      boolean to determine if a pool adjustment should be done
     * @throws Exception if an error occurs
     */
    void releaseResource(Object resource, boolean destroy, boolean adjustment) throws Exception;

    /**
     * <b>sampling</b> updates the interval pool information
     *
     * @throws Exception if an error occurs
     */
    void sampling() throws Exception;

    /**
     * <b>setInitSize</b> creates initsize resoures to this Pool.
     *
     * @param initsize       The init size to be created.
     * @throws Exception if an error occurs
     */
    void setInitSize(int initsize) throws Exception;

    /**
     * <b>setJdbcConnLevel</b> sets the JDBC connection level for this pool
     *
     * @param jdbcConnLevel  int JDBC connection level
     */
    public void setJdbcConnLevel(int jdbcConnLevel);
    
    /**
     * <b>setJdbcTestStatement</b> sets the JDBC test statement for this pool
     *
     * @param jdbcTestStatement  String JDBC test statement
     */
    public void setJdbcTestStatement(String jdbcTestStatement);
    
    /**
     * <b>setMatchFactory</b> assigns a PoolMatchFactory to this Pool.
     *
     * @param pmf                The PoolMatchFactory to be assigned.
     */
    void setMatchFactory(PoolMatchFactory pmf);

    /**
     * <b>setMaxAge</b> sets the max age for a pool entry
     *
     * @param maxAge int max number of minutes to keep a connection
     *                      in the pool.
     */
    void setMaxAge(int maxAge);

    /**
     * <b>setMaxOpentime</b> sets the max age for an entry to be opened
     *
     * @param maxOpentime int max number of minutes to keep a connection
     *                      opened.
     */
    void setMaxOpentime(int maxOpentime);

    /**
     * <b>setMaxSize</b> assigns a maximum size to this Pool.
     *
     * @param maxsize int maximum size to be assigned.
     * @throws Exception if an error occurs
     */
    void setMaxSize(int maxsize) throws Exception;

    /**
     * <b>setMaxWaiters</b> sets the maximum number of waiters for a connection
     *    in this Pool.
     *
     * @param maxWaiters int maximum number of waiters
     */
    void setMaxWaiters(int maxWaiters);

    /**
     * <b>setMaxWaitTime</b> sets the maximum number of seconds to wait for a
     *    connection in this Pool.
     *
     * @param maxWaitTime int maximum number of seconds to wait
     */
    void setMaxWaitTime(int maxWaitTime);

    /**
     * <b>setMinSize</b> assigns a minimum size to this Pool.
     *
     * @param minsize  int minimum size to be assigned.
     * @throws Exception if an error occurs
     */
    void setMinSize(int minsize) throws Exception;

    /**
     * <b>setSamplingPeriod</b> sets the number of seconds between statistics
     *    sampling for this Pool.
     *
     * @param samplingPeriod int number of seconds between samplings
     */
    void setSamplingPeriod(int samplingPeriod);

    /**
     * <b>setTimeout</b> assigns a timeout to this Pool.
     *
     * @param crto long timeout to be assigned.
     */
    void setTimeout(long crto);

    /**
     * <b>startMonitor</b> starts the pool monitor for this Pool.
     *
     */
    void startMonitor();

    /**
     * <b>validateMCs</b> validates ManagedConnections in Pool every 10 minutes
     *
     * @throws Exception if an error occurs
     */
    void validateMCs() throws Exception;

    /* Statistics area */
    /**
     * @return int number of busy connections
     */
    public int getCurrentBusy();

    /**
     * @return int number of opened connections
     */
    public int getCurrentOpened();

    /**
     * @return maximum nb of busy connections in last sampling period
     */
    int getBusyMaxRecent();

    /**
     * @return minimum nb of busy connections in last sampling period
     */
    int getBusyMinRecent();

    /**
     * @return current number of connection waiters
     */
    int getCurrentWaiters();

    /**
     * @return int number of physical jdbc connection opened
     */
    int getOpenedCount();

    /**
     * @return int number of connection failures on open
     */
    int getConnectionFailures();

    /**
     * @return int number of connection leaks
     */
    int getConnectionLeaks();

    /**
     * @return int number of connection served
     */
    int getServedOpen();

    /**
     * @return int number of open calls that were rejected due to waiter overflow
     */
    int getRejectedFull();

    /**
     * @return int number of open calls that were rejected by timeout
     */
    int getRejectedTimeout();

    /**
     * @return int number of open calls that were rejected
     */
    int getRejectedOther();

    /**
     * @return int number of open calls that were rejected
     */
    int getRejectedOpen();

    /**
     * @return maximum nb of waiters since the datasource creation
     */
    int getWaitersHigh();

    /**
     * @return maximum nb of waiters in last sampling period
     */
    int getWaitersHighRecent();

    /**
     * @return total nb of waiters since the datasource creation
     */
    int getWaiterCount();

    /**
     * @return total waiting time since the datasource creation
     */
    long getWaitingTime();

    /**
     * @return max waiting time since the datasource creation
     */
    long getWaitingHigh();

    /**
     * @return max waiting time in last sampling period
     */
    long getWaitingHighRecent();

    /**
     * force the close of the Connection identified by ots Id
     * @param connectionId int that represent the Connection
     */
    public void forceCloseConnection(final int connectionId);

    /**
     * return a list of idents that represent the connections
     * opened for a given nb of seconds
     * @param usedTimeMs nb of milliseconds the Connection has been opened
     * @return array of idents representing the Connections
     */
    public int[] getOpenedConnections(final long usedTimeMs);

    /**
     * Return the ManagedConnection identified by this Id
     * @param connectionId Ident that represent the connection
     * @return the Managed Connection
     */
    public ManagedConnection getConnectionById(int connectionId);

    /**
     * Return a Map with details about a Connection
     * @param mc the connection
     * @param tx Transaction associated to this Connection, or null.
     * @return map given the details about this connection.
     */
    public Map getConnectionDetails(ManagedConnection mc, Transaction tx);

    /**
     * Set the pool observable
     * @param obs = true if keep stack traces at open
     */
    public void setObservable(boolean obs);
}


