/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */

package com.sun.enterprise.connectors;

import com.sun.enterprise.util.Utility;
import com.sun.enterprise.repository.J2EEResourceBase;
import com.sun.enterprise.repository.J2EEResource;
import java.io.Serializable;
import java.util.Iterator;
import com.sun.enterprise.deployment.EnvironmentProperty;
import com.sun.enterprise.connectors.authentication.ConnectorSecurityMap;

/**
 * This class abstracts a connection connection pool. It contains 
 * two parts 
 * 1) Connector Connection Pool properties. 
 * 2) ConnectorDescriptorInfo which contains some of the values of ra.xml 
 *    pertaining to managed connection factory class
 *    
 * @author Srikanth Padakandla 
 */

public class ConnectorConnectionPool extends J2EEResourceBase 
                                      implements Serializable {
    
    protected ConnectorDescriptorInfo connectorDescriptorInfo_ ;

    protected String steadyPoolSize_;
    protected String maxPoolSize_;
    protected String maxWaitTimeInMillis_;
    protected String poolResizeQuantity_;
    protected String idleTimeoutInSeconds_;
    protected boolean failAllConnections_;
    //This property will *always* initially be set to:
    // true - by ConnectorConnectionPoolDeployer
    // false - by JdbcConnectionPoolDeployer
    protected boolean matchConnections_ = false;

    protected int transactionSupport_;
    protected boolean isConnectionValidationRequired_ = false;

    private boolean lazyConnectionAssoc_ = false;
    private boolean lazyConnectionEnlist_ = false;
    private boolean associateWithThread_ = false;
    private boolean nonTransactional_ = false;
    private boolean nonComponent_ = false;
    private boolean connectionLeakTracing_ = false;
    private ConnectorSecurityMap[] securityMaps = null;
    private boolean isAuthCredentialsDefinedInPool_ = false;

    //To validate a Sun RA Pool Connection if it hasnot been validated in the past x sec. (x=idle-timeout)
    //The property will be set from system property - com.sun.enterprise.connectors.ValidateAtmostEveryIdleSecs=true
    private boolean validateAtmostEveryIdleSecs = false;
    

    /** Constructor
     *  @param name Name of the connector connection pool
     */

    public ConnectorConnectionPool(String name) {
        super(name);
    }
    
    /** Clone method.
     */ 

    protected J2EEResource doClone(String name) {

        ConnectorConnectionPool clone = new ConnectorConnectionPool(name);
        ConnectorDescriptorInfo cdi = connectorDescriptorInfo_.doClone();
        clone.setSecurityMaps(this.securityMaps);
        clone.setSteadyPoolSize(getSteadyPoolSize());
        clone.setMaxPoolSize(getMaxPoolSize());
        clone.setMaxWaitTimeInMillis(getMaxWaitTimeInMillis());
        clone.setPoolResizeQuantity(getPoolResizeQuantity());
        clone.setIdleTimeoutInSeconds(getIdleTimeoutInSeconds());
        clone.setFailAllConnections(isFailAllConnections());
        clone.setMatchConnections(matchConnections());
	clone.setTransactionSupport( getTransactionSupport());
        clone.setConnectorDescriptorInfo(cdi);
	clone.setConnectionValidationRequired( isConnectionValidationRequired_ );
	clone.setLazyConnectionAssoc( isLazyConnectionAssoc() );
	clone.setAssociateWithThread( isAssociateWithThread() );
	clone.setNonComponent( isNonComponent() );
	clone.setNonTransactional( isNonTransactional() );
	clone.setConnectionLeakTracing( isConnectionLeakTracing() );

        return clone;
    }

    public void setAuthCredentialsDefinedInPool(boolean authCred) {
        this.isAuthCredentialsDefinedInPool_ = authCred;
    }

    public boolean getAuthCredentialsDefinedInPool() {
        return this.isAuthCredentialsDefinedInPool_;
    }

    /**
     * Getter method of ConnectorDescriptorInfo which contains some the ra.xml 
     * values pertainining to managed connection factory 
     * @return ConnectorDescriptorInfo which contains ra.xml values
     *        pertaining to managed connection factory
     */

    public ConnectorDescriptorInfo getConnectorDescriptorInfo() {
        return connectorDescriptorInfo_;
    }
   
    /**
     * Setter method of ConnectorDescriptorInfo which contains some the ra.xml 
     * values pertainining to managed connection factory 
     * @param ConnectorDescriptorInfo which contains ra.xml values
     *        pertaining to managed connection factory
     */
    
    public void setConnectorDescriptorInfo(
                   ConnectorDescriptorInfo connectorDescriptorInfo) 
    {
        connectorDescriptorInfo_ = connectorDescriptorInfo;
    }

    /**
     * Getter method of the Resource Type.
     * @return Resource type
     */

    public int getType() {
        return J2EEResource.JDBC_CONNECTION_POOL;
    }
   
    /**
     * Getter method of SteadyPoolSize property
     * @return Steady Pool Size value
     */

    public String getSteadyPoolSize() {
        return steadyPoolSize_;
    }
    
    /**
     * Setter method of SteadyPoolSize property
     * @param steadyPoolSize  Steady pool size value
     */

    public void setSteadyPoolSize(String steadyPoolSize) {
        steadyPoolSize_ = steadyPoolSize;
    }

    /**
     * Getter method of MaxPoolSize property
     * @return maximum Pool Size value
     */

    public String getMaxPoolSize() {
        return maxPoolSize_;
    }

    /**
     * Setter method of MaxPoolSize property
     * @param maxPoolSize  maximum pool size value
     */

    public void setMaxPoolSize(String maxPoolSize) {
        maxPoolSize_ = maxPoolSize;
    }

    /**
     * Getter method of MaxWaitTimeInMillis property
     * @return maximum wait time in milli value
     */

    public String getMaxWaitTimeInMillis() {
        return maxWaitTimeInMillis_;
    }
    
    /**
     * Setter method of MaxWaitTimeInMillis property
     * @param maxWaitTimeInMillis  maximum wait time in millis value
     */

    public void setMaxWaitTimeInMillis(String maxWaitTimeInMillis) {
        maxWaitTimeInMillis_ = maxWaitTimeInMillis;
    }

    /**
     * Getter method of PoolResizeQuantity property
     * @return pool resize quantity value
     */

    public String getPoolResizeQuantity() {
        return poolResizeQuantity_;
    }
    
    /**
     * Setter method of PoolResizeQuantity property
     * @param poolResizeQuantity  pool resize quantity value
     */

    public void setPoolResizeQuantity(String poolResizeQuantity) {
        poolResizeQuantity_ = poolResizeQuantity;
    }

    /**
     * Getter method of IdleTimeoutInSeconds property
     * @return idle Timeout in seconds value
     */

    public String getIdleTimeoutInSeconds() {
        return idleTimeoutInSeconds_;
    }
    
    /**
     * Setter method of IdleTimeoutInSeconds property
     * @param idleTimeoutInSeconds  Idle timeout in seconds value
     */

    public void setIdleTimeoutInSeconds(String idleTimeoutInSeconds) {
        idleTimeoutInSeconds_ = idleTimeoutInSeconds;
    }
    
    /**
     * Getter method of FailAllConnections property
     * @return whether to fail all connections or not 
     */

    public boolean isFailAllConnections() {
        return failAllConnections_;
    }
    
    /**
     * Setter method of FailAllConnections property
     * @param failAllConnections  fail all connections value 
     * 
     */

    public void setFailAllConnections(boolean failAllConnections) {
        failAllConnections_ = failAllConnections;
    }
    
    /**
     * Getter method of matchConnections property
     * @return whether to match connections always with resource adapter 
     * or not 
     */

    public boolean matchConnections() {
        return matchConnections_;
    }
    
    /**
     * Setter method of matchConnections property
     * @param matchConnections  fail all connections value 
     * 
     */

    public void setMatchConnections(boolean matchConnections) {
        matchConnections_ = matchConnections;
    }

    /**
     * Returns the transaction support level for this pool
     * The valid values are<br>
     * <ul>
     * <li>ConnectorConstants.NO_TRANSACTION</li>
     * <li>ConnectorConstants.LOCAL_TRANSACTION</li>
     * <li>ConnectorConstants.XA_TRANSACTION</li>
     * </ul>
     * @return the transaction support level for this pool
     */
    public int getTransactionSupport() {
        return transactionSupport_;
    }
    
    /**
     * Sets the transaction support level for this pool
     * The valid values are<br>
     * <ul>
     * <li>ConnectorConstants.NO_TRANSACTION</li>
     * <li>ConnectorConstants.LOCAL_TRANSACTION</li>
     * <li>ConnectorConstants.XA_TRANSACTION</li>
     * </ul>
     *
     */
    public void setTransactionSupport( int transactionSupport ) {
        transactionSupport_ = transactionSupport;
    }
    
    /**
     * Sets the is-connection-validation-required pool attribute
     */
    public void setConnectionValidationRequired( boolean validation ) {
        isConnectionValidationRequired_ = validation;
    }
    
    /**
     * Queries the is-connection-validation-required pool attribute
     */
    public boolean isIsConnectionValidationRequired() {
        return isConnectionValidationRequired_;
    }
   
    public boolean isLazyConnectionAssoc() {
        return lazyConnectionAssoc_;
    }

    public void setLazyConnectionAssoc( boolean match ) {
        lazyConnectionAssoc_ = match;
    }

    public boolean isLazyConnectionEnlist() {
        return lazyConnectionEnlist_;
    }

    public void setLazyConnectionEnlist( boolean flag ) {
        lazyConnectionEnlist_ = flag;
    }
   
    public boolean isAssociateWithThread() {
        return associateWithThread_;
    }

    public void setAssociateWithThread( boolean match ) {
        associateWithThread_ = match;
    }
    
    public boolean isNonTransactional() {
        return nonTransactional_;
    }

    public void setNonTransactional( boolean match ) {
        nonTransactional_ = match;
    }

    public boolean isNonComponent() {
        return nonComponent_;
    }

    public void setNonComponent( boolean match ) {
        nonComponent_ = match;
    }
    public boolean isConnectionLeakTracing() {
        return connectionLeakTracing_;
    }

    public void setConnectionLeakTracing( boolean match ) {
        connectionLeakTracing_ = match;
    }


    /** Setter method for Security Maps
     * @param securityMapArray SecurityMap[]
     */

    public void setSecurityMaps(ConnectorSecurityMap[] securityMapArray){
        this.securityMaps = securityMapArray;
    }
    
    /** Getter method for Security Maps
     * @return SecurityMap[]
     */

    public ConnectorSecurityMap[] getSecurityMaps(){
        return this.securityMaps;
    }

    /**
     * return the String representation of the pool.
     * @return String representation of pool
     */
    public String toString() {
        String returnVal = null;
        StringBuffer sb = new StringBuffer("ConnectorConnectionPool :: ");
        try {
            sb.append(getName());
            sb.append("\nsteady size: ");
            sb.append(getSteadyPoolSize());
            sb.append("\nmax pool size: ");
            sb.append(getMaxPoolSize());
            sb.append("\nmax wait time: ");
            sb.append(getMaxWaitTimeInMillis());
            sb.append("\npool resize qty: ");
            sb.append(getPoolResizeQuantity());
            sb.append("\nIdle timeout: ");
            sb.append(getIdleTimeoutInSeconds());
            sb.append("\nfailAllConnections: ");
            sb.append(isFailAllConnections());
	    sb.append("\nTransaction Support Level: ");
	    sb.append(transactionSupport_);
	    sb.append("\nmatchConnections_ ");
	    sb.append(matchConnections_);
	    sb.append("\nisConnectionValidationRequired_ ");
	    sb.append(isConnectionValidationRequired_);
	    sb.append("\nassociateWithThread_ ");
	    sb.append(associateWithThread_);
            sb.append("\nlazyConnectionAssoc_ ");
	    sb.append(lazyConnectionAssoc_);
	    sb.append("\nnonTransactional_ ");
	    sb.append(nonTransactional_);
	    sb.append("\nnonComponent_ ");
	    sb.append(nonComponent_);
	    sb.append("\nconnectionLeakTracing_ ");
	    sb.append(connectionLeakTracing_);
            sb.append("\nConnectorDescriptorInfo -> ");
            sb.append("\nrarName: ");
            sb.append(connectorDescriptorInfo_.getRarName());
            sb.append("\nresource adapter class: ");
            sb.append(connectorDescriptorInfo_.getResourceAdapterClassName());
            sb.append("\nconnection def name: ");
            sb.append(connectorDescriptorInfo_.getConnectionDefinitionName());
            sb.append("\nMCF Config properties-> ");
            Iterator iter = 
                connectorDescriptorInfo_.getMCFConfigProperties().iterator();
            while( iter.hasNext() ) {
                EnvironmentProperty ep = (EnvironmentProperty)iter.next();
                sb.append(ep.getName());
                sb.append(":");
                sb.append( ("password".equalsIgnoreCase(ep.getName()) ? "****" : ep.getValue() ));
                sb.append("\n");
            }
            if ( securityMaps != null ) {
                sb.append("SecurityMaps -> {");
                for (int i=0; i<securityMaps.length; i++) {
                    if ( securityMaps[i] != null && 
                            securityMaps[i].getName() != null ) {
                        sb.append(securityMaps[i].getName()+" ");
                    }
                }
                sb.append("}");
            }
            returnVal = sb.toString();
        } catch( Exception e) { 
            e.printStackTrace(); 
        }
        return returnVal;
    }

     public boolean isValidateAtmostEveryIdleSecs() {
         return validateAtmostEveryIdleSecs;
     }
     public void setValidateAtmostEveryIdleSecs(boolean validateAtmostEveryIdleSecs) {
         this.validateAtmostEveryIdleSecs = validateAtmostEveryIdleSecs;
     }

}
