/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * 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.1 of the License, or 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
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */


package org.objectweb.jonas.resource;

import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.modelmbean.ModelMBean;
import javax.naming.BinaryRefAddr;
import javax.naming.Context;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.resource.Referenceable;
import javax.resource.spi.ConnectionManager;
import javax.resource.spi.ManagedConnectionFactory;
import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.ResourceAdapterAssociation;

import org.apache.commons.modeler.ManagedBean;
import org.apache.commons.modeler.Registry;
import org.objectweb.jonas.common.JNDIUtils;
import org.objectweb.jonas.common.Log;
import org.objectweb.jonas.jmx.J2eeObjectName;
import org.objectweb.jonas.naming.CompNamingContext;
import org.objectweb.jonas_ejb.deployment.api.ActivationConfigPropertyDesc;
import org.objectweb.jonas_rar.deployment.api.ConfigPropertyDesc;
import org.objectweb.jonas_rar.deployment.api.ConnectorDesc;
import org.objectweb.jonas_rar.deployment.api.JdbcConnParamsDesc;
import org.objectweb.jonas_rar.deployment.api.JonasConfigPropertyDesc;
import org.objectweb.jonas_rar.deployment.api.JonasConnectorDesc;
import org.objectweb.jonas_rar.deployment.api.PoolParamsDesc;
import org.objectweb.transaction.jta.TransactionManager;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

/**
 * ResourceUtility class
 * @author Eric Hardesty
 * Contributor(s):
 *
 */

public class ResourceUtility {

    /**
     * Main logger
     */
    private static Logger logger = null;
    /**
     * Config property setter logger
     */
    private static Logger setterLogger = null;
    /**
     * Management logger
     */
    private static Logger manageLogger = null;

    /**
     * Reference to a Registry object
     */
    private Registry oRegistry = null;

    /**
     * Reference to a MBean server.
     */
    private MBeanServer mbeanServer = null;

    // Properties for inits

    /**
     * JOnAS Connection Definition
     */
    public static final String JCD = "JCD";
    /**
     * JOnAS Activationspec
     */
    public static final String JAS = "JAS";
    /**
     * JOnAS Administrated Object
     */
    public static final String JAO = "JAO";

    /**
     * Default constructor
     *
     */
    public ResourceUtility() {
    }

    /**
     * Constructor
     *
     * @param mbeanServer MBeanServer object
     * @param oRegistry Registry object
     * @param log Logger main logger
     * @param sLog Logger setter logger
     * @param mLog Logger management logger
     */
    public ResourceUtility(MBeanServer mbeanServer, Registry oRegistry,
                           Logger log, Logger sLog, Logger mLog) {
        this.mbeanServer = mbeanServer;
        this.oRegistry = oRegistry;
        logger = log;
        setterLogger = sLog;
        manageLogger = mLog;
    }

    /**
     *
     * @param raCfg List
     * @param jRaCfg1 List
     * @param jRaCfg2 List
     * @return ConfigPropertyDesc array
     */
    public ConfigPropertyDesc [] buildConfigProperty(List raCfg,
                                                     List jRaCfg1,
                                                     List jRaCfg2) {
        Vector cfVec = null;
        ConfigPropertyDesc[] configs = null;

        // Global config parameters for the Resource adapter
        if (raCfg != null) {
            for (Iterator i = raCfg.iterator(); i.hasNext();) {
                if (cfVec == null) {
                    cfVec = new Vector();
                }
                cfVec.add(new ConfigPropertyDesc((ConfigPropertyDesc) i.next()));
            }
        } else {  //Special case for configuring ActivationSpecs
            ActivationConfigPropertyDesc acp = null;
            ConfigPropertyDesc cp = null;
            if (jRaCfg1 != null) {
                for (Iterator i = jRaCfg1.iterator(); i.hasNext();) {
                    if (cfVec == null) {
                        cfVec = new Vector();
                    }
                    acp = (ActivationConfigPropertyDesc) i.next();
                    cp = new ConfigPropertyDesc();
                    cp.setConfigPropertyName(acp.getActivationConfigPropertyName());
                    cp.setConfigPropertyValue(acp.getActivationConfigPropertyValue());
                    cfVec.add(cp);
                }
            }

            if (cfVec == null) {
                if (jRaCfg2 != null) {
                    for (Iterator i = jRaCfg2.iterator(); i.hasNext();) {
                        if (cfVec == null) {
                            cfVec = new Vector();
                        }
                        acp = (ActivationConfigPropertyDesc) i.next();
                        cp = new ConfigPropertyDesc();
                        cp.setConfigPropertyName(acp.getActivationConfigPropertyName());
                        cp.setConfigPropertyValue(acp.getActivationConfigPropertyValue());
                        cfVec.add(cp);
                    }
                    if (cfVec != null) {
                        configs = new ConfigPropertyDesc[cfVec.size()];
                        cfVec.copyInto(configs);
                    }
                }
            } else {
                if (jRaCfg2 != null) {
                    boolean found = false;
                    for (Iterator i = jRaCfg2.iterator(); i.hasNext();) {
                        found = false;
                        acp = (ActivationConfigPropertyDesc) i.next();
                        String name = acp.getActivationConfigPropertyName();
                        String val = acp.getActivationConfigPropertyValue();
                        if (val != null && val.length() > 0) {
                            for (int j = 0; j < cfVec.size(); j++) {
                                cp = (ConfigPropertyDesc) cfVec.get(j);
                                if (name.equalsIgnoreCase(cp.getConfigPropertyName())) {
                                    cp.setConfigPropertyValue(val);
                                    cfVec.set(j, cp);
                                    found = true;
                                    break;
                                }
                            }
                            // This is the case where a new activation-config property is in
                            // the jonas specific dd
                            if (!found) {
                                cp = new ConfigPropertyDesc();
                                cp.setConfigPropertyName(name);
                                cp.setConfigPropertyValue(val);
                                cfVec.add(cp);
                            }
                        }
                    }
                }
                configs = new ConfigPropertyDesc[cfVec.size()];
                cfVec.copyInto(configs);
            }

            if (cfVec == null) {
                return null;
            }
            return configs;
        }

        if (cfVec == null) {
            return null;
        }

        configs = new ConfigPropertyDesc[cfVec.size()];
        cfVec.copyInto(configs);

        JonasConfigPropertyDesc jcpNext = null;
        if (jRaCfg2 != null) {
            for (Iterator i = jRaCfg2.iterator(); i.hasNext();) {
                jcpNext = (JonasConfigPropertyDesc) i.next();
                String name = jcpNext.getJonasConfigPropertyName();
                String val = jcpNext.getJonasConfigPropertyValue();
                if (val != null && val.length() > 0) {
                    for (int j = 0; j < configs.length; j++) {
                        if (name.equalsIgnoreCase(configs[j].getConfigPropertyName())) {
                            configs[j].setConfigPropertyValue(val);
                            break;
                        }
                    }
                }
            }
        }

        if (jRaCfg1 != null) {
            for (Iterator i = jRaCfg1.iterator(); i.hasNext();) {
                jcpNext = (JonasConfigPropertyDesc) i.next();
                String name = jcpNext.getJonasConfigPropertyName();
                String val = jcpNext.getJonasConfigPropertyValue();
                if (val != null && val.length() > 0) {
                    for (int j = 0; j < configs.length; j++) {
                        if (name.equalsIgnoreCase(configs[j].getConfigPropertyName())) {
                            configs[j].setConfigPropertyValue(val);
                            break;
                        }
                    }
                }
            }
        }
        return configs;
    }

    /**
     *
     * @param inp String
     * @return boolean
     */
    private boolean checkLogEnabled(String inp) {
        if (inp.equals("1") || inp.equalsIgnoreCase("on")
            || inp.equalsIgnoreCase("t") || inp.equalsIgnoreCase("true")
            || inp.equalsIgnoreCase("y") || inp.equalsIgnoreCase("yes")) {
            return true;
        }
         return false;
    }

    /**
     *
     * @param trans String
     * @param tm TransactionManager
     * @param logger Logger
     * @param poolLogger Logger
     * @param jndiName String
     * @return ConnectionManager
     * @throws Exception any exception
     */
    public ConnectionManager createConnectionManager(String trans,
                                                     TransactionManager tm,
                                                     Logger logger,
                                                     Logger poolLogger,
                                                     String jndiName)
           throws Exception {

        ConnectionManagerImpl cm = new ConnectionManagerImpl(trans);

        Context c = new CompNamingContext("");
        c.rebind(ConnectionManagerImpl.TRANSACTION_MANAGER, tm);
        c.rebind(ConnectionManagerImpl.RESOURCE_MANAGER_EVENT_LISTENER, tm);

        // Set the MonologFactory into context of initialisation
        c.rebind(ConnectionManagerImpl.LOGGER, logger);
        c.rebind(ConnectionManagerImpl.POOL_LOGGER, poolLogger);
        c.rebind(ConnectionManagerImpl.JNDINAME, jndiName);

        // Initialize the ConnectionManager with the configured Context
        cm.init(c);
        return cm;
    }

    /**
     * Process the ManagedConnectionFactory object
     *
     * @param conn ConnectorDesc
     * @param jonasConn JonasConnectorDesc
     * @param cm ConnectionManager
     * @param curLoader ClassLoader
     * @param rarName String
     * @param mcfc String
     * @param jndiName String
     * @param logEnabled String
     * @param logTopic String
     * @param cfgRaJonas ConfigPropertyDesc array
     * @param resAdp ResourceAdapter
     * @param idOff int
     * @return Object
     * @throws Exception any exception
     */
    public Object processMCF(ConnectorDesc conn, JonasConnectorDesc jonasConn, ConnectionManager cm,
                              ClassLoader curLoader, String rarName, String mcfc,
                              String jndiName, String logEnabled, String logTopic,
                              ConfigPropertyDesc [] cfgRaJonas, ResourceAdapter resAdp,
                              int idOff) throws Exception {

        if (mcfc == null) {
            logger.log(BasicLevel.ERROR, "ResourceService.createRA:"
                       + " managedconnectionfactoryclass property not found");
            throw new Exception("configuration file incorrect");
        }

        if (jndiName == null || jndiName.length() == 0) {
            logger.log(BasicLevel.ERROR, "ResourceService.createRA: jndi-name not set in jonas-ra.xml");
            throw new Exception("configuration file incorrect");
        }

        // Instantiate into the currect loader
        Class mcfClass = curLoader.loadClass(mcfc);
        ManagedConnectionFactory mcf =
            (ManagedConnectionFactory) mcfClass.newInstance();

        if (resAdp != null) {
            try {
                ((ResourceAdapterAssociation) mcf).setResourceAdapter(resAdp);
            } catch (ClassCastException ce) {
                // Not able to associate ResourceAdapter to MCF
            } catch (Exception ex) {
                logger.log(BasicLevel.ERROR, "ResourceService: Error setting ResourceAdapter class to ManagedConnectionFactory ("
                           + mcfc + ") for " + jndiName);
                throw ex;
            }
        }

        if (logger.isLoggable(BasicLevel.DEBUG)) {
            logger.log(BasicLevel.DEBUG, "jndiName=" + jndiName);
        }

        // Check if logging desired and the value of the desired topic
        if (logEnabled != null) {
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG, "log-enabled=" + logEnabled);
            }
            if (checkLogEnabled(logEnabled)) {
                if (logTopic != null && logTopic.length() > 0) {
                    if (logger.isLoggable(BasicLevel.DEBUG)) {
                        logger.log(BasicLevel.DEBUG, "log-topic=" + logTopic);
                    }
                    mcf.setLogWriter(Log.getLogWriter(logTopic));
                } else {
                    if (logger.isLoggable(BasicLevel.DEBUG)) {
                        logger.log(BasicLevel.DEBUG, "default log-topic=" + Log.JONAS_JCA_PREFIX);
                    }
                    mcf.setLogWriter(Log.getLogWriter(Log.JONAS_JCA_PREFIX));   // "org.objectweb.jonas.jca"
                }
            }
        }

        processSetters(mcfClass, mcf, rarName, cfgRaJonas);

        PrintWriter pw = mcf.getLogWriter();
        if (pw != null) {
            //Create a date format
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
            String date = sdf.format(new Date());
            pw.println("MCF: output starting at " + date);
            pw.flush();
        }

        // Set hashCode for ManagedConnectionFactory
        try {
            mcf.hashCode();
        } catch (Exception ex) {
            String err = "Exception  in ManagedConnectionFactory.hashCode(): ";
            logger.log(BasicLevel.ERROR,err+ex);
        }

        return mcf;
    }


    /**
     *
     * @param cf Referenceable
     * @param jndiName String
     * @param rarName String
     * @param conn ConnectorDesc
     * @param jonasConn JonasConnectorDesc
     * @param factType String factory type
     * @param factOffset int factory offset
     * @param jcaResourceMBean JCAResource
     * @param jcaResourceName String
     * @param jDomain String of JOnAS domain name
     * @param jServer String of JOnAS server name
     * @param ictx Context
     * @param prop Properties
     * @throws Exception any Exception
     */
    public void registerMBean(Referenceable cf, String jndiName, String rarName, String rarFileName,
                              ConnectorDesc conn, JonasConnectorDesc jonasConn,
                              String factType, int factOffset,
                              JCAResource jcaResourceMBean, String jcaResourceName,
                              String jDomain, String jServer, Context ictx, Properties prop,
                              String description, ConnectionManagerImpl cm) throws Exception {

        try {
            Reference ref =
                new Reference(cf.getClass().getName(),
                              ResourceObjectJNDIHandler.class.getName(),
                              null);

            ref.add(new StringRefAddr(ResourceServiceImpl.JNDI_NAME, jndiName));
            ref.add(new StringRefAddr(ResourceServiceImpl.RAR_OBJNAME, rarName));
            ref.add(new StringRefAddr(ResourceServiceImpl.FACTORY_TYPE, factType));
            ref.add(new StringRefAddr(ResourceServiceImpl.FACTORY_OFFSET, "" + factOffset));
            //Put the connector objects
            byte[] bytes = JNDIUtils.getBytesFromObject(conn);
            if (bytes != null) {
                ref.add(new BinaryRefAddr(ResourceServiceImpl.RA_XML, bytes));
            }

            bytes = JNDIUtils.getBytesFromObject(jonasConn);
            if (bytes != null) {
                ref.add(new BinaryRefAddr(ResourceServiceImpl.JONAS_RA_XML, bytes));
            }

            cf.setReference(ref);
            ictx.rebind(jndiName, cf);

        } catch (Exception e) {
            logger.log(BasicLevel.ERROR, "ResourceService: Cannot register ResourceAdapter in naming with the name " + jndiName);
            logger.log(BasicLevel.ERROR, "ResourceService: Exception caught : " + e);
        }

        // --------------------------
        // Register MBeans cf. JSR 77
        // --------------------------
        if (mbeanServer != null) {

            // Available ConnectionFactories and ManagedConnectionFactories
            // ------------------------------------------------------------
            // ConnectionFactory MBean
            // -----------------------
            String jcaConnectionFactoryName = jndiName;
            ObjectName onJCAConnectionFactory =
                J2eeObjectName.getJCAConnectionFactory(jDomain,
                                                       jcaResourceName,
                                                       jServer,
                                                       jcaConnectionFactoryName);
            JCAConnectionFactory jcaConnectionFactoryMBean = new JCAConnectionFactory(onJCAConnectionFactory.toString(), jndiName, rarFileName, prop, description, cm);
            ManagedBean oManaged = oRegistry.findManagedBean("JCAConnectionFactory");
            ModelMBean oMBean = oManaged.createMBean(jcaConnectionFactoryMBean);
            if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
                manageLogger.log(BasicLevel.DEBUG, "JCAConnectionFactory created");
            }
            mbeanServer.registerMBean(oMBean, onJCAConnectionFactory);

            // Update the list of connection factories in the JCAResource MBean with the JCAConnectionFactory
            // MBean's OBJECT_NAME
            jcaResourceMBean.setConnectionFactory(onJCAConnectionFactory.toString());

            // ManagedConnectionFactory MBean
            // ------------------------------
            String jcaManagedConnectionFactoryName = getJcaMcfName(jcaConnectionFactoryName);
            ObjectName onJCAManagedConnectionFactory =
                J2eeObjectName.getJCAManagedConnectionFactory(jDomain,
                                                       jServer,
                                                       jcaManagedConnectionFactoryName);
            JCAManagedConnectionFactory jcaManagedConnectionFactoryMBean =
                new JCAManagedConnectionFactory(onJCAManagedConnectionFactory.toString());
            oManaged = oRegistry.findManagedBean("JCAManagedConnectionFactory");
            oMBean = oManaged.createMBean(jcaManagedConnectionFactoryMBean);
            if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
                manageLogger.log(BasicLevel.DEBUG, "JCAManagedConnectionFactory created");
            }
            mbeanServer.registerMBean(oMBean, onJCAManagedConnectionFactory);

            // Update the JCA ConnectionFactory with the JCA ManagedConnectionFactory
            jcaConnectionFactoryMBean.setManagedConnectionFactory(onJCAManagedConnectionFactory.toString());
            if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
                manageLogger.log(BasicLevel.DEBUG, "JCAConnectionFactory updated");
            }
        } // end JMX registration
    }


    /**
     *
     * @param clsClass Class
     * @param clsObj Object
     * @param rarFileName String
     * @param cProp ConfigPropertyDesc array
     * @throws Exception any exception
     */
    public void processSetters(Class clsClass, Object clsObj, String rarFileName,
                               ConfigPropertyDesc [] cProp) throws Exception {

        int curParam = 0;
        while (cProp != null && curParam < cProp.length) {
            String fieldName = cProp[curParam].getConfigPropertyName();
            String methodName = "set" + fieldName.substring(0, 1).toUpperCase()
                                + fieldName.substring(1);
            String fieldType = cProp[curParam].getConfigPropertyType();
            Method[] m = clsClass.getMethods();

            int i = 0;
            while (i < m.length
                   && (!m[i].getName().equals(methodName)
                       || m[i].getParameterTypes().length != 1
                       || (fieldType != null
                           && !(m[i].getParameterTypes())[0].getName().equals(fieldType)))
                   ) {
                i++;
            }
            if (i < m.length) {
                Class [] paramtype = m[i].getParameterTypes();
                Object[] param = new Object[1];

                String curValue = cProp[curParam].getConfigPropertyValue();
                if (setterLogger.isLoggable(BasicLevel.DEBUG)) {
                    setterLogger.log(BasicLevel.DEBUG, "Processing Field Name: " + fieldName
                            + " Type: " + fieldType + " Value: " + curValue);
                }

                if (paramtype[0].equals(java.lang.Integer.TYPE)
                    || paramtype[0].equals(java.lang.Integer.class)) {
                    param[0]  = new Integer(curValue);

                } else if (paramtype[0].equals(java.lang.Boolean.TYPE)
                           || paramtype[0].equals(java.lang.Boolean.class)) {
                    param[0]  = new Boolean(curValue);

                } else if (paramtype[0].equals(java.lang.Double.TYPE)
                           || paramtype[0].equals(java.lang.Double.class)) {
                    param[0]  = new Double(curValue);

                } else if (paramtype[0].equals(java.lang.Byte.TYPE)
                           || paramtype[0].equals(java.lang.Byte.class)) {
                    param[0]  = new Byte(curValue);

                } else if (paramtype[0].equals(java.lang.Short.TYPE)
                           || paramtype[0].equals(java.lang.Short.class)) {
                    param[0]  = new Short(curValue);

                } else if (paramtype[0].equals(java.lang.Long.TYPE)
                           || paramtype[0].equals(java.lang.Long.class)) {
                    param[0]  = new Long(curValue);

                } else if (paramtype[0].equals(java.lang.Float.TYPE)
                           || paramtype[0].equals(java.lang.Float.class)) {
                    param[0]  = new Float(curValue);

                } else if (paramtype[0].equals(java.lang.Character.TYPE)
                           || paramtype[0].equals(java.lang.Character.class)) {
                    param[0]  = new Character(curValue.charAt(0));

                } else if (paramtype[0].equals(java.lang.String.class)) {
                    param[0]  = curValue;
                    if (setterLogger.isLoggable(BasicLevel.DEBUG)) {
                        setterLogger.log(BasicLevel.DEBUG, "Calling String method with " + curValue);
                    }

                } else {
                    logger.log(BasicLevel.ERROR, "Type unsupported for setter method:"
                                + methodName);
                    throw new Exception("incorrect type for setter method ");
                }
                // invocation of the corresponding setter method on
                // class object instance
                try {
                    m[i].invoke(clsObj, param);
                } catch (Exception e) {
                    if (logger.isLoggable(BasicLevel.DEBUG)) {
                        logger.log(BasicLevel.DEBUG, "method "
                                + methodName
                                + " not found for " + rarFileName + "check its configuration ");
                    }
                }
                curParam++;
            } else {
                logger.log(BasicLevel.ERROR, "Method not found in class '" + clsClass + "': " + methodName);
                throw new Exception("method name '" + methodName + "' not found in class '" + clsClass + "'");
            }
        }
    }

    /**
     * set the PoolParams from the JonasConnector specified
     * @param pParams PoolParamsDesc
     * @param jConnParams JdbcConnParamsDesc
     * @param pool ConnectionManagerPoolParams
     * @return ConnectionManagerPoolParams
     * @throws Exception any exception
     */
    public ConnectionManagerPoolParams configurePoolParams (PoolParamsDesc pParams,
                                                            JdbcConnParamsDesc jConnParams,
                                                            ConnectionManagerPoolParams pool)
               throws Exception {

        ConnectionManagerPoolParams cmpp = null;
        if (pool == null) {
            cmpp = new ConnectionManagerPoolParams();
        } else {
            cmpp = new ConnectionManagerPoolParams(pool);
        }
        String tmpPool = null;
        try {
            if (pParams != null) {
                if (pParams.getPoolInit() != null) {
                    tmpPool = pParams.getPoolInit();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolInit(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPoolMin() != null) {
                    tmpPool = pParams.getPoolMin();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolMin(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPoolMax() != null) {
                    tmpPool = pParams.getPoolMax();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolMax(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPoolMaxAge() != null) {
                    tmpPool = pParams.getPoolMaxAge();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolMaxAge(Long.parseLong(tmpPool));
                    }
                }
                if (pParams.getPoolMaxAgeMinutes() != null) {
                    tmpPool = pParams.getPoolMaxAgeMinutes();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolMaxAgeMinutes(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPoolMaxOpentime() != null) {
                    tmpPool = pParams.getPoolMaxOpentime();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolMaxOpentime(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPoolMaxWaiters() != null) {
                    tmpPool = pParams.getPoolMaxWaiters();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolMaxWaiters(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPoolMaxWaittime() != null) {
                    tmpPool = pParams.getPoolMaxWaittime();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolMaxWaittime(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPoolSamplingPeriod() != null) {
                    tmpPool = pParams.getPoolSamplingPeriod();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPoolSamplingPeriod(Integer.parseInt(tmpPool));
                    }
                }
                if (pParams.getPstmtMax() != null) {
                    tmpPool = pParams.getPstmtMax();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setPstmtMax(Integer.parseInt(tmpPool));
                    }
                }
            }
           if (jConnParams != null) {
                if (jConnParams.getJdbcCheckLevel() != null) {
                    tmpPool = jConnParams.getJdbcCheckLevel();
                    if (tmpPool != null && tmpPool.length() > 0) {
                        cmpp.setJdbcConnLevel(Integer.parseInt(tmpPool));
                    }
                }
                if (jConnParams.getJdbcTestStatement() != null) {
                    cmpp.setJdbcConnTestStmt(jConnParams.getJdbcTestStatement());
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.log(BasicLevel.ERROR, "Invalid Pool parameter from jonas-ra.xml:  Ensure that numeric values are used. " + tmpPool);
            throw new Exception("incorrect pool parameter ");
        }
        return cmpp;
    }

    /**
     * Return the parsed XML object relative to the section
     *
     * @param jonasConn JonasConnectorDesc object
     * @param id String id of the section
     * @param idOffset int offset within the section
     * @param oType String type of section
     * @return Object of parsed XML object
     * @throws Exception if the element is out of bound
     */
    public Object getJonasXML(JonasConnectorDesc jonasConn,
                              String id, int idOffset, String oType) throws Exception {
        try {
            Object obj = null;
            if (oType == JCD) {
                obj = jonasConn.getJonasConnectionDefinitionList().get(idOffset);
            } else if (oType == JAS) {
                obj = jonasConn.getJonasActivationspecList().get(idOffset);
            } else if (oType == JAO) {
                obj = jonasConn.getJonasAdminobjectList().get(idOffset);
            }
            return obj;
        } catch (IndexOutOfBoundsException e) {
            throw new Exception("Element " + oType + ", " + idOffset + " is not found in the jonas-ra.xml", e);
        }
    }

    /**
     * Return the JCA Managed Connection Factory name
     * @param jndiName String of jndi name
     * @return String of JCA Managed Connection Factory name
     */
    public String getJcaMcfName(String jndiName) {
        return jndiName;
    }
}
