/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2006 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.management.monitoring;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;

import org.objectweb.jonas.common.JProp;
import org.objectweb.jonas.jmx.CatalinaObjectName;
import org.objectweb.jonas.jmx.J2eeObjectName;
import org.objectweb.jonas.jmx.JonasObjectName;
import org.objectweb.jonas.jmx.JoramObjectName;
import org.objectweb.jonas.jmx.ManagementException;
import org.objectweb.util.monolog.api.BasicLevel;


/**
 * A ServerProxy proxy MBean represents a server in the domain on the master side.
 * Implements state transition diagram.
 * @author Adriana Danes
 * @author S. Ali Tokmen
 */
public class ServerProxy extends JMXProxy implements ServerProxyMBean {
    /**
     * J2EEServer ObjectName corresponding to the represented server
     */
    private String j2eeObjectName;

    /**
     * Default value for maxcheck
     */
    private static final int MAXCHECK_DEFAULT = 5;

    /**
     * Number of retries when detecting a broken connection
     */
    private int maxcheck = MAXCHECK_DEFAULT;

    /**
     * number of checks in UNREACHABLE case in the case of a server with discovery
     */
    private int nbcheck = 0;
    /**
     * This variable, set to false when the ServerProxy is created, passes to true
     * if a discovery notification arrives concerning the server represented by this
     * proxy
     */
    private boolean hasDiscovery = false;

    /**
     * Ref to the ClusterDaemon that can monitor the Server
     * null if no ClusterDaemon declared or found.
     */
    private ClusterDaemonProxy clusterdaemon = null;

    /**
     * MBeanServer
     */
    private MBeanServer mbeanServer = null;

    /**
     * Constructor used when a server is discovered
     * @param serverName the name of the managed server
     * @param dm the domain monitor which treated the discovery notification
     */
    public ServerProxy(DomainMonitor dm, String serverName) {
        super(dm, serverName, null);
        logger.log(BasicLevel.DEBUG, name);
    }


    /**
     * Constructor used for a new domain.xml entry or for
     * a server added to the domain by a management application.
     * Also used when creating the ServerProxy for the local server.
     * @param dm current domain monitor
     * @param serverName the name of the managed server
     * @param urls Collection of urls to connect to the server
     * @param cdp possible clusterdaemon
     */
    public ServerProxy(DomainMonitor dm, String serverName, Collection urls, ClusterDaemonProxy cdp) {
        super(dm, serverName, urls);
        clusterdaemon = cdp;
        logger.log(BasicLevel.DEBUG, name);
    }

    /**
     * Notification from discovery: RUNNING
     * @param urls for connection
     */
    public void notifyStarting(Collection urls) {
        logger.log(BasicLevel.DEBUG, name);
        switch (state) {
            case RUNNING:
                logger.log(BasicLevel.DEBUG, "Already running");
                break;
            case FAILED:
                if (connect(urls)) {
                    state = RUNNING;
                    getMonitoringInfo();
                }
                break;
            case UNKNOWN:
                logger.log(BasicLevel.WARN, "Running now with discovery");
            case INITIAL:
            case UNREACHABLE:
            case STOPPED:
            case STARTING:
                if (connect(urls)) {
                    state = RUNNING;
                    getMonitoringInfo();
                } else {
                    state = FAILED;
                }
                break;
        }
        hasDiscovery = true;
    }

    /**
     * Notification from discovery: STOPPING
     */
    public void notifyStopping() {
        logger.log(BasicLevel.DEBUG, name);
        switch (state) {
            case STOPPED:
                logger.log(BasicLevel.DEBUG, "Already stopped");
                break;
            case UNKNOWN:
                logger.log(BasicLevel.WARN, "Running now with discovery");
            case FAILED:
            case UNREACHABLE:
            case RUNNING:
            case STOPPING:
                state = STOPPED;
                disconnect();
                break;
        }
        // Set indicator to false in order to reset general info in case
        // the server restarts
        setInfoSet(false);
        hasDiscovery = true;
    }


    /**
     * Check the MBean server connection and possibly change state in UNREACHABLE
     * or FAILED.
     * @param readall read all monitoring info if server RUNNING
     */
    public void checkit(boolean readall) {
        logger.log(BasicLevel.DEBUG, name);

        switch (state) {
            case RUNNING:
                if (!checkConnection()) {
                    state = UNREACHABLE;
                    disconnect();
                    setInfoSet(false);
                    nbcheck = 0;
                }
                break;
            case FAILED:
                if (checkConnection()) {
                    serverStarted();
                }
                break;
            case INITIAL:
                if (checkConnection()) {
                    serverStarted();
                } else {
                    state = UNREACHABLE;
                }
                break;
            case UNREACHABLE:
                if (checkConnection()) {
                    serverStarted();
                } else {
                    if (hasDiscovery) {
                        // Increment and test nbcheck only if server with
                        // discovery
                        if (nbcheck++ >= maxcheck) {
                            state = FAILED;
                        }
                    }
                }
                break;
            case STOPPING:
                // let stopit set the state
                break;
            case STARTING:
                if (checkConnection()) {
                    serverStarted();
                } else {
                    if (nbcheck++ >= maxcheck) {
                        state = UNREACHABLE;
                    }
                }
                break;
            case STOPPED:
                break;
        }
        if (readall && state == RUNNING) {
            // Update some information about the server
            getMonitoringInfo();
        }
    }
    /**
     * This method is called by checkit() when the represented server is not
     * in RUNNING state but its connection works. This is good, it means
     * that the server is RUNNING.
     */
    void serverStarted() {
        state = RUNNING;
        dm.notifyServerProxyRunning(this);
    }

    /**
     * @return The J2EEServer ObjectName corresponding to the represented server
     */
    public String getJ2eeObjectName() {
        if (j2eeObjectName == null) {
            j2eeObjectName = J2eeObjectName.J2EEServer(getDomain(), name).toString();
        }
        return j2eeObjectName;
    }

    /**
     * @return The name corresponding to the represented server
     */
    public String getServerName() {
        return name;
    }

    /**
     * @return The name of the associated cluster daemon, if any, null otherwise
     */
    public String getClusterDaemonName() {
        if (clusterdaemon == null) {
            return null;
        }
        return clusterdaemon.getName();
    }

    /**
     * Start the Server
     * discovery notification concerning the represented server
     */
    public void startit() {
        logger.log(BasicLevel.DEBUG, name);
        if (clusterdaemon == null) {
            logger.log(BasicLevel.ERROR, "No ClusterDaemon associated to " + name);
            return;
        }
        if (state != RUNNING) {
            state = STARTING;
            clusterdaemon.startServer(name, null);
            nbcheck = 0;
        }
        checkit(true);
    }

    /**
     * Stop the server via the ClusterDaemon
     */
    public void stopit() {
        logger.log(BasicLevel.DEBUG, name);
        if (clusterdaemon == null) {
            logger.log(BasicLevel.ERROR, "No ClusterDaemon associated to " + name);
            return;
        }
        if (state != STOPPED) {
            state = STOPPING;
            if (clusterdaemon.stopServer(name, null)) {
                state = STOPPED;
            }
        }
    }

    /**
     * Deploy a filename on the represented (remote) server
     * @param fileName the name of the file containig the module/application
     * to deploy
     */
    public void deployModule(String fileName) {

        logger.log(BasicLevel.DEBUG, fileName);

        // Build a DeployAction and register it in DomainMonitor
        DeployAction act = new DeployAction(this, fileName, DeployAction.DEPLOY);
        if (dm == null) {
            logger.log(BasicLevel.ERROR, "Operation reserved to the master");
            return;
        }
        if (!dm.registerDeployAction(act)) {
            logger.log(BasicLevel.WARN, "Operation already running for " + fileName);
            return;
        }

        // Check connection
        if (!checkConnection()) {
            logger.log(BasicLevel.WARN, "Cannot deploy: Server " + name + " not running");
            act.setError("server not running");
            return;
        }

        // operation depends on the type of the file
        String opName = null;
        if (fileName.endsWith(".jar")) {
            opName = "deployJar";
        } else if (fileName.endsWith(".war")) {
            opName = "deployWar";
        } else if (fileName.endsWith(".rar")) {
            opName = "deployRar";
        } else if (fileName.endsWith(".ear")) {
            opName = "deployEar";
        } else {
            logger.log(BasicLevel.ERROR, "Cannot deploy this type of file: " + fileName);
            act.setError("Bad file type : " + fileName);
            return;
        }

        String[] params = {fileName };
        String[] signature = {"java.lang.String" };
        try {
            connection.invoke(serverOn, opName, params, signature);
        } catch (InstanceNotFoundException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            act.setError("Remote J2EEServer not registered");
            return;
        } catch (MBeanException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            Exception t = e.getTargetException();
            String errmess = t.getMessage();
            Throwable c = t.getCause();
            if (c != null) {
                errmess += " - " + c.getMessage();
            }
            act.setError(errmess);
            return;
        } catch (ReflectionException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            act.setError(e.getCause().getMessage());
            return;
        } catch (IOException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            act.setError(e.getMessage());
            return;
        } catch (RuntimeOperationsException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            Exception t = e.getTargetException();
            String errmess = t.getMessage();
            Throwable c = t.getCause();
            if (c != null) {
                errmess += " - " + c.getMessage();
            }
            act.setError(errmess);
            return;
        } catch (Exception e) {
            logger.log(BasicLevel.ERROR, "Unexpected exception: " + e);
            act.setError(e.getMessage());
            return;
        }
        act.setOK();
    }

    /**
     * Undeploy a module on the remote server
     * @param fileName Name of the file containing module (or app) to undeploy
     */
    public void undeployModule(String fileName) {

        logger.log(BasicLevel.DEBUG, fileName);

        // Build a DeployAction and register it in DomainMonitor
        DeployAction act = new DeployAction(this, fileName, DeployAction.UNDEPLOY);
        if (dm == null) {
            logger.log(BasicLevel.ERROR, "Operation reserved to the master");
            return;
        }
        if (!dm.registerDeployAction(act)) {
            logger.log(BasicLevel.WARN, "Operation already running for " + fileName);
            return;
        }

        // Check connection
        if (!checkConnection()) {
            logger.log(BasicLevel.WARN, "Cannot undeploy: Server " + name + " not running");
            act.setError("server not running");
            return;
        }

        // operation depends on the type of the file
        String opName = null;
        if (fileName.endsWith(".jar")) {
            opName = "unDeployJar";
        } else if (fileName.endsWith(".war")) {
            opName = "unDeployWar";
        } else if (fileName.endsWith(".rar")) {
            opName = "unDeployRar";
        } else if (fileName.endsWith(".ear")) {
            opName = "unDeployEar";
        } else {
            logger.log(BasicLevel.ERROR, "Cannot undeploy this type of file: " + fileName);
            act.setError("Bad file type : " + fileName);
            return;
        }

        String[] params = {fileName };
        String[] signature = {"java.lang.String" };
        try {
            connection.invoke(serverOn, opName, params, signature);
        } catch (InstanceNotFoundException e) {
            logger.log(BasicLevel.ERROR, "Cannot undeploy file: " + fileName + " :", e);
            act.setError("Remote J2EEServer not registered");
            return;
        } catch (MBeanException e) {
            logger.log(BasicLevel.ERROR, "Cannot undeploy file: " + fileName + " :", e);
            Exception t = e.getTargetException();
            String errmess = t.getMessage();
            Throwable c = t.getCause();
            if (c != null) {
                errmess += " - " + c.getMessage();
            }
            act.setError(errmess);
            return;
        } catch (ReflectionException e) {
            logger.log(BasicLevel.ERROR, "Cannot undeploy file: " + fileName + " :", e);
            act.setError(e.getCause().getMessage());
            return;
        } catch (IOException e) {
            logger.log(BasicLevel.ERROR, "Cannot undeploy file: " + fileName + " :", e);
            act.setError(e.getMessage());
            return;
        }
        act.setOK();
    }
    /**
     * used for upload in file transfer
     */
    private static final int BUFFER_SIZE = 1024;

    /**
     * Upload a file on remote server for deployment
     * @param fileName file to upload. One among .war,.jar,.ear,.rar
     * @param replaceExisting if true, replace the existing file if any
     * @throws IOException
     */
    public void uploadFile(String fileName, boolean replaceExisting) {

        logger.log(BasicLevel.DEBUG, fileName);

        // Build a DeployAction and register it in DomainMonitor
        DeployAction act = new DeployAction(this, fileName, DeployAction.UPLOAD);
        if (dm == null) {
            logger.log(BasicLevel.ERROR, "Operation reserved to the master");
            return;
        }
        if (!dm.registerDeployAction(act)) {
            logger.log(BasicLevel.WARN, "Operation already running for " + fileName);
            return;
        }

        // Check connection
        if (!checkConnection()) {
            logger.log(BasicLevel.WARN, "Cannot upload file: Server " + name + " not running");
            act.setError("server not running");
            return;
        }

        File file = null;
        // first try the file name as it is
        try {
            file = new File(fileName).getCanonicalFile();
        } catch (IOException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file " + fileName, e);
            act.setError(e.getMessage());
            return;
        }
        String deployName = file.getName();
        if (!file.exists()) {
            // if the file was not found try looking for it under JONAS_BASE
            String dir = getFolderDir(fileName);
            if (dir == null) {
                act.setError("Directory not found");
                return;
            }
            file = new File(dir, fileName);
            deployName = fileName;
        }
        if (file == null || !file.exists()) {
            act.setError("File not found");
            return;
        }

        try {
            FileInputStream inputStream = new FileInputStream(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[BUFFER_SIZE];
            // Read bytes
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                baos.write(buf, 0, len);
            }
            byte[] bytesOfFile = baos.toByteArray();

            Object[] opParams = new Object[] {bytesOfFile, deployName, Boolean.valueOf(replaceExisting)};
            String[] opSignature = new String[] {"[B", "java.lang.String", "boolean"};
            connection.invoke(serverOn, "sendFile", opParams, opSignature);
        } catch (InstanceNotFoundException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            act.setError("Remote J2EEServer not registered");
            return;
        } catch (MBeanException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            Exception t = e.getTargetException();
            String errmess = t.getMessage();
            Throwable c = t.getCause();
            if (c != null) {
                errmess += " - " + c.getMessage();
            }
            act.setError(errmess);
            return;
        } catch (ReflectionException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            act.setError(e.getCause().getMessage());
            return;
        } catch (IOException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            act.setError(e.getMessage());
            return;
        }
        act.setOK();
    }

    /**
     * Upload a file on remote server and deploy it.
     * @param fileName file to upload. One among .war,.jar,.ear,.rar
     * @param replaceExisting if true, replace the existing file if any
     */
    public void uploadDeployModule(String fileName, boolean replaceExisting) {

        logger.log(BasicLevel.DEBUG, fileName);

        // This must be considered as 1 single action, so we cannot just
        // call the 2 methods like that :
        //   uploadFile(filename, replaceExisting);
        //   deployModule(filename);

        // Build a DeployAction and register it in DomainMonitor
        DeployAction act = new DeployAction(this, fileName, DeployAction.UPLOADDEPLOY);
        if (dm == null) {
            logger.log(BasicLevel.ERROR, "Operation reserved to the master");
            return;
        }
        if (!dm.registerDeployAction(act)) {
            logger.log(BasicLevel.WARN, "Operation already running for " + fileName);
            return;
        }

        // Check connection
        if (!checkConnection()) {
            logger.log(BasicLevel.WARN, "Cannot upload file: Server " + name + " not running");
            act.setError("server not running");
            return;
        }

        File file = null;
        // first try the file name as it is
        try {
            file = new File(fileName).getCanonicalFile();
        } catch (IOException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file " + fileName, e);
            act.setError(e.getMessage());
            return;
        }
        String deployName = file.getName();
        if (!file.exists()) {
            // if the file was not found try looking for it under JONAS_BASE
            String dir = getFolderDir(fileName);
            if (dir == null) {
                act.setError("Directory not found");
                return;
            }
            file = new File(dir, fileName);
            deployName = fileName;
        }
        if (file == null || !file.exists()) {
            act.setError("File not found");
            return;
        }

        try {
            FileInputStream inputStream = new FileInputStream(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[BUFFER_SIZE];
            // Read bytes
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                baos.write(buf, 0, len);
            }
            byte[] bytesOfFile = baos.toByteArray();

            Object[] opParams = new Object[] {bytesOfFile, deployName, Boolean.valueOf(replaceExisting)};
            String[] opSignature = new String[] {"[B", "java.lang.String", "boolean"};
            connection.invoke(serverOn, "sendFile", opParams, opSignature);
        } catch (InstanceNotFoundException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            act.setError("Remote J2EEServer not registered");
            return;
        } catch (MBeanException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            Exception t = e.getTargetException();
            String errmess = t.getMessage();
            Throwable c = t.getCause();
            if (c != null) {
                errmess += " - " + c.getMessage();
            }
            act.setError(errmess);
            return;
        } catch (ReflectionException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            act.setError(e.getCause().getMessage());
            return;
        } catch (IOException e) {
            logger.log(BasicLevel.ERROR, "Cannot upload file: " + fileName + " :", e);
            act.setError(e.getMessage());
            return;
        }
        // Set intermediate state: DEPLOYING
        act.setDeploying();

        // operation depends on the type of the file
        String opName = null;
        if (fileName.endsWith(".jar")) {
            opName = "deployJar";
        } else if (fileName.endsWith(".war")) {
            opName = "deployWar";
        } else if (fileName.endsWith(".rar")) {
            opName = "deployRar";
        } else if (fileName.endsWith(".ear")) {
            opName = "deployEar";
        } else {
            logger.log(BasicLevel.ERROR, "Cannot deploy this type of file: " + fileName);
            return;
        }

        String[] params = {fileName };
        String[] signature = {"java.lang.String" };
        try {
            connection.invoke(serverOn, opName, params, signature);
        } catch (InstanceNotFoundException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            act.setError("Remote J2EEServer not registered");
            return;
        } catch (MBeanException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            Exception t = e.getTargetException();
            String errmess = t.getMessage();
            Throwable c = t.getCause();
            if (c != null) {
                errmess += " - " + c.getMessage();
            }
            act.setError(errmess);
            return;
        } catch (ReflectionException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            act.setError(e.getCause().getMessage());
            return;
        } catch (IOException e) {
            logger.log(BasicLevel.ERROR, "Cannot deploy file: " + fileName + " :", e);
            act.setError(e.getMessage());
            return;
        }
        act.setOK();
    }

    /**
     * Returns the directory that a file would be found in.
     *
     * @param fileName the file to find the directory for.
     * @return The directory of the given file.
     */
    private String getFolderDir(String fileName) {
        String jBase = JProp.getJonasBase();
        // based on extension
        String dir = null;
        // EJB
        if (fileName.toLowerCase().endsWith(".jar")) {
            dir = jBase + File.separator + "ejbjars";
        } else if (fileName.toLowerCase().endsWith(".war")) {
            // War file
            dir = jBase + File.separator + "webapps";
        } else if (fileName.toLowerCase().endsWith(".ear")) {
            // ear file
            dir = jBase + File.separator + "apps";
        } else if (fileName.toLowerCase().endsWith(".rar")) {
            // rar file
            dir = jBase + File.separator + "rars";
        } else {
            // invalid type
            logger.log(BasicLevel.ERROR, "Invalid extension for " + fileName);
        }
        return dir;
    }
    /**
     * @return maxcheck value
     */
    public int getMaxcheck() {
        return maxcheck;
    }
    /**
     * @param maxcheck maxcheck value
     */
    public void setMaxcheck(int maxcheck) {
        this.maxcheck = maxcheck;
    }

    // ------------------- Monitoring support -------------------//
    // MBean ObjectNames used for monitoring the represented server
    // these names depend on the domain name and the server name
    private ObjectName jvmOn = null;

    // General information about the server
    /**
     * Name of the host as given by InetAddress.getLoaclHost().
     * (node attribute from JVM MBean)
     */
    private String hostName = null;
    /**
     * JOnAS version
     */
    private String jonasVersion = null;
    /**
     * JVM vendor
     */
    private String javaVendor = null;
    /**
     * JVM version
     */
    private String javaVersion = null;
    // Info about memory usage
    /**
     * Heap size - free memory
     */
    private Long currentUsedMemory = new Long(-1);
    /**
     * Allocated heap size
     */
    private Long currentTotalMemory = new Long(-1);
    private int allThreadsCount;
    private String protocols = null;
    // infos jdk5
    private String loadCPU = null;
    // Tomcat
    private boolean tomcat;
    private int maxThreadsByConnectorTomcat = 0;
    private int currentThreadCountByConnectorTomcat = 0;
    private int currentThreadBusyByConnectorTomcat = 0;
    private long bytesReceivedByConnectorTomcat = 0;
    private long bytesSentByConnectorTomcat = 0;
    private int errorCountByConnectorTomcat = 0;
    private long processingTimeByConnectorTomcat = 0;
    private int requestCountByConnectorTomcat = 0;
    //Tx
    private boolean transaction;
    private int totalBegunTransactions;
    private int totalCommittedTransactions;
    private int totalCurrentTransactions;
    private int totalExpiredTransactions;
    private int totalRolledbackTransactions;
    // Worker Pool
    private boolean workers;
    private int currentWorkerPoolSize;
    private int maxWorkerPoolSize;
    private int minWorkerPoolSize;
    // JCA
    private boolean jcaConnection;
    private int connectionFailuresJCAConnection = 0;
    private int connectionLeaksJCAConnection = 0;
    private int currentBusyJCAConnection = 0;
    private int currentOpenedJCAConnection = 0;
    private int rejectedOpenJCAConnection = 0;
    private int servedOpenJCAConnection = 0;
    private int waiterCountJCAConnection = 0;
    private long waitingTimeJCAConnection = 0;
    //private int currentInTxJCAConnection;
    //private int currentWaitersJCAConnection;
    //private int poolMaxWaitersJCAConnection;
    //private int poolMaxOpentimeJCAConnection;
    //private int physicalConnectionOpenedCountJCAConnection;
    //private int rejectedFullJCAConnection;
    //private int rejectedOtherJCAConnection;
    //private int rejectedTimeoutJCAConnection;
    // JDBCResource
    private boolean jdbcDatasource;
    private int connectionFailuresJDBCResource;
    private int connectionLeaksJDBCResource;
    private int currentBusyJDBCResource;
    private int currentOpenedJDBCResource;
    private int rejectedOpenJDBCResource;
    private int servedOpenJDBCResource;
    private int waiterCountJDBCResource;
    private long waitingTimeJDBCResource;

    // JMS
    private boolean jmsJoram;
    private int jmsQueuesNbMsgsReceiveSinceCreation;
    private int jmsQueuesNbMsgsSendToDMQSinceCreation;
    private int jmsQueuesNbMsgsDeliverSinceCreation;
    private int jmsTopicsNbMsgsReceiveSinceCreation;
    private int jmsTopicsNbMsgsSendToDMQSinceCreation;
    private int jmsTopicsNbMsgsDeliverSinceCreation;
    // EJB
    private int currentNumberOfEntityBean;
    private int currentNumberOfEJB;
    private int currentNumberOfMDB;
    private int currentNumberOfSBF;
    private int currentNumberOfSBL;
    /**
     * Indicates if general info on representes server are set or not set
     */
    private boolean infoSet;
    /**
     * @return true if the general info are set, false otherwise
     */
    public boolean isInfoSet() {
        return infoSet;
    }
    /**
     * Set the indicator value to <code>true</code> after execting the getInfo() method,
     * and to <code>false</code> when detecting that server become unreacheable or stopping.
     * @param infoSet indicator value to set
     */
    public void setInfoSet(boolean infoSet) {
        this.infoSet = infoSet;
    }
    /**
     * Get general information that charaterizes the managed server and set this info into
     * attributes that won't change during the server life (JOnAS version, JVM version, etc;)
     */
    private void getInfo() {
        logger.log(BasicLevel.DEBUG, name);
        if (!checkConnection()) {
            logger.log(BasicLevel.INFO, "Cannot set info for " + name);
            logger.log(BasicLevel.INFO, "Connection is not set yet");
            return;
        }
        String domain = getDomain();
        /**
         * ObjectName of the JSR77 JVM MBean
         * <domain>:j2eeType=JVM,name=<server>,J2EEServer=<server>
         */
        jvmOn = J2eeObjectName.JVM(domain, name, name);

        String attr = "";
        try {
            if (serverOn != null && connection.isRegistered(serverOn)) {
                attr = "serverVersion";
                jonasVersion = (String) connection.getAttribute(serverOn, attr);
            }
            if (jvmOn != null && connection.isRegistered(jvmOn)) {
                String[] attributes = new String[] {
                        "javaVersion", "javaVendor", "node"
                };
                AttributeList al = (AttributeList) connection.getAttributes(jvmOn, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("javaVersion".equals(name)) {
                        javaVersion = (String) at.getValue();
                    } else if ("javaVendor".equals(name)) {
                        javaVendor = (String) at.getValue();
                    } else if ("node".equals(name)) {
                        hostName = (String) at.getValue();
                    }
                }
            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while getting attribute " + attr);
            logger.log(BasicLevel.WARN, "serverObjectName=" + serverOn);
            logger.log(BasicLevel.WARN, "jvmObjectName=" + jvmOn);
            throw new ManagementException("Error while getting attribute " + attr + " from " + name, e);
        }
        setInfoSet(true);
    }

    /**
     * Update non static information for this node.
     */
    public void getMonitoringInfo() {
        logger.log(BasicLevel.DEBUG, name);
        if (!isInfoSet()) {
            getInfo();
        }
        // Get general monitoring info
        ObjectName on = null;
        try {
            // Threads usage given by the JVM MBean
            if (jvmOn != null && connection.isRegistered(jvmOn)) {
                on = jvmOn;
                allThreadsCount = ((Integer) connection.getAttribute(on, "allThreadsCount")).intValue();
            }
            // JDK5 - TODO

            // J2EEServer provided info on memory managemenet and on protocols
            if (serverOn != null && connection.isRegistered(serverOn)) {
                on = serverOn;
                String[] attributes = new String[] {
                        "currentUsedMemory", "currentTotalMemory", "protocols"
                };
                AttributeList al = (AttributeList) connection.getAttributes(on, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("currentUsedMemory".equals(name)) {
                        currentUsedMemory = (Long) at.getValue();
                    } else if ("currentTotalMemory".equals(name)) {
                        currentTotalMemory = (Long) at.getValue();
                    } else if ("protocols".equals(name)) {
                        protocols = (String) at.getValue();
                    }
                }
            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoting MBean " + on + ", " + e);
        }

        // Get satistics provided by Cataline MBeans
        getMonitoringInfoTomcat();

        // Get satistics provided JOnAS WORKER POOL MBeans
        getMonitoringInfoWorkers();

        // Get satistics on transactions provided by JTAResource MBean
        getMonitoringInfoTransaction();

        // Get satistics on JCA connection factories
        getMonitoringInfoJCAConnection();

        // Get satistics on DataSources
        getMonitoringInfoJDBCResource();

        // Get statistics on EJBS
        getMonitoringInfoEJBs();

        // Get Joram Jms Statistics
        getMonitoringInfoJmsJoram();
    }
    /**
     * Get Joram Jms Statistics
     */
    private void getMonitoringInfoJmsJoram() {
        jmsJoram = false;
        ObjectName on = null;
        try {
            // Check if the remote server has registered the JORAM RAR module MBean:
            // <domainName>:j2eeType=ResourceAdapterModule,name=joram_for_jonas_ra,J2EEServer=<serverName>
            on = J2eeObjectName.getResourceAdapterModules(getDomain(), name);
            Iterator it = connection.queryNames(on, null).iterator();
            while (it.hasNext()) {
                on = (ObjectName) it.next();
                String name = on.getKeyProperty("name");
                if (name.equals(JoramObjectName.getJORAM_RAR_NAME())) {
                    jmsJoram = true;
                }
            }
            if (jmsJoram) {
                Hashtable statistic = null;
                jmsQueuesNbMsgsReceiveSinceCreation = 0;
                jmsQueuesNbMsgsSendToDMQSinceCreation = 0;
                jmsQueuesNbMsgsDeliverSinceCreation = 0;
                jmsTopicsNbMsgsReceiveSinceCreation = 0;
                jmsTopicsNbMsgsSendToDMQSinceCreation = 0;
                jmsTopicsNbMsgsDeliverSinceCreation = 0;
                on = JoramObjectName.joramQueues();
                Set onSet = connection.queryNames(on, null);
                for (it = onSet.iterator(); it.hasNext();) {
                    on = (ObjectName) it.next();
                    statistic = (Hashtable) connection.getAttribute(on, "Statistic");
                    jmsQueuesNbMsgsReceiveSinceCreation +=
                        ((Long) statistic.get("nbMsgsReceiveSinceCreation")).doubleValue();
                    jmsQueuesNbMsgsSendToDMQSinceCreation +=
                        ((Long) statistic.get("nbMsgsSendToDMQSinceCreation")).doubleValue();
                    jmsQueuesNbMsgsDeliverSinceCreation +=
                        ((Long) statistic.get("nbMsgsDeliverSinceCreation")).doubleValue();
                }
                on = JoramObjectName.joramTopics();
                onSet = connection.queryNames(on, null);
                for (it = onSet.iterator(); it.hasNext();) {
                    on = (ObjectName) it.next();
                    statistic = (Hashtable) connection.getAttribute(on, "Statistic");
                    jmsTopicsNbMsgsReceiveSinceCreation +=
                        ((Long) statistic.get("nbMsgsReceiveSinceCreation")).doubleValue();
                    jmsTopicsNbMsgsSendToDMQSinceCreation +=
                        ((Long) statistic.get("nbMsgsSendToDMQSinceCreation")).doubleValue();
                    jmsTopicsNbMsgsDeliverSinceCreation +=
                        ((Long) statistic.get("nbMsgsDeliverSinceCreation")).doubleValue();
                }

            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoring MBean " + on + ", " + e);
        }
    }
    /**
     * Update satistics information provided by Cataline MBeans for this node.
     */
    private void getMonitoringInfoTomcat() {
        ObjectName on = null;
        try {
            // Catalina MBeans provided info
            // thread uage provided by <domain>:type=ThreadPool,name=connectorName
            ObjectName ons = CatalinaObjectName.catalinaThreadPools(getDomain());
            tomcat = false;
            maxThreadsByConnectorTomcat = 0;
            currentThreadCountByConnectorTomcat = 0;
            currentThreadBusyByConnectorTomcat = 0;
            for (Iterator it = connection.queryNames(ons, null).iterator(); it.hasNext();) {
                tomcat = true;
                on = (ObjectName) it.next();
                String[] attributes = new String[] {
                        "maxThreads", "currentThreadCount", "currentThreadsBusy"
                        // "minSpareThreads", "maxSpareThreads"
                };
                AttributeList al = (AttributeList) connection.getAttributes(on, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("maxThreads".equals(name)) {
                        maxThreadsByConnectorTomcat  = maxThreadsByConnectorTomcat + ((Integer) at.getValue()).intValue();
                    } else if ("currentThreadCount".equals(name)) {
                        currentThreadCountByConnectorTomcat = currentThreadCountByConnectorTomcat + ((Integer) at.getValue()).intValue();
                    } else if ("currentThreadsBusy".equals(name)) {
                        int value = ((Integer) at.getValue()).intValue();
                        currentThreadBusyByConnectorTomcat += value;
                    }
                }
            }
            // request processing statistics provided by
            // <domain>:type=GlobalRequestProcessor,name=connectorName
            ons = CatalinaObjectName.catalinaGlobalRequestProcessors(getDomain());
            bytesReceivedByConnectorTomcat = 0;
            bytesSentByConnectorTomcat = 0;
            errorCountByConnectorTomcat = 0;
            processingTimeByConnectorTomcat = 0;
            requestCountByConnectorTomcat = 0;
            for (Iterator it = connection.queryNames(ons, null).iterator(); it.hasNext();) {
                tomcat = true;
                on = (ObjectName) it.next();
                String[] attributes = new String[] {
                        "bytesReceived", "bytesSent", "errorCount", "maxTime",
                        "processingTime", "requestCount"
                };
                AttributeList al = (AttributeList) connection.getAttributes(on, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("bytesReceived".equals(name)) {
                        bytesReceivedByConnectorTomcat += ((Long) at.getValue()).longValue();
                    } else if ("bytesSent".equals(name)) {
                        bytesSentByConnectorTomcat += ((Long) at.getValue()).longValue();
                    } else if ("errorCount".equals(name)) {
                        errorCountByConnectorTomcat += ((Integer) at.getValue()).intValue();
                    } else if ("processingTime".equals(name)) {
                        processingTimeByConnectorTomcat += ((Long) at.getValue()).longValue();
                    } else if ("requestCount".equals(name)) {
                        requestCountByConnectorTomcat += ((Integer) at.getValue()).intValue();
                    }
                }
            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoring MBean " + on);
        }
    }
    /**
     * Update transaction statistics using JTA MBean
     */
    private void getMonitoringInfoTransaction() {
        // transaction processing statistics provided by JTA MBean:
        // <domain>:j2eeType=JTAResource,name=JTAResource,J2EEServer=<server>
        ObjectName jtaOn = J2eeObjectName.JTAResource(getDomain(), name, null);
        transaction = false;
        try {
            if (jtaOn != null && connection.isRegistered(jtaOn)) {
                transaction = true;
                String[] attributes = new String[] {
                        "totalBegunTransactions", "totalCommittedTransactions", "totalCurrentTransactions",
                        "totalExpiredTransactions", "totalRolledbackTransactions"
                };
                AttributeList al = (AttributeList) connection.getAttributes(jtaOn, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("totalBegunTransactions".equals(name)) {
                        totalBegunTransactions = ((Integer) at.getValue()).intValue();
                    } else if ("totalCommittedTransactions".equals(name)) {
                        totalCommittedTransactions = ((Integer) at.getValue()).intValue();
                    } else if ("totalCurrentTransactions".equals(name)) {
                        totalCurrentTransactions = ((Integer) at.getValue()).intValue();
                    } else if ("totalRolledbackTransactions".equals(name)) {
                        totalRolledbackTransactions = ((Integer) at.getValue()).intValue();
                    }
                }
            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoring MBean " + jtaOn);
        }
    }

    /**
     * Update JOnAS Worker pool thread statistics
     */
    private void getMonitoringInfoWorkers() {
        // JOnAS Worker pool thread statistics are provided by workmanager MBean:
        // <domain>:type=workmanager/*,name=.. TO BE Added*/
        ObjectName wpoolOn = JonasObjectName.workManager();
        workers = false;
        try {
            if (wpoolOn != null && connection.isRegistered(wpoolOn)) {
                workers = true;
                String[] attributes = new String[] {
                        "currentPoolSize", "maxPoolSize", "minPoolSize"
                };
                AttributeList al = (AttributeList) connection.getAttributes(wpoolOn, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("currentPoolSize".equals(name)) {
                        currentWorkerPoolSize = ((Integer) at.getValue()).intValue();
                    } else if ("maxPoolSize".equals(name)) {
                        maxWorkerPoolSize = ((Integer) at.getValue()).intValue();
                    } else if ("minPoolSize".equals(name)) {
                        minWorkerPoolSize = ((Integer) at.getValue()).intValue();
                    }
                }
            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoring MBean " + wpoolOn);
        }
    }

    /**
     * Update statistics related to the JDBCDataSources.
     * The ***JDBCResource attributes represent the sum of the corresponding attributes
     * in all the JDBCDataSource MBeans of a given managed server
     */
    private void getMonitoringInfoJDBCResource() {
        // JDBCDataSources MBeans are identified by
        // <domain>:j2eeType=JDBCDataSource,name=<datasource-name>
        ObjectName jdbcDatasourcesOn = J2eeObjectName.getJDBCDataSources(getDomain(), name);
        ObjectName jdbcDatasourceOn = null;
        jdbcDatasource = false;
        try {
            Set jdbcDatasourceOns = connection.queryNames(jdbcDatasourcesOn, null);
            if (jdbcDatasourceOns.isEmpty()) {
                return;
            }
            String[] attributes = new String[] {
                    "connectionFailures", "connectionLeaks",
                    "currentBusy", "currentOpened",
                    "rejectedOpen", "servedOpen",
                    "waiterCount", "waitingTime"
            };
            jdbcDatasource = true;
            connectionFailuresJDBCResource = 0;
            connectionLeaksJDBCResource = 0;
            currentBusyJDBCResource = 0;
            currentOpenedJDBCResource = 0;
            rejectedOpenJDBCResource = 0;
            servedOpenJDBCResource = 0;
            waiterCountJDBCResource = 0;
            waitingTimeJDBCResource = 0;
            for (Iterator it = jdbcDatasourceOns.iterator(); it.hasNext();) {
                jdbcDatasourceOn = (ObjectName) it.next();
                AttributeList al = (AttributeList) connection.getAttributes(jdbcDatasourceOn, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("connectionFailures".equals(name)) {
                        connectionFailuresJDBCResource += ((Integer) at.getValue()).intValue();
                    } else if ("connectionLeaks".equals(name)) {
                        connectionLeaksJDBCResource += ((Integer) at.getValue()).intValue();
                    } else if ("currentBusy".equals(name)) {
                        currentBusyJDBCResource += ((Integer) at.getValue()).intValue();
                    } else if ("currentOpened".equals(name)) {
                        currentOpenedJDBCResource += ((Integer) at.getValue()).intValue();
                    } else if ("rejectedOpen".equals(name)) {
                        rejectedOpenJDBCResource += ((Integer) at.getValue()).intValue();
                    } else if ("servedOpen".equals(name)) {
                        servedOpenJDBCResource += ((Integer) at.getValue()).intValue();
                    } else if ("waiterCount".equals(name)) {
                        waiterCountJDBCResource += ((Integer) at.getValue()).intValue();
                    } else if ("waitingTime".equals(name)) {
                        waitingTimeJDBCResource += ((Long) at.getValue()).intValue();
                    }
                }
            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoring MBean " + jdbcDatasourceOn);
        }
    }

    /**
     * Update statistics related to the JCAConnection resources.
     * The ***JCA attributes represent the sum of the corresponding attributes
     * in all the JCAConnectionFactory MBeans of a given managed server
     */
    private void getMonitoringInfoJCAConnection() {
        // JCAConnectionFactory MBeans are identified by
        // <domain>:j2eeType=JCAConnectionFactory,name=<jca-connection-name>
        ObjectName jcaFactoriesOn = J2eeObjectName.getJCAConnectionFactories(getDomain(), name);
        ObjectName jcaFactoryOn = null;
        jcaConnection = false;
        try {
            Set jcaFactoryOns = connection.queryNames(jcaFactoriesOn, null);
            if (jcaFactoryOns.isEmpty()) {
                return;
            }
            String[] attributes = new String[] {
                    "connectionFailures", "connectionLeaks",
                    "currentBusy", "currentOpened",
                    "rejectedOpen", "servedOpen",
                    "waiterCount", "waitingTime"
            };
            jcaConnection = true;
            connectionFailuresJCAConnection = 0;
            connectionLeaksJCAConnection = 0;
            currentBusyJCAConnection = 0;
            currentOpenedJCAConnection = 0;
            rejectedOpenJCAConnection = 0;
            servedOpenJCAConnection = 0;
            waiterCountJCAConnection = 0;
            waitingTimeJCAConnection = 0;
            for (Iterator it = jcaFactoryOns.iterator(); it.hasNext();) {
                jcaFactoryOn = (ObjectName) it.next();
                AttributeList al = (AttributeList) connection.getAttributes(jcaFactoryOn, attributes);
                for (int i = 0; i < al.size(); i++) {
                    Attribute at = (Attribute) al.get(i);
                    String name = at.getName();
                    if ("connectionFailures".equals(name)) {
                        connectionFailuresJCAConnection += ((Integer) at.getValue()).intValue();
                    } else if ("connectionLeaks".equals(name)) {
                        connectionLeaksJCAConnection += ((Integer) at.getValue()).intValue();
                    } else if ("currentBusy".equals(name)) {
                        currentBusyJCAConnection += ((Integer) at.getValue()).intValue();
                    } else if ("currentOpened".equals(name)) {
                        currentOpenedJCAConnection += ((Integer) at.getValue()).intValue();
                    } else if ("rejectedOpen".equals(name)) {
                        rejectedOpenJCAConnection += ((Integer) at.getValue()).intValue();
                    } else if ("servedOpen".equals(name)) {
                        servedOpenJCAConnection += ((Integer) at.getValue()).intValue();
                    } else if ("waiterCount".equals(name)) {
                        waiterCountJCAConnection += ((Integer) at.getValue()).intValue();
                    } else if ("waitingTime".equals(name)) {
                        waitingTimeJCAConnection += ((Long) at.getValue()).intValue();
                    }
                }
            }
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoring MBean " + jcaFactoryOn + ", " + e);
        }
    }

    private void getMonitoringInfoEJBs() {
        ObjectName entityBeansOn = J2eeObjectName.getEntityBeans(getDomain());
        ObjectName on = null;
        try {
            on = J2eeObjectName.getEntityBeans(getDomain());
            Set ons = connection.queryNames(on, null);
            currentNumberOfEntityBean = ons.size();
            on = J2eeObjectName.getStatefulSessionBeans(getDomain());
            ons = connection.queryNames(on, null);
            currentNumberOfSBF = ons.size();
            on = J2eeObjectName.getStatelessSessionBeans(getDomain());
            ons = connection.queryNames(on, null);
            currentNumberOfSBL = ons.size();
            on = J2eeObjectName.getMessageDrivenBeans(getDomain());
            ons = connection.queryNames(on, null);
            currentNumberOfMDB = ons.size();
            currentNumberOfEJB = currentNumberOfEntityBean
                + currentNumberOfSBF
                + currentNumberOfSBL
                + currentNumberOfMDB;
        } catch (Exception e) {
            logger.log(BasicLevel.WARN, "Error while monitoring MBean " + on + ", " + e);
        }
    }

    public int getAllThreadsCount() {
        return allThreadsCount;
    }

    public long getBytesReceivedByConnectorTomcat() {
        return bytesReceivedByConnectorTomcat;
    }

    public long getBytesSentByConnectorTomcat() {
        return bytesSentByConnectorTomcat;
    }

    public int getConnectionFailuresJCAConnection() {
        return connectionFailuresJCAConnection;
    }

    public int getConnectionLeaksJCAConnection() {
        return connectionLeaksJCAConnection;
    }

    public int getCurrentBusyJCAConnection() {
        return currentBusyJCAConnection;
    }

    public int getCurrentNumberOfEntityBean() {
        return currentNumberOfEntityBean;
    }

    public int getCurrentNumberOfEJB() {
        return currentNumberOfEJB;
    }

    public int getCurrentNumberOfMDB() {
        return currentNumberOfMDB;
    }

    public int getCurrentNumberOfSBF() {
        return currentNumberOfSBF;
    }

    public int getCurrentNumberOfSBL() {
        return currentNumberOfSBL;
    }

    public int getCurrentOpenedJCAConnection() {
        return currentOpenedJCAConnection;
    }

    public int getCurrentThreadBusyByConnectorTomcat() {
        return currentThreadBusyByConnectorTomcat;
    }

    public int getCurrentThreadCountByConnectorTomcat() {
        return currentThreadCountByConnectorTomcat;
    }

    public Long getCurrentTotalMemory() {
        return currentTotalMemory;
    }

    public Long getCurrentUsedMemory() {
        return currentUsedMemory;
    }

    public int getCurrentWorkerPoolSize() {
        return currentWorkerPoolSize;
    }

    public int getErrorCountByConnectorTomcat() {
        return errorCountByConnectorTomcat;
    }

    public String getHostName() {
        return hostName;
    }

    public String getJavaVendor() {
        return javaVendor;
    }

    public String getJavaVersion() {
        return javaVersion;
    }

    public int getJmsQueuesNbMsgsDeliverSinceCreation() {
        return jmsQueuesNbMsgsDeliverSinceCreation;
    }

    public int getJmsQueuesNbMsgsReceiveSinceCreation() {
        return jmsQueuesNbMsgsReceiveSinceCreation;
    }

    public int getJmsQueuesNbMsgsSendToDMQSinceCreation() {
        return jmsQueuesNbMsgsSendToDMQSinceCreation;
    }

    public int getJmsTopicsNbMsgsDeliverSinceCreation() {
        return jmsTopicsNbMsgsDeliverSinceCreation;
    }

    public int getJmsTopicsNbMsgsReceiveSinceCreation() {
        return jmsTopicsNbMsgsReceiveSinceCreation;
    }

    public int getJmsTopicsNbMsgsSendToDMQSinceCreation() {
        return jmsTopicsNbMsgsSendToDMQSinceCreation;
    }

    public String getJOnASVersion() {
        return jonasVersion;
    }

    public String getLoadCPU() {
        return loadCPU;
    }

    public int getMaxThreadsByConnectorTomcat() {
        return maxThreadsByConnectorTomcat;
    }

    public int getMaxWorkerPoolSize() {
        return maxWorkerPoolSize;
    }

    public MBeanServer getMbeanServer() {
        return mbeanServer;
    }

    public int getMinWorkerPoolSize() {
        return minWorkerPoolSize;
    }

    public long getProcessingTimeByConnectorTomcat() {
        return processingTimeByConnectorTomcat;
    }

    public String getProtocols() {
        return protocols;
    }

    public int getRequestCountByConnectorTomcat() {
        return requestCountByConnectorTomcat;
    }

    public int getTotalBegunTransactions() {
        return totalBegunTransactions;
    }

    public int getTotalCommittedTransactions() {
        return totalCommittedTransactions;
    }

    public int getTotalCurrentTransactions() {
        return totalCurrentTransactions;
    }

    public int getTotalExpiredTransactions() {
        return totalExpiredTransactions;
    }

    public int getTotalRolledbackTransactions() {
        return totalRolledbackTransactions;
    }

    public int getWaiterCountJCAConnection() {
        return waiterCountJCAConnection;
    }

    public long getWaitingTimeJCAConnection() {
        return waitingTimeJCAConnection;
    }

    public boolean getTomcat() {
        return tomcat;
    }

    public boolean getTransaction() {
        return transaction;
    }

    public boolean getWorkers() {
        return workers;
    }

    public int getConnectionFailuresJDBCResource() {
        return connectionFailuresJDBCResource;
    }

    public int getConnectionLeaksJDBCResource() {
        return connectionLeaksJDBCResource;
    }

    public int getCurrentBusyJDBCResource() {
        return currentBusyJDBCResource;
    }

    public int getCurrentOpenedJDBCResource() {
        return currentOpenedJDBCResource;
    }

    public int getRejectedOpenJDBCResource() {
        return rejectedOpenJDBCResource;
    }

    public int getServedOpenJDBCResource() {
        return servedOpenJDBCResource;
    }

    public int getWaiterCountJDBCResource() {
        return waiterCountJDBCResource;
    }

    public long getWaitingTimeJDBCResource() {
        return waitingTimeJDBCResource;
    }

    public int getServedOpenJCAConnection() {
        return servedOpenJCAConnection;
    }

    public int getRejectedOpenJCAConnection() {
        return rejectedOpenJCAConnection;
    }

    public boolean getJcaConnection() {
        return jcaConnection;
    }

    public boolean getJdbcDatasource() {
        return jdbcDatasource;
    }

    public boolean getJmsJoram() {
        return jmsJoram;
    }
}