/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2004 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.webapp.jonasadmin;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;

import org.apache.struts.util.MessageResources;
import org.objectweb.jonas.jmx.J2eeObjectName;
import org.objectweb.jonas.jmx.JonasManagementRepr;
import org.objectweb.jonas.jmx.JonasObjectName;
import org.objectweb.jonas.jmx.ManagementException;
import org.objectweb.jonas.mail.MailServiceImpl;
import org.objectweb.jonas.jmx.CatalinaObjectName;
import org.objectweb.jonas.webapp.jonasadmin.common.BeanComparator;
import org.objectweb.jonas.webapp.jonasadmin.logging.LoggerItem;
import org.objectweb.jonas.webapp.jonasadmin.mbean.MbeanItem;
import org.objectweb.jonas.webapp.jonasadmin.service.container.WebAppItem;

/**
 * Helper class supporting manipulation of MBeans (accessing MBeans).
 * @author Michel-Ange ANTON<p>
 * Contributors: Adriana Danes
 */
public class JonasAdminJmx {

// ----------------------------------------------------------- Constants

    private static Object s_Synchro = new Object();

// ----------------------------------------------------------- Constructors

    /**
     * Protected constructor to prevent instantiation.
     */
    protected JonasAdminJmx() {
    }

// --------------------------------------------------------- Public Methods

    /**
     * Replace any occurrence of the specified placeholder in the specified
     * template string with the specified replacement value.
     *
     * @param template Pattern string possibly containing the placeholder
     * @param placeholder Placeholder expression to be replaced
     * @param value Replacement value for the placeholder
     * @return A complete string
     */
    public static String replace(String template, String placeholder, String value) {
        if (template == null) {
            return (null);
        }
        if ((placeholder == null) || (value == null)) {
            return (template);
        }
        String sRet = new String(template);
        while (true) {
            int index = sRet.indexOf(placeholder);
            if (index < 0) {
                break;
            }
            StringBuffer temp = new StringBuffer(sRet.substring(0, index));
            temp.append(value);
            temp.append(sRet.substring(index + placeholder.length()));
            sRet = temp.toString();
        }
        return (sRet);

    }

    /**
     * Return the ObjectName corresponding to the J2EEDomain managed object registered in the
     * current MBeanServer. Normally, we should have only one which has not the property 'clusterName'
     * @return an ObjectName which corresponds to the first J2EEDomain ObjectName pattern
     */
    public static ObjectName getJ2eeDomainObjectName(String serverName) {
        // Lookup for the domain J2EEDomain managed object in the current MBeanServer
        ObjectName onDomains = J2eeObjectName.J2EEDomains();
        synchronized (s_Synchro) {
            ArrayList al = new ArrayList();
            Iterator itNames = JonasManagementRepr.queryNames(onDomains, serverName).iterator();
            while(itNames.hasNext()) {
                ObjectName item = (ObjectName) itNames.next();
                if (item.getKeyProperty("clusterName") == null) {
                    return item;
                }
            }
            return null;
        }
    }

    public static ObjectName getArchiveConfigObjectName(String serverName) {
        ObjectName onUtils = JonasObjectName.ArchiveConfig();
        return getFirstMbean(onUtils, serverName);
    }

    public static ObjectName getRarConfigObjectName(String serverName) {
        ObjectName onUtils = JonasObjectName.RarConfig();
        return getFirstMbean(onUtils, serverName);
    }

    /**
     * Return the ObjectName corresponding to the J2EEServer managed object registered in the
     * current MBeanServer and belonging to a domain.
     * We should have one ObjectName corresponding to the current JOnAS server instance.
     * @param p_DomainName The name of the management domain.
     * @return an ObjectName which corresponds to a J2EEServer ObjectName pattern or null if
     * no J2EEServer found for the given management domain
     * (having <code>j2eeType</code> key property equal to <code>J2EEServer</code>)
     * @throws ManagementException if could not connect to the MBean server
     */
    public static ObjectName getJ2eeServerObjectName(String p_DomainName, String serverName) throws ManagementException {
        // Lookup for a J2EEServer managed object in the current MBeanServer
        ObjectName pattern_server_on = J2eeObjectName.J2EEServers(p_DomainName);
        ObjectName server_on = null;
        Iterator it = JonasManagementRepr.queryNames(pattern_server_on, serverName).iterator();
        if (it.hasNext()) {
            // Got one J2EEServer managed object ; normally should not be more than one
            server_on = (ObjectName) it.next();
        }
        return server_on;
    }

    /**
     * Return the ObjectName corresponding to the J2EEServer managed object registered in the
     * current MBeanServer. This method is used by EditTopAction to determine the list of
     * JOnAS servers registered in the current registry (this code is particular to the current
     * domain concept implementation).
     * We should have one ObjectName corresponding to the current JOnAS server instance.
     * @return an ObjectName which corresponds to a J2EEServer ObjectName pattern
     * (having <code>j2eeType</code> key property equal to <code>J2EEServer</code>)
     */
    public static ObjectName getJ2eeServerObjectName(String serverName) {
        // Lookup for a J2EEServer managed object in the current MBeanServer
        ObjectName pattern_server_on = J2eeObjectName.J2EEServers();
        ObjectName server_on = null;
        Iterator it = JonasManagementRepr.queryNames(pattern_server_on, serverName).iterator();
        if (it.hasNext()) {
            // Got one J2EEServer managed object ; normally should not be more than one
            server_on = (ObjectName) it.next();
        }
        return server_on;
    }

    /**
     * Verify if the Mbean gotten by the query in the current MbeanServer exists.
     *
     * @param p_On Query Mbean name to search
     * @return true if MBean exists
     * @throws ManagementException
     */
    public static boolean hasMBeanName(ObjectName p_On, String serverName)
        throws ManagementException {
        synchronized (s_Synchro) {
            ArrayList al = new ArrayList();
            Iterator itNames = JonasManagementRepr.queryNames(p_On, serverName).iterator();
            if (itNames.hasNext()) {
                return true;
            }
            return false;
        }
    }

    /**
     * Return the first Mbean name gotten by the query in the current MbeanServer.
     *
     * @param p_On Query Mbean name to search
     * @return The first MBean name or null if not found
     * @throws ManagementException
     */
    public static String getFirstMBeanName(ObjectName p_On, String serverName)
        throws ManagementException {
        synchronized (s_Synchro) {
            ArrayList al = new ArrayList();
            Iterator itNames = JonasManagementRepr.queryNames(p_On, serverName).iterator();
            if (itNames.hasNext()) {
                return itNames.next().toString();
            }
            return null;
        }
    }

    /**
     * Return the list of Mbean name gotten by the query in the current MbeanServer.
     *
     * @param p_On Query Mbean name to search
     * @return A list of string Mbean name
     * @throws ManagementException
     */
    public static List getListMBeanName(ObjectName p_On, String serverName)
        throws ManagementException {
        synchronized (s_Synchro) {
            ArrayList al = new ArrayList();
            Iterator itNames = JonasManagementRepr.queryNames(p_On, serverName).iterator();
            while (itNames.hasNext()) {
                ObjectName item = (ObjectName) itNames.next();
                al.add(item.toString());
            }
            Collections.sort(al);
            return al;
        }
    }

    /**
     * Return the first <code>ObjectName</code> Mbean gotten by the query
     * in the current MbeanServer.
     *
     * @param p_On Query Mbean name to search
     * @return The first <code>ObjectName</code> or null if not found
     * @throws ManagementException
     */
    public static ObjectName getFirstMbean(ObjectName p_On, String serverName)
        throws ManagementException {
        synchronized (s_Synchro) {
            Iterator itNames = JonasManagementRepr.queryNames(p_On, serverName).iterator();
            if (itNames.hasNext()) {
                return (ObjectName) itNames.next();
            }
            return null;
        }
    }

    /**
     * Return the list of <code>ObjectName</code> Mbean gotten by the query
     * in the current MbeanServer.
     *
     * @param p_On Query Mbeans to search
     * @return The list of <code>ObjectName</code>
     * @throws ManagementException
     */
    public static List getListMbean(ObjectName p_On, String serverName)
        throws ManagementException {
        synchronized (s_Synchro) {
            ArrayList al = new ArrayList();
            Iterator itNames = JonasManagementRepr.queryNames(p_On, serverName).iterator();
            while (itNames.hasNext()) {
                al.add(itNames.next());
            }
            return al;
        }
    }

    /**
     * Extract the value of a key property from the MBean name.
     * This method is usefull when we have the String form and not the ObjectName
     * (avoid creating an ObjectName instance).
     * @param pName Name of the key property
     * @param pMBeanName Stringified ObjectName
     * @return The value or null if not found
     */
    public static String extractValueMbeanName(String pName, String pMBeanName) {
        String sValue = null;
        try {
            String sSearch = pName.trim() + "=";
            int iPos = pMBeanName.indexOf(sSearch);
            if (iPos > -1) {
                sValue = pMBeanName.substring(iPos + sSearch.length());
                iPos = sValue.indexOf(",");
                if (iPos > -1) {
                    sValue = sValue.substring(0, iPos);
                }
            }
        } catch (NullPointerException e) {
            // none
            sValue = null;
        }
        return sValue;
    }

    /**
     * Extract the filename of complete path.
     *
     * @param p_Path Complete path (directory and filename)
     * @return The filename or null
     */
    public static String extractFilename(String p_Path) {
        String sFilename = null;
        try {
            int iPosSeparator = p_Path.lastIndexOf("/");
            if (iPosSeparator < 0) {
                iPosSeparator = p_Path.lastIndexOf("\\");
                if (iPosSeparator < 0) {
                    sFilename = new String(p_Path);
                }
                else {
                    sFilename = p_Path.substring(iPosSeparator + 1);
                }
            }
            else {
                sFilename = p_Path.substring(iPosSeparator + 1);
            }
            if (sFilename.length() > 0) {
                int iPos_1 = p_Path.indexOf(DIR_AUTOLOAD + "/" + sFilename);
                int iPos_2 = p_Path.indexOf(DIR_AUTOLOAD + "\\" + sFilename);
                if (iPos_1 > -1) {
                    sFilename = DIR_AUTOLOAD + "/" + sFilename;
                }
                else if (iPos_2 > -1) {
                    sFilename = DIR_AUTOLOAD + "\\" + sFilename;
                }
            }
            else {
                sFilename = null;
            }
        }
        catch (NullPointerException e) {
            // none action
            sFilename = null;
        }
        return sFilename;
    }

    /**
     *
     */
    private static String DIR_RARS = "rars";
    private static String DIR_AUTOLOAD = "autoload";
    private static String DIR_CONF = "conf";

    private static ArrayList getFilenames(String p_Directory, String p_Extension) {
        ArrayList al = new ArrayList();
        String sExt = "." + p_Extension.toLowerCase();
        String sFile;

        File oFile = new File(p_Directory);
        String[] asFiles = oFile.list();
        int iPos;
        if (asFiles != null) {
            for (int i = 0; i < asFiles.length; i++) {
                oFile = new File(p_Directory, asFiles[i]);
                if (oFile.isFile() == true) {
                    sFile = oFile.getName().toLowerCase();
                    iPos = sFile.lastIndexOf(sExt);
                    if (iPos > -1) {
                        if (iPos == (sFile.length() - sExt.length())) {
                            al.add(oFile.getName());
                        }
                    }
                }
            }
        }
        Collections.sort(al);
        return al;
    }

    private static ArrayList getDirectories(String p_Directory) {
        ArrayList al = new ArrayList();
        String sFile;

        File oFile = new File(p_Directory);
        String[] asFiles = oFile.list();

        if (asFiles != null) {
            for (int i = 0; i < asFiles.length; i++) {
                oFile = new File(p_Directory, asFiles[i]);
                if (oFile.isDirectory() == true) {
                    al.add(oFile.getName());
                }
            }
        }
        Collections.sort(al);
        return al;
    }

    private static void appendDirectory(ArrayList p_List, String p_Dir) {
        String sDir = p_Dir + "/";
        for (int i = 0; i < p_List.size(); i++) {
            p_List.set(i, sDir + p_List.get(i));
        }
    }

    /**
     * Return the list of JAR filename ready to deploy in the current server.
     *
     * @return The list of JAR filename.
     * @throws ManagementException
     */
    public static ArrayList getJarFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.ejbService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployableJars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "EjbjarsDirectory", serverName);

        String sEarDir = null;
        try {
            on = JonasObjectName.earService();
            sEarDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        }
        catch (Exception e) {
            // nothing, Ear service not found
        }
        return prepareContainersToDisplay(al, sDir, sEarDir);
    }

    /**
     * Return the list of RAR filename ready to deploy in the current server.
     *
     * @return The list of RAR filename.
     * @throws ManagementException
     */
    public static ArrayList getRarFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.resourceService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployableRars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "RarsDirectory", serverName);

        String sEarDir = null;
        try {
            on = JonasObjectName.earService();
            sEarDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        }
        catch (Exception e) {
            // nothing, Ear service not found
        }
        return prepareContainersToDisplay(al, sDir, sEarDir);
    }

    /**
     * Return the list of EAR filename ready to deploy in the current server.
     *
     * @return The list of EAR filename.
     * @throws ManagementException
     */
    public static ArrayList getEarFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.earService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployableEars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        return prepareContainersToDisplay(al, sDir, null);
    }

    /**
     * Return the list of WAR filename ready to deploy in the current server.
     *
     * @return The list of WAR filename.
     * @throws ManagementException
     */
    public static ArrayList getWarFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.webContainerService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployableWars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "WebappsDirectory", serverName);

        String sEarDir = null;
        try {
            on = JonasObjectName.earService();
            sEarDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        }
        catch (Exception e) {
            // nothing, Ear service not found
        }
        return prepareContainersToDisplay(al, sDir, sEarDir);
    }

    /**
     * Return the list of deployed JAR filename in the current server.
     *
     * @return The list of JAR filename.
     * @throws ManagementException
     */
    public static ArrayList getJarFilesDeployed(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.ejbService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployedJars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "EjbjarsDirectory", serverName);

        String sEarDir = null;
        try {
            on = JonasObjectName.earService();
            sEarDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        }
        catch (Exception e) {
            // nothing, Ear service not found
        }
        return prepareContainersToDisplay(al, sDir, sEarDir);
    }

    /**
     * Return the list of deployed EAR filename in the current server.
     *
     * @return The list of EAR filename.
     * @throws ManagementException
     */
    public static ArrayList getEarFilesDeployed(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.earService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployedEars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        return prepareContainersToDisplay(al, sDir, null);
    }

    /**
     * Return the list of deployed RAR filename in the current server.
     *
     * @return The list of RAR filename.
     * @throws ManagementException
     */
    public static ArrayList getRarFilesDeployed(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.resourceService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployedRars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "RarsDirectory", serverName);

        String sEarDir = null;
        try {
            on = JonasObjectName.earService();
            sEarDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        }
        catch (ManagementException e) {
            // nothing, Ear service not found
        }
        return prepareContainersToDisplay(al, sDir, sEarDir);
    }

    /**
     * Return the list of deployed WAR filename in the current server.
     *
     * @return The list of WAR filename.
     * @throws ManagementException
     */
    public static ArrayList getWarFilesDeployed(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.webContainerService();
        ArrayList al = (ArrayList) JonasManagementRepr.getAttribute(on, "DeployedWars", serverName);
        String sDir = (String) JonasManagementRepr.getAttribute(on, "WebappsDirectory", serverName);

        String sEarDir = null;
        try {
            on = JonasObjectName.earService();
            sEarDir = (String) JonasManagementRepr.getAttribute(on, "AppsDirectory", serverName);
        }
        catch (ManagementException e) {
            // nothing, Ear service not found
        }
        return prepareContainersToDisplay(al, sDir, sEarDir);
    }

    /**
     * Prepare a list of containers to diplay.
     * Deleting prefix root container directory, sorting the list.
     * @param p_Containers The list of containers
     * @param p_ContainerDir The root container directory
     * @param p_EarDir The root ear directory or null
     * @return The list of containers ready to display
     */
    public static ArrayList prepareContainersToDisplay(ArrayList p_Containers
        , String p_ContainerDir, String p_EarDir) {
        int iPos;
        String sPath;
        boolean bAdd;
        ArrayList al = new ArrayList();
        for (int i = 0; i < p_Containers.size(); i++) {
            // Delete prefix root container directory
            sPath = p_Containers.get(i).toString();
            iPos = sPath.indexOf(p_ContainerDir);
            if (iPos > -1) {
                sPath = sPath.substring(p_ContainerDir.length());
            }
            // Delete suffix slash
            if (sPath.endsWith("/") == true) {
                sPath = sPath.substring(0, sPath.length() - 1);
            }
            // Flag to filter
            bAdd = true;
            // Filter Jar or War include in Ear
            if (p_EarDir != null) {
                iPos = sPath.indexOf(p_EarDir);
                if (iPos > -1) {
                    bAdd = false;
                }

            }
            if (bAdd == true) {
                al.add(sPath);
            }
        }
        // Sort
        Collections.sort(al);
        return al;
    }

    private static ArrayList getFilesDeployed(ObjectName on, String serverName)
        throws ManagementException {
        ArrayList alDeployed = new ArrayList();
        String sPath;
        String sFile;
        Iterator itNames = JonasAdminJmx.getListMBeanName(on, serverName).iterator();
        while (itNames.hasNext()) {
            sPath = JonasAdminJmx.extractValueMbeanName("fname", itNames.next().toString());
            sFile = JonasAdminJmx.extractFilename(sPath);
            if (sFile != null) {
                alDeployed.add(sFile);
            }
        }
        Collections.sort(alDeployed);
        return alDeployed;

    }

    /**
     * Return the list of Mail factory files ready to deploy in the current server.
     *
     * @return The list of Mail factory properties filenames.
     * @throws ManagementException
     */
    public static ArrayList getMailFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.mailService();
        return (ArrayList) JonasManagementRepr.getAttribute(on, "MailFactoryPropertiesFiles", serverName);
    }

    /**
         * Return the list of MimePartDataSource Mail factory files ready to deploy in the current server.
     *
     * @return The list of MimePartDataSource Mail factory properties filenames.
     * @throws ManagementException
     */
    public static ArrayList getMimePartMailFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.mailService();
        return (ArrayList) JonasManagementRepr.getAttribute(on
            , "MimePartMailFactoryPropertiesFiles", serverName);
    }

    /**
     * Return the list of Session Mail factory files ready to deploy in the current server.
     *
     * @return The list of Session Mail factory properties filenames.
     * @throws ManagementException
     */
    public static ArrayList getSessionMailFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.mailService();
        return (ArrayList) JonasManagementRepr.getAttribute(on, "SessionMailFactoryPropertiesFiles", serverName);
    }

    /**
     * Return the list of deployed MimePartDataSource Mail factories in the current server.
     *
     * @param p_WhereAreYou The container WhereAreYou
     * @return The list of MimePartDataSource Mail factory filename.
     * @throws ManagementException
     */
    public static ArrayList getMimePartMailFilesDeployed(WhereAreYou p_WhereAreYou)
        throws ManagementException {
        ArrayList alDeployed = new ArrayList();
        String sName;
        String domainName = p_WhereAreYou.getCurrentDomainName();
        String serverName = p_WhereAreYou.getCurrentJonasServerName();
        ObjectName on = J2eeObjectName.JavaMailResources(domainName, serverName
            , MailServiceImpl.MIMEPART_PROPERTY_TYPE);
        Iterator itNames = JonasManagementRepr.queryNames(on, serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName it_on = (ObjectName) itNames.next();
            sName = it_on.getKeyProperty("name");
            if (sName != null) {
                alDeployed.add(sName);
            }
        }
        Collections.sort(alDeployed);
        return alDeployed;
    }

    /**
     * Return the list of deployed Session Mail factories in the current server.
     *
     * @param p_WhereAreYou The container WhereAreYou
     * @return The list of Session Mail factory filename.
     * @throws ManagementException
     */
    public static ArrayList getSessionMailFilesDeployed(WhereAreYou p_WhereAreYou)
        throws ManagementException {
        ArrayList alDeployed = new ArrayList();
        String sName;
        String domainName = p_WhereAreYou.getCurrentDomainName();
        String serverName = p_WhereAreYou.getCurrentJonasServerName();
        ObjectName on = J2eeObjectName.JavaMailResources(domainName, serverName
            , MailServiceImpl.SESSION_PROPERTY_TYPE);
        Iterator itNames = JonasManagementRepr.queryNames(on, serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName it_on = (ObjectName) itNames.next();
            sName = it_on.getKeyProperty("name");
            if (sName != null) {
                alDeployed.add(sName);
            }
        }
        Collections.sort(alDeployed);
        return alDeployed;
    }

    /**
     * Return the list of deployed Mail factories in the current server.
     *
     * @param p_WhereAreYou The container WhereAreYou
     * @return The list of Mail factory filename.
     * @throws ManagementException
     */
    public static ArrayList getMailFilesDeployed(WhereAreYou p_WhereAreYou)
        throws ManagementException {
        ArrayList alDeployed = getSessionMailFilesDeployed(p_WhereAreYou);
        alDeployed.addAll(getMimePartMailFilesDeployed(p_WhereAreYou));
        Collections.sort(alDeployed);
        return alDeployed;
    }

    /**
     * Return the list of Datasource properties files ready to deploy in the current server.
     *
     * @return The list of Datasource properties filenames.
     * @throws ManagementException Could not get managzement info from the MBeanServer
     */
    public static ArrayList getDatasourceFilesDeployable(String serverName)
        throws ManagementException {
        ObjectName on = JonasObjectName.databaseService();
        return (ArrayList) JonasManagementRepr.getAttribute(on, "DataSourcePropertiesFiles", serverName);
    }

    /**
     * Return the list of deployed Datasources in the current server.
     * @param domainName Current domain name
     * @param serverName Current server name
     * @return The list of Datasource filename.
     * @throws ManagementException Could not get managzement info from the MBeanServer
     */
    public static ArrayList getDatasourceFilesDeployed(String domainName, String serverName)
        throws ManagementException {

        ArrayList alDeployed = new ArrayList();
        ObjectName ons = J2eeObjectName.JDBCDataSources(domainName, serverName);
        // iterate ovent the JDBCDataSources within the current server
        Iterator itNames = JonasManagementRepr.queryNames(ons, serverName).iterator();
        String sName = null;
        while (itNames.hasNext()) {
            ObjectName on = (ObjectName) itNames.next();
            sName = on.getKeyProperty("name");
            if (sName != null) {
                alDeployed.add(sName);
            }
        }
        Collections.sort(alDeployed);
        return alDeployed;
    }

    /**
     * Return the list of Datasource dependences for a given datasource name in the current server.
     *
     * @param pDatasourceName The name of the datasource
     * @param domainName Current domain name
     * @param serverName Current server name
     * @return The list of Datasource dependence (a list of names corresponding to EJBs using this datasource).
     * @throws ManagementException Could not get managzement info from the MBeanServer
     * @throws MalformedObjectNameException
     */
    public static ArrayList getDatasourceDependences(String pDatasourceName, String domainName, String serverName)
        throws ManagementException {
        ObjectName jdbcDatasource = J2eeObjectName.getJDBCDataSource(domainName, serverName, pDatasourceName);
        String[] asParam = new String[1];
        String[] asSignature = new String[1];
        asSignature[0] = "java.lang.String";
        ArrayList al = new ArrayList();
        asParam[0] = (String) JonasManagementRepr.getAttribute(jdbcDatasource, "jndiName", serverName);
        if (JonasManagementRepr.isRegistered(JonasObjectName.ejbService(), serverName)) {
            String sName;
            Iterator it = ((java.util.Set) JonasManagementRepr.invoke(JonasObjectName.ejbService()
                , "getDataSourceDependence", asParam, asSignature, serverName)).iterator();
            while (it.hasNext()) {
                sName = JonasAdminJmx.extractValueMbeanName(",name", it.next().toString());
                if (sName != null) {
                    al.add(sName);
                }
            }
            Collections.sort(al);
        }
        return al;
    }

    /**
     * Return the list of Mail factory dependences in the current server for a given factory name.
     *
     * @param p_MailFactoryName The name of the mail factory
     * @param p_WhereAreYou The container WhereAreYou
     * @return The list of Mail factory dependences (a list of names corresponding to EJBs using this mail factory).
     * @throws ManagementException
     */
    public static ArrayList getMailFactoryDependences(String p_MailFactoryName
        , WhereAreYou p_WhereAreYou)
        throws ManagementException {
        String jndiName = null;
        String domainName = p_WhereAreYou.getCurrentDomainName();
        String serverName = p_WhereAreYou.getCurrentJonasServerName();
        String type = MailServiceImpl.SESSION_PROPERTY_TYPE;
        // create an MBean name with the given MailFactory name
        // - try with a session Mail Factory type
        ObjectName on = J2eeObjectName.JavaMailResource(domainName, p_MailFactoryName, serverName
            , type);
        //ObjectName on = JonasObjectName.sessionMailFactory(p_MailFactoryName);
        if (JonasManagementRepr.isRegistered(on, serverName) != true) {
            // in this case, this is a MimePartDataSource mail factory
            //on = JonasObjectName.mimeMailFactory(p_MailFactoryName);
            type = MailServiceImpl.MIMEPART_PROPERTY_TYPE;
            on = J2eeObjectName.JavaMailResource(domainName, p_MailFactoryName, serverName, type);
        }
        jndiName = (String) JonasManagementRepr.getAttribute(on, "Name", serverName);

        String[] asParam = new String[1];
        String[] asSignature = new String[1];
        asSignature[0] = "java.lang.String";
        ArrayList al = new ArrayList();
        asParam[0] = jndiName;
        if (JonasManagementRepr.isRegistered(JonasObjectName.ejbService(), serverName) == true) {
            String sName;
            Iterator it = ((java.util.Set) JonasManagementRepr.invoke(JonasObjectName.ejbService()
                , "getMailFactoryDependence", asParam, asSignature, serverName)).iterator();
            while (it.hasNext()) {
                sName = JonasAdminJmx.extractValueMbeanName(",name", it.next().toString());
                if (sName != null) {
                    al.add(sName);
                }
            }
            Collections.sort(al);
        }
        return al;
    }

    /**
     * Return the list of deployed Session Mail Factories in the current server.
     *
     * @param p_WhereAreYou The container WhereAreYou
     * @return The list
     * @throws ManagementException
     */
    public static ArrayList getSessionMailFactoriesDeployed(WhereAreYou p_WhereAreYou)
        throws ManagementException {

        ArrayList alDeployed = new ArrayList();
        String sName;
        String domainName = p_WhereAreYou.getCurrentDomainName();
        String serverName = p_WhereAreYou.getCurrentJonasServerName();
        String type = MailServiceImpl.SESSION_PROPERTY_TYPE;

        ObjectName any_on = J2eeObjectName.JavaMailResources(domainName, serverName, type);
        Iterator itNames = JonasManagementRepr.queryNames(any_on, serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName on = (ObjectName) itNames.next();
            sName = on.getKeyProperty("name");
            if (sName != null) {
                alDeployed.add(sName);
            }
        }

        Collections.sort(alDeployed);
        return alDeployed;
    }

    /**
     * Return the list of deployed MimePartDatasource Mail Factories in the current server.
     *
     * @param p_WhereAreYou The container WhereAreYou
     * @return The list
     * @throws ManagementException
     */
    public static ArrayList getMimeMailPartFactoriesDeployed(WhereAreYou p_WhereAreYou)
        throws ManagementException {
        ArrayList alDeployed = new ArrayList();
        String sName;
        String domainName = p_WhereAreYou.getCurrentDomainName();
        String serverName = p_WhereAreYou.getCurrentJonasServerName();
        String type = MailServiceImpl.MIMEPART_PROPERTY_TYPE;

        ObjectName any_on = J2eeObjectName.JavaMailResources(domainName, serverName, type);
        Iterator itNames = JonasManagementRepr.queryNames(any_on, serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName on = (ObjectName) itNames.next();
            sName = on.getKeyProperty("name");
            if (sName != null) {
                alDeployed.add(sName);
            }
        }
        Collections.sort(alDeployed);
        return alDeployed;
    }

    /**
     * Return the list of Security Memory Factories in the current server.
     *
     * @return The list of Security Memory Factories
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static ArrayList getSecurityMemoryFactories(String serverName)
        throws ManagementException, MalformedObjectNameException {
        String sName;
        ArrayList al = new ArrayList();
        Iterator itNames = getListMBeanName(JonasObjectName.allSecurityMemoryFactories(), serverName).iterator();
        while (itNames.hasNext()) {
            sName = JonasAdminJmx.extractValueMbeanName(",name", itNames.next().toString());
            if (sName != null) {
                al.add(sName);
            }
        }
        Collections.sort(al);
        return al;
    }

    /**
     * Return the list of Security Datasource Factories in the current server.
     *
     * @return The list of Security Datasource Factories
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static ArrayList getSecurityDatasourceFactories(String serverName)
        throws ManagementException, MalformedObjectNameException {
        String sName;
        ArrayList al = new ArrayList();
        Iterator itNames = getListMBeanName(JonasObjectName.allSecurityDatasourceFactories(), serverName).
            iterator();
        while (itNames.hasNext()) {
            sName = JonasAdminJmx.extractValueMbeanName(",name", itNames.next().toString());
            if (sName != null) {
                al.add(sName);
            }
        }
        Collections.sort(al);
        return al;
    }

    /**
     * Return the list of Security Ldap Factories in the current server.
     *
     * @return The list of Security Ldap Factories
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static ArrayList getSecurityLdapFactories(String serverName)
        throws ManagementException, MalformedObjectNameException {
        String sName;
        ArrayList al = new ArrayList();
        Iterator itNames = getListMBeanName(JonasObjectName.allSecurityLdapFactories(), serverName).iterator();
        while (itNames.hasNext()) {
            sName = JonasAdminJmx.extractValueMbeanName(",name", itNames.next().toString());
            if (sName != null) {
                al.add(sName);
            }
        }
        Collections.sort(al);
        return al;
    }

    /**
     * Return the SubType of a Security Factory in the current server.
     *
     * @param p_NameFactory The factory name to find
     * @return The SubType or null if not found
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static String findSecurityFactorySubType(String p_NameFactory, String serverName)
        throws ManagementException, MalformedObjectNameException {
        String sName;
        String sSubType = null;
        ObjectName on = null;

        Iterator itNames = getListMBeanName(JonasObjectName.allSecurityFactories(), serverName).iterator();
        while (itNames.hasNext()) {
            on = new ObjectName(itNames.next().toString());
            sName = on.getKeyProperty("name");
            if (p_NameFactory.equals(sName) == true) {
                sSubType = on.getKeyProperty("subtype");
                break;
            }
        }
        return sSubType;
    }

    /**
     * Return the list of all users in a resource.
     *
     * @param p_Resource The resource
     * @return The list of users
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static ArrayList getUsers(String p_Resource, String serverName)
        throws ManagementException, MalformedObjectNameException {
        String sName;
        ArrayList al = new ArrayList();
        Iterator itNames = getListMBeanName(JonasObjectName.allUsers(p_Resource), serverName).iterator();
        while (itNames.hasNext()) {
            sName = JonasAdminJmx.extractValueMbeanName(",name", itNames.next().toString());
            if (sName != null) {
                al.add(sName);
            }
        }
        Collections.sort(al);
        return al;
    }

    /**
     * Return the list of all roles in a resource.
     *
     * @param p_Resource The resource
     * @return The list of roles
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static ArrayList getRoles(String p_Resource, String serverName)
        throws ManagementException, MalformedObjectNameException {
        String sName;
        ArrayList al = new ArrayList();
        Iterator itNames = getListMBeanName(JonasObjectName.allRoles(p_Resource), serverName).iterator();
        while (itNames.hasNext()) {
            sName = JonasAdminJmx.extractValueMbeanName(",name", itNames.next().toString());
            if (sName != null) {
                al.add(sName);
            }
        }
        Collections.sort(al);
        return al;
    }

    /**
     * Return the list of all groups in a resource.
     *
     * @param p_Resource The resource
     * @return The list of groups
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static ArrayList getGroups(String p_Resource, String serverName)
        throws ManagementException, MalformedObjectNameException {
        String sName;
        ArrayList al = new ArrayList();
        Iterator itNames = getListMBeanName(JonasObjectName.allGroups(p_Resource), serverName).iterator();
        while (itNames.hasNext()) {
            sName = JonasAdminJmx.extractValueMbeanName(",name", itNames.next().toString());
            if (sName != null) {
                al.add(sName);
            }
        }
        Collections.sort(al);
        return al;
    }

    /**
     * Return a list of names bounded in the registry.
     *
     * @return The list
     * @throws NamingException
     */
    public static ArrayList getRegistryList(String serverName)
        throws NamingException {
        synchronized (s_Synchro) {
            ArrayList oNames = new ArrayList();
            // get the naming context
            Context ctx = JonasManagementRepr.getContext(serverName);
            // get all names bounded in the contexr
            for (NamingEnumeration e = ctx.list(""); e.hasMoreElements(); ) {
                oNames.add(((NameClassPair) e.nextElement()).getName());
            }
            return oNames;
        }
    }

    /**
     * Return the Queue destinations list.
     * @return The list
     */
    public static ArrayList getQueuesList(String serverName) {
        synchronized (s_Synchro) {
            ObjectName jmsServMB = JonasObjectName.jmsService();
            Set queues = (Set) JonasManagementRepr.getAttribute(jmsServMB
                , "AllJmsQueueDestinationNames", serverName);
            ArrayList al = new ArrayList();
            Iterator itNames = queues.iterator();
            while (itNames.hasNext()) {
                al.add(itNames.next());
            }
            return al;
        }
    }

    /**
     * Return the Topic destinations list.
     * @return The list
     */
    public static ArrayList getTopicsList(String serverName) {
        synchronized (s_Synchro) {
            ObjectName jmsServMB = JonasObjectName.jmsService();
            Set topics = (Set) JonasManagementRepr.getAttribute(jmsServMB
                , "AllJmsTopicDestinationNames", serverName);
            ArrayList al = new ArrayList();
            Iterator itNames = topics.iterator();
            while (itNames.hasNext()) {
                al.add(itNames.next());
            }
            return al;
        }
    }

    /**
     * Return the default Connection Factories.
     *
     * @param p_Resources The messages
     * @return The list
     */
    public static ArrayList getConnectionFactoriesList(MessageResources p_Resources, String serverName) {
        synchronized (s_Synchro) {
            ObjectName jmsServMB = JonasObjectName.jmsService();
            String cfName = (String) JonasManagementRepr.getAttribute(jmsServMB
                , "DefaultConnectionFactoryName", serverName);
            String tcfName = (String) JonasManagementRepr.getAttribute(jmsServMB
                , "DefaultTopicConnectionFactoryName", serverName);
            String qcfName = (String) JonasManagementRepr.getAttribute(jmsServMB
                , "DefaultQueueConnectionFactoryName", serverName);
            ArrayList al = new ArrayList();
            String comment = p_Resources.getMessage("tab.connfact.defaultconnfact");
            JmsConnFact cf = new JmsConnFact(cfName, comment);
            al.add(cf);
            comment = p_Resources.getMessage("tab.connfact.defaulttopicconnfact");
            cf = new JmsConnFact(tcfName, comment);
            al.add(cf);
            comment = p_Resources.getMessage("tab.connfact.defaultqueueconnfact");
            cf = new JmsConnFact(qcfName, comment);
            al.add(cf);
            return al;
        }
    }

    /**
     * Return the list of all used loggers in this JOnAS server.
     * @param p_Resources The used message resource
     * @param p_WhereAreYou The used WhereAreYou instance
     * @param p_Action True to get the action (to use directly in jsp) or False to get the same action but in forward (write in the file struts-config.xml)
     * @return The list of loggers
     * @throws ManagementException
     * @throws MalformedObjectNameException
     */
    public static ArrayList getLoggers(MessageResources p_Resources, WhereAreYou p_WhereAreYou
        , boolean p_Action)
        throws ManagementException, MalformedObjectNameException {
        String serverName = p_WhereAreYou.getCurrentJonasServerName();
        ArrayList al = new ArrayList();
        String sActionForward;
        // Get JONAS logger
        if (p_Action == true) {
            sActionForward = "EditLoggingJonas.do";
        }
        else {
            sActionForward = "ActionEditLoggingJonas";
        }
        String itemName = p_Resources.getMessage("logger.jonas.name");
        String type = LoggerItem.LOGGER_JONAS;
        LoggerItem li = new LoggerItem(itemName, type, sActionForward);
        al.add(li);
        // Get Catalina Logger
        if (p_WhereAreYou.isCatalinaServer() == true) {
            ObjectName on = CatalinaObjectName.catalinaAccessLogValves(p_WhereAreYou.
                getCurrentCatalinaDomainName());

            Iterator it = getListMbean(on, serverName).iterator();
            while (it.hasNext()) {
                ObjectName oItem = (ObjectName) it.next();
                if (p_Action) {
                    sActionForward = "EditCatalinaAccessLogger.do?select=" + oItem.toString();
                }
                else {
                    sActionForward = "ActionEditCatalinaAccessLogger";
                }
                itemName = p_Resources.getMessage("logger.catalina.access.name");
                String hostName = oItem.getKeyProperty("host");
                String containerName = null;
                String containerType = null;
                String containerLabel = null;
                if (hostName == null) {
                    type = LoggerItem.LOGGER_CATALINA_ACCESS_ENGINE;
                    containerType = p_Resources.getMessage("label.loggers.container.engine");
                    containerName = p_Resources.getMessage("label.loggers.container.engine.name");
                    containerLabel = containerName;
                } else {
                    String pathName = oItem.getKeyProperty("path");
                    if (pathName != null) {
                        type = LoggerItem.LOGGER_CATALINA_ACCESS_CONTEXT;
                        containerName = pathName;
                        containerType = p_Resources.getMessage("label.loggers.container.context");
                        containerLabel = WebAppItem.extractLabelPathContext(containerName, p_WhereAreYou.getCurrentCatalinaDefaultHostName());
                    } else {
                        type = LoggerItem.LOGGER_CATALINA_ACCESS_HOST;
                        containerName = hostName;
                        containerType = p_Resources.getMessage("label.loggers.container.host");
                        containerLabel = containerName;
                    }
                }
                itemName = itemName.concat(" " + containerLabel);
                li = new LoggerItem(itemName, type, sActionForward, oItem.toString(), containerType, containerName);
                al.add(li);
            }
        }
        // sort
        Collections.sort(al, new BeanComparator(new String[]{"name"}));
        return al;
    }

    /**
     * Create a list for each family of Mbean.
     *
     * @return An array of lists
     * @throws ManagementException
     */
    public static ArrayList getMbeansLists(String serverName)
        throws ManagementException {

        MbeanItem oItem;

        // Create the new list
        ArrayList al = new ArrayList();
        // Dispath each Mbean in its list
        Iterator it = JonasAdminJmx.getListMbean(null, serverName).iterator();
        while (it.hasNext()) {
            oItem = MbeanItem.build((ObjectName) it.next());
            al.add(oItem);
        }
        return al;
    }

    /**
     * Create a list for each family of Mbean.
     *
     * @return An array of lists
     * @throws ManagementException
     */
    public static ArrayList[] getFamiliesMbeansLists(String serverName)
        throws ManagementException {

        MbeanItem oItem;

        // Create the new lists
        ArrayList[] als = new ArrayList[3];
        for (int i = 0; i < MbeanItem.SIZE_FAMILIES; i++) {
            als[i] = new ArrayList();
        }
        // Dispath each Mbean in its list
        Iterator it = JonasAdminJmx.getListMbean(null, serverName).iterator();
        while (it.hasNext()) {
            oItem = MbeanItem.build((ObjectName) it.next());
            als[oItem.getFamily()].add(oItem);
        }
        return als;
    }
}
