/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2008 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.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.servlet.http.HttpServletRequest;

import org.allesta.wsabi.j2ee.Handler;
import org.allesta.wsabi.j2ee.PortComponent;
import org.allesta.wsabi.j2ee.WebServiceDescription;
import org.allesta.wsabi.j2ee.provider.GenericDomainCapableProvider;
import org.allesta.wsabi.j2ee.provider.jonas.JonasProvider;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.util.MessageResources;
import org.objectweb.jonas.jmx.CatalinaObjectName;
import org.objectweb.jonas.jmx.J2eeObjectName;
import org.objectweb.jonas.jmx.JonasManagementRepr;
import org.objectweb.jonas.jmx.JonasObjectName;
import org.objectweb.jonas.jmx.JoramObjectName;
import org.objectweb.jonas.webapp.jonasadmin.catalina.ConnectorItem;
import org.objectweb.jonas.webapp.jonasadmin.catalina.ConnectorItemByPort;
import org.objectweb.jonas.webapp.jonasadmin.common.BeanComparator;
import org.objectweb.jonas.webapp.jonasadmin.joramplatform.ItemDestination;
import org.objectweb.jonas.webapp.jonasadmin.logging.LoggerItem;
import org.objectweb.jonas.webapp.jonasadmin.mbean.J2eeMbeanItem;
import org.objectweb.jonas.webapp.jonasadmin.mbean.MbeanItem;
import org.objectweb.jonas.webapp.jonasadmin.mbean.OwnerMbeanItem;
import org.objectweb.jonas.webapp.jonasadmin.service.container.ContainerItem;
import org.objectweb.jonas.webapp.jonasadmin.service.container.ContainerItemByFile;
import org.objectweb.jonas.webapp.jonasadmin.service.container.WebAppItem;
import org.objectweb.jonas.webapp.jonasadmin.service.container.WebAppItemByPathContext;
import org.objectweb.jonas.webapp.jonasadmin.service.ejb.EjbItem;
import org.objectweb.jonas.webapp.jonasadmin.service.ejb.EjbItemByNameComparator;
import org.objectweb.jonas.webapp.jonasadmin.service.resource.ResourceItem;
import org.objectweb.jonas.webapp.jonasadmin.service.resource.ResourceItemByFile;
import org.objectweb.jonas.webapp.jonasadmin.jonasmqconnect.util.MqObjectNames;
import org.objectweb.jonas.webapp.taglib.TreeBuilder;
import org.objectweb.jonas.webapp.taglib.TreeControl;
import org.objectweb.jonas.webapp.taglib.TreeControlNode;

/**
 * Implementation of <code>TreeBuilder</code> that adds the nodes required
 * for administering the Jonas server.
 *
 * @author Michel-Ange ANTON (initial developer)
 * @author Adriana Danes : add nodes for JMS service
 * @author Florent Benoit (changes for struts 1.2.2)
 */
public class JonasTreeBuilder implements TreeBuilder {

// ----------------------------------------------------- Instance Variables

// ---------------------------------------------------- TreeBuilder Methods
    /**
     * Add the required nodes to the specified <code>treeControl</code>
     * instance.
     *
     * @param treeControl The <code>TreeControl</code> to which we should
     *  add our nodes
     * @param servlet The controller servlet for the admin application
     * @param request The servlet request we are processing
     */
    public void buildTree(TreeControl treeControl, ActionServlet servlet
        , HttpServletRequest request) {
        try {
            TreeControlNode rootNode = treeControl.getRoot();
            MessageResources resources = (MessageResources) servlet.getServletContext().
                getAttribute(Globals.MESSAGES_KEY);
            getDomain(rootNode, resources, request);
        } catch (Throwable t) {
            t.printStackTrace(System.out);
        }
    }

// ------------------------------------------------------ Protected Methods

    /**
     * Append nodes for the current domain.
     *
     * @param p_RootNode Root node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDomain(TreeControlNode p_RootNode, MessageResources p_Resources
        , HttpServletRequest p_Request)
        throws Exception {
        // Add domain node
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);
        //String sDomain = oWhere.getCurrentDomain().toString();// OBJECT_NAME
        String sDomainName = oWhere.getCurrentDomainName();// value of the 'name' key property
        String sServerName = oWhere.getCurrentJonasServerName();

        String sNodeLabel = p_Resources.getMessage("treenode.jonas.domain") + " ( " + sDomainName
            + " )";
        TreeControlNode domainNode = new TreeControlNode("domain", "icon/domain_jonas.gif"
            , sNodeLabel, "EditDomain.do?select=" + URLEncoder.encode(sDomainName, "UTF-8"), "content", true);
        p_RootNode.addChild(domainNode);

        // Add children
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.discoveryService(), sServerName) && isMaster(p_Request, sServerName)) {
            getMonitoring(domainNode, p_Resources, p_Request, sDomainName, sServerName);
            getDomainDeploy(domainNode, p_Resources, p_Request);
        }
        getServer(domainNode, p_Resources, p_Request, sDomainName, sServerName);
        getJoramPlatform(domainNode, sServerName, p_Resources, p_Request);
        getMBeans(domainNode, p_Resources, p_Request);
    }

    /**
     * Returns if the current server (with discovery running) is a master server.
     * @return if the current server is a master server.
     */
    protected boolean isMaster(HttpServletRequest p_Request, String serverName) {
        ObjectName oObjectName = JonasObjectName.discoveryService();
        Boolean result = (Boolean) JonasManagementRepr.getAttribute(oObjectName, "IsDiscoveryMaster", serverName);
        return result.booleanValue();
    }

    /**
     * Append nodes for domain management deployment.
     *
     * @param p_DomainNode Domain node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     * @param p_DomainName The name of the domain.
     *
     * @throws Exception if an exception occurs building the tree
     */
    protected void getDomainDeploy(TreeControlNode p_DomainNode, MessageResources p_Resources
            , HttpServletRequest p_Request)
            throws Exception {

        TreeControlNode nodeDeployments = new TreeControlNode(p_DomainNode.getName()
                + WhereAreYou.NODE_SEPARATOR + "deployments", "icon/deployDomainManage.gif"
                , p_Resources.getMessage("treenode.jonas.server.deployments"), null, "content", true);
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
                SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        p_DomainNode.addChild(1, nodeDeployments);
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.earService(), serverName) == true) {
            getDomainDeploymentEar(nodeDeployments, p_Resources);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.ejbService(), serverName) == true) {
            getDomainDeploymentEjb(nodeDeployments, p_Resources);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.webContainerService(), serverName) == true) {
            getDomainDeploymentWebAppli(nodeDeployments, p_Resources);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.resourceService(), serverName) == true) {
            getDomainDeploymentRar(nodeDeployments, p_Resources);
        }
    }

    /**
     * Append node for Ear deployment using domain management.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDomainDeploymentEar(TreeControlNode p_NodeDeployments, MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_EAR, "icon/deployDomain_ear.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_EAR)
            , "EditDomainDeploy.do?type=" + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_EAR, "content", false);
        p_NodeDeployments.addChild(oNode);
    }

    /**
     * Append node for Ejb deployment using domain management.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDomainDeploymentEjb(TreeControlNode p_NodeDeployments, MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_JAR, "icon/deployDomain_jar.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_JAR)
            , "EditDomainDeploy.do?type=" + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_JAR, "content", false);
        p_NodeDeployments.addChild(oNode);

        // Add list files
        //getDeploymentJarFiles(oNode, p_Resources);
    }

    /**
     * Append node for Web deployment using domain management.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDomainDeploymentWebAppli(TreeControlNode p_NodeDeployments
        , MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_WAR, "icon/deployDomain_war.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_WAR)
            , "EditDomainDeploy.do?type=" + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_WAR, "content", false);
        p_NodeDeployments.addChild(oNode);
    }

    /**
     * Append node for Rar deployment using domain management.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDomainDeploymentRar(TreeControlNode p_NodeDeployments, MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_RAR, "icon/deployDomain_rar.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_RAR)
            , "EditDomainDeploy.do?type=" + WhereAreYou.DOMAIN_DEPLOYMENT_STRING_RAR, "content", false);
        p_NodeDeployments.addChild(oNode);
    }

    /**
     * Append nodes for a defined Jonas server.
     *
     * @param p_DomainNode Domain node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServer(TreeControlNode p_DomainNode
            , MessageResources p_Resources, HttpServletRequest p_Request
            , String p_DomainName, String p_ServerName)
        throws Exception {
        // Add server node
        /* Implem note
         * -----------
         * Currently we have only one server in the domain, it's id being registered
         * in helper class WhereAreYou. This will change with in the next version
         * with full Domain support. We'll have to query for all the J2EEServer MBeans.
         */
        String sServerName = p_ServerName;
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
                SESSION_NAME);
        String sServer = oWhere.getCurrentJonasServer().toString();
        String sNodeLabel = p_Resources.getMessage("treenode.jonas.server") + " ( " + sServerName + " )";
        TreeControlNode serverNode = new TreeControlNode(p_DomainNode.getName()
            + WhereAreYou.NODE_SEPARATOR + sServerName, "icon/BalJonasTree.gif", sNodeLabel
            , "EditJonasServer.do?select=" + URLEncoder.encode(sServer, "UTF-8"), "content", true);
        p_DomainNode.addChild(serverNode);
        // Add children
        getServerMonitoring(serverNode, p_Resources);
        getLogging(serverNode, p_Resources, p_Request);
        getProtocols(serverNode, p_Resources, p_Request);
        getServices(serverNode, p_Resources, p_Request, p_DomainName, sServerName);
        getDeployments(serverNode, p_Resources, p_Request);
        getResources(serverNode, p_Resources, p_Request);
        getSecurity(serverNode, p_Resources, p_Request);
        // Add node for MQ connector support
        getJonasMqConnectorPlatform(serverNode, sServerName, p_Resources, p_Request);
    }

    /**
     * Append nodes for Monitoring.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *  messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServerMonitoring(TreeControlNode p_ServerNode, MessageResources p_Resources)
        throws Exception {
        // Monitoring server Service node
        TreeControlNode node = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "monitoring", "icon/monitoring.gif"
            , p_Resources.getMessage("treenode.jonas.server.monitoring"), "EditMonitoring.do"
            , "content", false);
        p_ServerNode.addChild(node);
    }

    /**
     * Append nodes for Logging.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getLogging(TreeControlNode p_ServerNode, MessageResources p_Resources
        , HttpServletRequest p_Request)
        throws Exception {
        // Logging server Service node
        TreeControlNode node = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "logging", "icon/loggers.gif"
            , p_Resources.getMessage("treenode.jonas.server.logging"), "ListLoggers.do", "content", false);
        p_ServerNode.addChild(node);
        // Add all loggers
        getLoggers(node, p_Resources, p_Request);
    }

    /**
     * Append nodes for each logger.
     *
     * @param p_LoggingNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getLoggers(TreeControlNode p_LoggingNode, MessageResources p_Resources
        , HttpServletRequest p_Request)
        throws Exception {
        // Get WhereAreYou instance in session
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);
        // Get list of loggers with Action name
        ArrayList al = JonasAdminJmx.getLoggers(p_Resources, oWhere, true);
        // Build the node of each logger
        LoggerItem oLog;
        String sIcon = "icon/loggers.gif";
        String rootNodeName = p_LoggingNode.getName();
        String nodeName;
        for (int i = 0; i < al.size(); i++) {
            oLog = (LoggerItem) al.get(i);
            if (LoggerItem.LOGGER_JONAS.equals(oLog.getType())) {
                sIcon = "icon/logger_jonas.gif";
                nodeName = rootNodeName +  WhereAreYou.NODE_SEPARATOR + LoggerItem.LOGGER_JONAS;
            } else /*if (LoggerItem.LOGGER_CATALINA_ACCESS.equals(oLog.getType()) == true)*/ {
                sIcon = "icon/logger_http.gif";
                nodeName = rootNodeName
                    + WhereAreYou.NODE_SEPARATOR
                    + oLog.getType()
                    + WhereAreYou.NODE_SEPARATOR
                    + oLog.getContainerName();
            }
            // Add a logger node
            TreeControlNode node = new TreeControlNode(nodeName, sIcon
                , oLog.getName()
                , oLog.getForward()
                , "content", false);
            p_LoggingNode.addChild(node);
        }
    }

    /**
     * Append nodes for all defined services for the specified server.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServices(TreeControlNode p_ServerNode, MessageResources p_Resources
            , HttpServletRequest p_Request, String p_DomainName, String p_ServerName)
        throws Exception {
        // Services node
        TreeControlNode nodeAllServices = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "services", "icon/services.gif"
            , p_Resources.getMessage("treenode.jonas.server.services"), "ListServices.do"
            , "content", false);
        p_ServerNode.addChild(nodeAllServices);
        String serverName = p_ServerName;
        // Detail Service node
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.earService(), serverName)) {
            getServiceApp(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.ejbService(), serverName)) {
            getServiceEjbContainer(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.webContainerService(), serverName)) {
            getServiceWeb(nodeAllServices, p_Resources, p_Request, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.databaseService(), serverName)) {
            getServiceDatabase(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.resourceService(), serverName)) {
            getServiceResourceAdapter(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.transactionService(), serverName)) {
            getServiceTransaction(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.jmsService(), serverName)) {
            getServiceJms(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.mailService(), serverName)) {
            getServiceMail(nodeAllServices, p_Resources, p_Request, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.securityService(), serverName)) {
            getServiceSecurity(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.discoveryService(), serverName)) {
            getServiceDiscovery(nodeAllServices, p_Resources, p_DomainName, p_ServerName);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.wsService(), serverName)) {
            getServiceWebService(nodeAllServices, p_Resources, p_Request, p_DomainName, p_ServerName);
        }
    }

    /**
     * Append node for Ear service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceApp(TreeControlNode p_NodeServices, MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "ear", "icon/service_application.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.ear")
            , "ListAppContainers.do"
            , "content", false);
        p_NodeServices.addChild(nodeService);

        // Add App Containers nodes
        getAppContainers(nodeService, p_Resources, p_DomainName, p_ServerName);
    }

    /**
     * Append node for all App Containers.
     *
     * @param p_NodeParent Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getAppContainers(TreeControlNode p_NodeParent, MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        String sPath;
        String sFile;
        String sNodeName;
        String sName;
        ArrayList al = new ArrayList();
        String serverName = p_ServerName;
        // Get Container List
        ObjectName ons = J2eeObjectName.J2EEApplications(p_DomainName, p_ServerName);
        Iterator itNames = JonasManagementRepr.queryNames(ons, serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName it_on = (ObjectName) itNames.next();
            sPath = (String) JonasManagementRepr.getAttribute(it_on, "earUrl", serverName).toString();
            sFile = JonasAdminJmx.extractFilename(sPath);
            sNodeName = p_NodeParent.getName() + WhereAreYou.NODE_SEPARATOR + sFile;
            sName = it_on.getKeyProperty("name");
            if (sFile != null) {
                al.add(new ContainerItem(sFile, sPath, sNodeName, it_on.toString(), sName));
            }
        }
        // Sort list
        Collections.sort(al, new ContainerItemByFile());
        // Build nodes
        ContainerItem oItem;
        for (int i = 0; i < al.size(); i++) {
            oItem = (ContainerItem) al.get(i);
            TreeControlNode node = new TreeControlNode(oItem.getNodeName(), "icon/ear.gif"
                , oItem.getFile(), "EditEar.do?select=" + oItem.getObjectName(), "content", false);
            p_NodeParent.addChild(node);
        }
    }

    /**
     * Append node for EJBContainer service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *  messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceEjbContainer(TreeControlNode p_NodeServices
        , MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "ejbContainers", "icon/service_ejb.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.ejbContainers")
            , "ListContainers.do"
            , "content", false);
        p_NodeServices.addChild(nodeService);
        // Add Containers nodes
        getContainers(nodeService, p_Resources, p_DomainName, p_ServerName);
    }

    /**
     * Append node for all Containers.
     *
     * @param p_NodeParent Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getContainers(TreeControlNode p_NodeParent, MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        String sPath;
        String sFile;
        String sName;
        String sNodeName;
        ObjectName onContainer;
        ArrayList al = new ArrayList();

        // Get Container List
        Iterator itNames = JonasManagementRepr.queryNames(J2eeObjectName.getEJBModules(p_DomainName, p_ServerName), p_ServerName).iterator();
        while (itNames.hasNext()) {
            ObjectName it_on = (ObjectName) itNames.next();
            sPath = (String) JonasManagementRepr.getAttribute(it_on, "fileName", p_ServerName);
            sFile = JonasAdminJmx.extractFilename(sPath);
            sNodeName = p_NodeParent.getName() + WhereAreYou.NODE_SEPARATOR + sFile;
            sName = it_on.getKeyProperty("name");
            if (sFile != null) {
                al.add(new ContainerItem(sFile, sPath, sNodeName, it_on.toString(), sName));
            }
        }

        // Sort list
        Collections.sort(al, new ContainerItemByFile());
        // Build nodes
        ContainerItem oItem;
        for (int i = 0; i < al.size(); i++) {
            oItem = (ContainerItem) al.get(i);
            TreeControlNode node = new TreeControlNode(oItem.getNodeName(), "icon/jar.gif"
                , oItem.getFile(), "EditContainer.do?select=" + oItem.getObjectName(), "content", false);
            p_NodeParent.addChild(node);
            // Add ejb node
            getEjbs(node, p_Resources, oItem.getPath(), p_DomainName, p_ServerName, oItem.getName());
        }
    }

    /**
     * Append node for all Ejbs for a Container.
     *
     * @param p_NodeParent Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Filename Filename of container
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getEjbs(TreeControlNode p_NodeParent, MessageResources p_Resources
        , String p_Filename, String p_DomainName, String p_ServerName, String p_moduleName)
        throws Exception {
        //String sName;
        Iterator itNames;
        ObjectName on;
        ArrayList al = new ArrayList();

        on = J2eeObjectName.getEntityBeans(p_DomainName, p_moduleName, p_ServerName);

        itNames = JonasAdminJmx.getListMbean(on, p_ServerName).iterator();
        while (itNames.hasNext()) {
            al.add(new EjbItem((ObjectName) itNames.next(), p_ServerName));
        }
        on = J2eeObjectName.getStatefulSessionBeans(p_DomainName, p_moduleName, p_ServerName);
        itNames = JonasAdminJmx.getListMbean(on, p_ServerName).iterator();
        while (itNames.hasNext()) {
            al.add(new EjbItem((ObjectName) itNames.next(), p_ServerName));
        }
        on = J2eeObjectName.getStatelessSessionBeans(p_DomainName, p_moduleName, p_ServerName);
        itNames = JonasAdminJmx.getListMbean(on, p_ServerName).iterator();
        while (itNames.hasNext()) {
            al.add(new EjbItem((ObjectName) itNames.next(), p_ServerName));
        }
        on = J2eeObjectName.getMessageDrivenBeans(p_DomainName, p_moduleName, p_ServerName);
        itNames = JonasAdminJmx.getListMbean(on, p_ServerName).iterator();
        while (itNames.hasNext()) {
            al.add(new EjbItem((ObjectName) itNames.next(), p_ServerName));
        }

        // Sort by name
        Collections.sort(al, new EjbItemByNameComparator());

        // Add all node Ejb
        String sNodeName;
        String sAction;
        TreeControlNode nodeEjb;
        EjbItem oEjb;
        for (int i = 0; i < al.size(); i++) {
            oEjb = (EjbItem) al.get(i);
            sNodeName = p_NodeParent.getName() + WhereAreYou.NODE_SEPARATOR + oEjb.getName();
            sAction = "EditEjb" + oEjb.getTypeString() + ".do?select=" + oEjb.getObjectName();
            // Add node Ejb
            nodeEjb = new TreeControlNode(sNodeName, "icon/bean.gif", oEjb.getName(), sAction
                , "content", false);
            p_NodeParent.addChild(nodeEjb);
        }
    }

    /**
     * Append node for Database service for the JOnAS services.
     *
     * @param pNodeServices Services node for the tree control
     * @param pResources The MessageResources for our localized messages
     * @param pDomainName The name of the current management domain
     * @param pServerName The name of the currently managed JOnAS server
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceDatabase(TreeControlNode pNodeServices, MessageResources pResources, String pDomainName, String pServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(pNodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "database", "icon/service_database.gif"
            , pResources.getMessage("treenode.jonas.server.services.database"), "ListDatabases.do"
            , "content", false);
        pNodeServices.addChild(nodeService);
        // Add Datasources nodes
        getDatasources(nodeService, pResources, pDomainName, pServerName);
    }

    /**
     * Append node for all deployed Datasources.
     *
     * @param pNodeParent Server node for the tree control
     * @param pResources The MessageResources for our localized messages
     * @param pDomainName The name of the current management domain
     * @param pServerName The name of the currently managed JOnAS server
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getDatasources(TreeControlNode pNodeParent, MessageResources pResources, String pDomainName, String pServerName)
        throws Exception {

        ArrayList al = JonasAdminJmx.getDatasourceFilesDeployed(pDomainName, pServerName);
        // Build nodes
        for (int i = 0; i < al.size(); i++) {
            TreeControlNode node = new TreeControlNode(pNodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + al.get(i).toString(), "icon/Datasource.gif"
                , al.get(i).toString(), "EditDatasource.do?name=" + al.get(i), "content", false);
            pNodeParent.addChild(node);
        }
    }

    /**
     * Append node for Web service for the JOnAS services.
     *
     * @param pNodeServices Services node for the tree control
     * @param pResources The MessageResources for our localized messages
     * @param pRequest The servlet request we are processing
     * @param pDomainName The name of the current management domain
     * @param pServerName The name of the currently managed JOnAS server
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceWeb(TreeControlNode pNodeServices, MessageResources pResources
        , HttpServletRequest pRequest, String pDomainName, String pServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(pNodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "web", "icon/service_web.gif"
            , pResources.getMessage("treenode.jonas.server.services.web"), "ListWebContainers.do"
            , "content", false);
        pNodeServices.addChild(nodeService);
        // Add Web Containers nodes
        getWebContainers(nodeService, pResources, pRequest);
    }

    /**
     * Append node for all Web Containers.
     *
     * @param p_NodeParent Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getWebContainers(TreeControlNode p_NodeParent, MessageResources p_Resources
        , HttpServletRequest p_Request)
        throws Exception {
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        String domainName = oWhere.getCurrentDomainName();
        ArrayList al = new ArrayList();
        // Detect Catalina items present
        if (oWhere.isCatalinaServer()) {
            // Get the list of WebModule
            Iterator itOns = JonasAdminJmx.getListMbean(J2eeObjectName.getWebModules(oWhere.
                getCurrentCatalinaDomainName()), serverName).iterator();
            while (itOns.hasNext()) {
                al.add(new WebAppItem((ObjectName) itOns.next(), oWhere.getCurrentCatalinaDefaultHostName()));
            }
        }
        // Detect Jetty items present
        else if (oWhere.isJettyServer()) {
            ObjectName on;
            String sPathContext;
            HashMap hWebAppItems = new HashMap();

            // Get the list of Jetty contexts
            Iterator itOnContexts = JonasAdminJmx.getListMbean(JettyObjectName.jettyContexts(domainName), serverName).
                iterator();
            while (itOnContexts.hasNext()) {
                on = (ObjectName) itOnContexts.next();
                sPathContext = on.getKeyProperty("context");
                if (sPathContext != null) {
                    if (!hWebAppItems.containsKey(sPathContext) && on.getKeyProperty("WebApplicationContext") != null &&
                            on.getKeyProperty("WebApplicationHandler") == null && on.getKeyProperty("config") == null) {
                        hWebAppItems.put(sPathContext, new WebAppItem(sPathContext, on.toString()));
                    }
                }
            }
            // Prepare to display
            al.addAll(hWebAppItems.values());
        }
        // Sort list
        Collections.sort(al, new WebAppItemByPathContext());
        // Build nodes
        WebAppItem oItem;
        for (int i = 0; i < al.size(); i++) {
            oItem = (WebAppItem) al.get(i);
            TreeControlNode node = new TreeControlNode(p_NodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + oItem.getObjectName(), "icon/war.gif"
                , oItem.getLabelPathContext(), "EditWebApp.do?on=" + oItem.getObjectName()
                , "content", false);
            p_NodeParent.addChild(node);
        }
    }

    /**
     * Append node for Transaction service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *  messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceTransaction(TreeControlNode p_NodeServices
        , MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "transaction", "icon/service_transaction.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.transaction")
            , "EditJtmService.do", "content", false);
        p_NodeServices.addChild(nodeService);
    }

    /**
     * Append node for discovery service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *  messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceDiscovery(TreeControlNode p_NodeServices, MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "discovery", "icon/service_transaction.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.discovery")
            , "EditServiceDiscovery.do", "content", false);
        p_NodeServices.addChild(nodeService);
    }

    /**
     * Append node for WebService (ws) service for the JOnAS services.
     *
     * @param p_NodeServices
     *            Services node for the tree control
     * @param p_Resources
     *            The MessageResources for our localized messages
     * @param request
     *            The HTTP request object currently in use.
     * @param p_DomainName
     *            The domain name for the instance
     * @param p_ServerName
     *            The server name for the instance being monitored
     * @exception Exception
     *                if an exception occurs building the tree
     */
     public void getServiceWebService(TreeControlNode p_NodeServices,
            MessageResources p_Resources, HttpServletRequest request, String p_DomainName,
            String p_ServerName) throws Exception {
        String nodeName = p_NodeServices.getName() + WhereAreYou.NODE_SEPARATOR + "WebService";
        TreeControlNode nodeService = null;
        // Rebuild the webservice tree.
        nodeService = p_NodeServices.getTree().findNode(nodeName);
        if (nodeService != null) {
            nodeService.remove();
        }
            // (Re)Add Web Service node
            nodeService = new TreeControlNode(
                    nodeName,
                    "icon/war.gif",
                    p_Resources
                            .getMessage("treenode.jonas.server.services.webservices"),
                    "ListWebService.do", "content", false);
            p_NodeServices.addChild(nodeService);
            getWebServiceDetails(nodeService, p_Resources, request);

    }
    /**
     * Append Web Service names for web services node in tree.
     *
     * @param p_WebServicesNode
     *            Web Services node for the tree control
     * @param p_Resources
     *            The MessageResources for our localized messages
     * @param p_Request
     *            The servlet request we are processing
     * @exception Exception
     *                if an exception occurs building the tree
     */
    public void getWebServiceDetails(TreeControlNode p_webServicesNode,
            MessageResources p_Resources, HttpServletRequest p_Request)
            throws Exception {
        // Get WhereAreYou
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(
                WhereAreYou.SESSION_NAME);

        // Get the server name
        String sServerName = oWhere.getCurrentJonasServerName();
        // Get the list of webservice descriptions from mbean server.
        Collection al = new ArrayList();
        GenericDomainCapableProvider jProvider = new JonasProvider();
        jProvider.initialize(sServerName, null);
        al = jProvider.getWebServiceDescription();

        // Build the nodes
        TreeControlNode node;
        WebServiceDescription oWebServiceDescription = null;
        String sLabel;
        Iterator it = al.iterator();
        while (it.hasNext()) {
            oWebServiceDescription = (WebServiceDescription) it.next();
            node = new TreeControlNode(p_webServicesNode.getName()
                    + WhereAreYou.NODE_SEPARATOR
                    + oWebServiceDescription.getId(), "icon/war.gif",
                    oWebServiceDescription.getId(),
                    "WebServiceDetails.do?select="
                            + oWebServiceDescription.getId(), "content", false);
            p_webServicesNode.addChild(node);
            getPortComponents(oWebServiceDescription, node, p_Resources);
        }
    }

    /**
     * Append port component names for a web service node in tree.
     *
     * @param wsd
     *            Web Service Description for current web service.
     * @param p_WebServicesNode
     *            Connector node for the tree control
     * @param p_Resources
     *            The MessageResources for our localized messages
     * @exception Exception
     *                if an exception occurs building the tree
     */
    private void getPortComponents(WebServiceDescription wsd,
            TreeControlNode p_webServiceNode, MessageResources p_Resources)
            throws Exception {

        String sLabel;
        // Build the nodes
        TreeControlNode node = null;
        for (int i = 0; i < wsd.getPortComponentCount(); i++) {
            PortComponent pc = wsd.getPortComponent(i);
            node = new TreeControlNode(p_webServiceNode.getName()
                    + WhereAreYou.NODE_SEPARATOR + pc.getId(), "icon/war.gif",
                    pc.getId(), "PortComponentsDetails.do?pcselect="
                            + pc.getId() + "&wsdselect=" + wsd.getId(),
                    "content", false);
            p_webServiceNode.addChild(node);
            getPortComponentHandler(wsd, pc, node, p_Resources);
        }

    }

    /**
     * Append handler names for port component node in tree.
     *
     * @param wsd
     *            Web Service Description for current web service.
     * @param pc
     *            Port Component for current web service.
     * @param p_portComponentNode
     *            Port component node for the tree control
     * @param p_Resources
     *            The MessageResources for our localized messages
     */
    private void getPortComponentHandler(WebServiceDescription wsd,
            PortComponent pc, TreeControlNode p_portComponentNode,
            MessageResources p_Resources) throws Exception {
        // Build the nodes
        TreeControlNode node = null;
        for (int i = 0; i < pc.getHandlerCount(); i++) {
            Handler handler = pc.getHandler(i);
            node = new TreeControlNode(
                    p_portComponentNode.getName() + WhereAreYou.NODE_SEPARATOR
                            + handler.getId(),
                    "icon/war.gif",
                    handler.getId(),
                    "HandlersDetails.do?pcselect=" + pc.getId() + "&wsdselect="
                            + wsd.getId() + "&handlerselect=" + handler.getId(),
                    "content", false);
            p_portComponentNode.addChild(node);
        }

    }

    /**
     * Append node for Jms service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceJms(TreeControlNode p_NodeServices, MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "jms", "icon/service_jms.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.jms"), "EditJmsService.do"
            , "content", false);
        p_NodeServices.addChild(nodeService);
        // Add JMS administred objects (resources)
        getJmsResources(nodeService, p_Resources, p_ServerName);
    }

    /**
     * Append 3 subnodes for the JMS resource types + subnodes for all the ressources
     *
     * @param p_NodeParent JMS service node
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getJmsResources(TreeControlNode p_NodeParent, MessageResources p_Resources, String p_ServerName)
        throws Exception {
        // Add node for Connection Factories
        TreeControlNode node = new TreeControlNode(p_NodeParent.getName()
            + WhereAreYou.NODE_SEPARATOR + "cf", "icon/jms_connector.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.jms.cf")
            , "ListConnectionFactories.do", "content", false);
        p_NodeParent.addChild(node);
        getJmsConnectionFactories(node, p_Resources, p_ServerName);

        // Add node for Queues
        node = new TreeControlNode(p_NodeParent.getName() + WhereAreYou.NODE_SEPARATOR + "queue"
            , "icon/jms_queue.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.jms.queues"), "ListQueues.do"
            , "content", false);
        p_NodeParent.addChild(node);
        getJmsQueues(node, p_Resources, p_ServerName);

        // Add node for Topics
        node = new TreeControlNode(p_NodeParent.getName() + WhereAreYou.NODE_SEPARATOR + "topic"
            , "icon/jms_topic.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.jms.topics"), "ListTopics.do"
            , "content", false);
        p_NodeParent.addChild(node);
        getJmsTopics(node, p_Resources, p_ServerName);
    }

    /**
     * Append subnodes for ConnectionFactory resources
     *
     * @param p_NodeParent CFs subnode
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getJmsConnectionFactories(TreeControlNode p_NodeParent
        , MessageResources p_Resources, String p_ServerName)
        throws Exception {
        // Get the 3 connection factories created by default:
        // - default ConnectionFactory , default Topic ConnectionFactory, default Queue ConnectionFactory,
        // This corresponds to the current implementation of the JMS service ..... ???
        int nbConnFacts = 3;
        String cfNames[] = new String[3];
        ObjectName jmsServMB = JonasObjectName.jmsService();
        cfNames[0] = (String) JonasManagementRepr.getAttribute(jmsServMB
            , "DefaultConnectionFactoryName", p_ServerName);
        cfNames[1] = (String) JonasManagementRepr.getAttribute(jmsServMB
            , "DefaultTopicConnectionFactoryName", p_ServerName);
        cfNames[2] = (String) JonasManagementRepr.getAttribute(jmsServMB
            , "DefaultQueueConnectionFactoryName", p_ServerName);
        TreeControlNode node;
        for (int i = 0; i < nbConnFacts; i++) {
            node = new TreeControlNode(p_NodeParent.getName() + WhereAreYou.NODE_SEPARATOR
                + cfNames[i], "icon/jms_connector.gif", cfNames[i]
                , "PresentConnectionFactory.do?name=" + cfNames[i], "content", false);
            p_NodeParent.addChild(node);
        }
    }

    /**
     * Append subnodes node for Queue destinations
     *
     * @param p_NodeParent Queue subnode
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getJmsQueues(TreeControlNode p_NodeParent, MessageResources p_Resources, String p_ServerName)
        throws Exception {
        // Get queues list
        Iterator itNames = ((java.util.Set) JonasManagementRepr.getAttribute(JonasObjectName.
            jmsService(), "AllJmsQueueDestinationNames", p_ServerName)).iterator();
        while (itNames.hasNext()) {
            String sNodeName = (String) itNames.next();
            String sQueueName = sNodeName;
            // Add node for each queue
            TreeControlNode node = new TreeControlNode(p_NodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + sNodeName, "icon/jms_queue.gif", sQueueName
                , "PresentQueue.do?name=" + sQueueName, "content", false);
            p_NodeParent.addChild(node);
        }
    }

    /**
     * Append subnodes node for Topic destinations
     *
     * @param p_NodeParent Topic subnode
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getJmsTopics(TreeControlNode p_NodeParent, MessageResources p_Resources, String p_ServerName)
        throws Exception {
        // Get topics list
        Iterator itNames = ((java.util.Set) JonasManagementRepr.getAttribute(JonasObjectName.
            jmsService(), "AllJmsTopicDestinationNames", p_ServerName)).iterator();
        while (itNames.hasNext()) {
            String sNodeName = (String) itNames.next();
            String sTopicName = sNodeName;
            // Add node for each topic
            TreeControlNode node = new TreeControlNode(p_NodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + sNodeName, "icon/jms_topic.gif", sTopicName
                , "PresentTopic.do?name=" + sTopicName, "content", false);
            p_NodeParent.addChild(node);
        }
    }

    /**
     * Append node for Mail service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *  messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceMail(TreeControlNode p_NodeServices, MessageResources p_Resources
        , HttpServletRequest p_Request, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "mail", "icon/service_mail.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.mail"), "EditMailService.do"
            , "content", false);
        p_NodeServices.addChild(nodeService);
        // Add nodes for MailFactories
        getAllSessionMailFactories(nodeService, p_Resources, p_Request);
        getAllMimePartDSMailFactories(nodeService, p_Resources, p_Request);
    }

    public void getAllSessionMailFactories(TreeControlNode p_NodeParent
        , MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {
        // Add parent node for all the Session Mail Factories
        TreeControlNode nodeSessionMailFactories = new TreeControlNode(p_NodeParent.getName()
            + WhereAreYou.NODE_SEPARATOR + "session", "icon/mail_session.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.mail.session")
            , "ListSessionMailFactories.do", "content", false);
        p_NodeParent.addChild(nodeSessionMailFactories);
        // Add a node for each Session Mail Factory
        getSessionMailFactories(nodeSessionMailFactories, p_Resources, p_Request);
    }

    public void getAllMimePartDSMailFactories(TreeControlNode p_NodeParent
        , MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {
        // Add parent node for all the Session Mail Factories
        TreeControlNode nodeMimePartMailFactories = new TreeControlNode(p_NodeParent.getName()
            + WhereAreYou.NODE_SEPARATOR + "mimepart", "icon/mail_mime.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.mail.mimepart")
            , "ListMimePartMailFactories.do", "content", false);
        p_NodeParent.addChild(nodeMimePartMailFactories);
        // Add a node for each Session Mail Factory
        getMimePartMailFactories(nodeMimePartMailFactories, p_Resources, p_Request);
    }

    protected void getSessionMailFactories(TreeControlNode p_NodeParent
        , MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {
        String sPath;
        String sFile;
        String sNodeName;
        ArrayList al = new ArrayList();

        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);

        // Get List
        java.util.List deployedFactories = (java.util.List) JonasAdminJmx.
            getSessionMailFactoriesDeployed(oWhere);
        Iterator itNames = deployedFactories.iterator();
        //Iterator itNames = ((java.util.List) JonasAdminJmx.getSessionMailFactoriesDeployed(oWhere)).iterator();
        while (itNames.hasNext()) {
            al.add(itNames.next().toString());
        }
        // Sort list
        Collections.sort(al);
        // Build nodes
        for (int i = 0; i < al.size(); i++) {
            TreeControlNode node = new TreeControlNode(p_NodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + al.get(i).toString(), "icon/mail_session.gif"
                , al.get(i).toString(), "EditSessionMailFactory.do?name=" + al.get(i).toString()
                , "content", false);
            p_NodeParent.addChild(node);
        }
    }

    protected void getMimePartMailFactories(TreeControlNode p_NodeParent
        , MessageResources p_Resource, HttpServletRequest p_Request)
        throws Exception {
        String sPath;
        String sFile;
        String sNodeName;
        ArrayList al = new ArrayList();

        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);

        // Get List
        Iterator itNames = ((java.util.List) JonasAdminJmx.getMimeMailPartFactoriesDeployed(oWhere)).
            iterator();
        while (itNames.hasNext()) {
            al.add(itNames.next().toString());
        }
        // Sort list
        Collections.sort(al);
        // Build nodes
        for (int i = 0; i < al.size(); i++) {
            TreeControlNode node = new TreeControlNode(p_NodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + al.get(i).toString(), "icon/mail_mime.gif"
                , al.get(i).toString(), "EditMimePartMailFactory.do?name=" + al.get(i).toString()
                , "content", false);
            p_NodeParent.addChild(node);
        }
    }

    /**
     * Append node for Resource service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceResourceAdapter(TreeControlNode p_NodeServices
        , MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "resourceAdapter", "icon/service_resource.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.resource")
            , "ListResourceAdapters.do", "content", false);
        p_NodeServices.addChild(nodeService);
        // Add Containers nodes
        getResourceAdapters(nodeService, p_Resources, p_DomainName, p_ServerName);
    }

    /**
     * Append node for all Resource Adapters.
     *
     * @param p_NodeParent Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param pDomainName The name of the current management domain
     * @param pServerName The name of the currently managed JOnAS server
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getResourceAdapters(TreeControlNode p_NodeParent, MessageResources p_Resources,
            String p_DomainName, String p_ServerName)
        throws Exception {
        String sPath;
        String sFile;
        String sNodeName;
        String sName;
        ObjectName on;
        ArrayList al = new ArrayList();

        // Get Resource Adapters
        ObjectName ons = J2eeObjectName.getResourceAdapters(p_DomainName, p_ServerName);
        Iterator itNames = JonasManagementRepr.queryNames(ons, p_ServerName).iterator();
        while (itNames.hasNext()) {
            ObjectName it_on = (ObjectName) itNames.next();
            sPath = (String) JonasManagementRepr.getAttribute(it_on, "fileName", p_ServerName);
            sFile = JonasAdminJmx.extractFilename(sPath);
            sNodeName = p_NodeParent.getName() + WhereAreYou.NODE_SEPARATOR + sFile;
            sName = it_on.getKeyProperty("name");
            if (sFile != null) {
                al.add(new ResourceItem(sFile, sPath, sNodeName, it_on.toString(), sName));
            }
        }
        // Sort list
        Collections.sort(al, new ResourceItemByFile());
        // Build nodes
        ResourceItem oItem;
        for (int i = 0; i < al.size(); i++) {
            oItem = (ResourceItem) al.get(i);
            TreeControlNode node = new TreeControlNode(oItem.getNodeName(), "icon/ear.gif"
                , oItem.getFile(), "EditResourceAdapter.do?select=" + oItem.getObjectName(), "content", false);
            p_NodeParent.addChild(node);
        }
/*
        // Get Container List
        ObjectName ons = J2eeObjectName.getResourceAdapterModules(p_DomainName, p_ServerName);
        Iterator itNames = JonasManagementRepr.queryNames(ons).iterator();
        while (itNames.hasNext()) {
            on = (ObjectName) itNames.next();
            al.add(on.getKeyProperty("name"));
        }
        // Sort list
        Collections.sort(al);
        // Build nodes
        for (int i = 0; i < al.size(); i++) {
            sName = al.get(i).toString();
            TreeControlNode node = new TreeControlNode(p_NodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + sName, "icon/resourceAdapter.gif"
                , JonasAdminJmx.extractFilename(sName)
                , "EditResourceAdapter.do?name=" + sName, "content", false);
            p_NodeParent.addChild(node);
        }
*/
    }

    /**
     * Append node for Security service for the JOnAS services.
     *
     * @param p_NodeServices Services node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *  messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getServiceSecurity(TreeControlNode p_NodeServices, MessageResources p_Resources, String p_DomainName, String p_ServerName)
        throws Exception {
        // Add Service node
        TreeControlNode nodeService = new TreeControlNode(p_NodeServices.getName()
            + WhereAreYou.NODE_SEPARATOR + "security", "icon/service_security.gif"
            , p_Resources.getMessage("treenode.jonas.server.services.security")
            , "EditServiceSecurity.do", "content", false);
        p_NodeServices.addChild(nodeService);
    }

    /**
     * Append nodes for Deployments services for the specified server.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDeployments(TreeControlNode p_ServerNode, MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {
        // Deployments node
        TreeControlNode nodeDeployments = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "deployments", "icon/deploy.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments"), null, "content", false);
        p_ServerNode.addChild(nodeDeployments);
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
                SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        // Detail Service node
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.earService(), serverName)) {
            getDeploymentEar(nodeDeployments, p_Resources);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.ejbService(), serverName)) {
            getDeploymentEjb(nodeDeployments, p_Resources);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.webContainerService(), serverName)) {
            getDeploymentWebAppli(nodeDeployments, p_Resources);
        }
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.resourceService(), serverName)) {
            getDeploymentRar(nodeDeployments, p_Resources);
        }
    }

    /**
     * Append node for Ear deployment.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDeploymentEar(TreeControlNode p_NodeDeployments, MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DEPLOYMENT_STRING_EAR, "icon/deploy_ear.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DEPLOYMENT_STRING_EAR)
            , "EditDeploy.do?type=" + WhereAreYou.DEPLOYMENT_STRING_EAR, "content", false);
        p_NodeDeployments.addChild(oNode);
    }

    /**
     * Append node for Ejb deployment.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDeploymentEjb(TreeControlNode p_NodeDeployments, MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DEPLOYMENT_STRING_JAR, "icon/deploy_jar.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DEPLOYMENT_STRING_JAR)
            , "EditDeploy.do?type=" + WhereAreYou.DEPLOYMENT_STRING_JAR, "content", false);
        p_NodeDeployments.addChild(oNode);

        // Add list files
        //getDeploymentJarFiles(oNode, p_Resources);
    }

    /**
     * Append node for Ejb Files deployment.
     *
     * @param p_NodeParent Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     *//*
    protected void getDeploymentEjbFiles(TreeControlNode p_NodeParent, MessageResources p_Resources)
        throws Exception {
        String sFile;
        Iterator it = JonasAdminJmx.getJarFilesDeployable().iterator();
        while (it.hasNext()) {
            sFile = it.next().toString();
            // Add node
            TreeControlNode oNode = new TreeControlNode(p_NodeParent.getName()
                + WhereAreYou.NODE_SEPARATOR + sFile, "icon/JonasQuestion.gif", sFile, null
                , "content", false);
            p_NodeParent.addChild(oNode);
        }

    }
*/
    /**
     * Append node for Web deployment.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDeploymentWebAppli(TreeControlNode p_NodeDeployments
        , MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DEPLOYMENT_STRING_WAR, "icon/deploy_war.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DEPLOYMENT_STRING_WAR)
            , "EditDeploy.do?type=" + WhereAreYou.DEPLOYMENT_STRING_WAR, "content", false);
        p_NodeDeployments.addChild(oNode);
    }

    /**
     * Append node for Rar deployment.
     *
     * @param p_NodeDeployments Deployment node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getDeploymentRar(TreeControlNode p_NodeDeployments, MessageResources p_Resources)
        throws Exception {
        // Add node
        TreeControlNode oNode = new TreeControlNode(p_NodeDeployments.getName()
            + WhereAreYou.NODE_SEPARATOR + WhereAreYou.DEPLOYMENT_STRING_RAR, "icon/deploy_rar.gif"
            , p_Resources.getMessage("treenode.jonas.server.deployments."
            + WhereAreYou.DEPLOYMENT_STRING_RAR)
            , "EditDeploy.do?type=" + WhereAreYou.DEPLOYMENT_STRING_RAR, "content", false);
        p_NodeDeployments.addChild(oNode);
    }

    /**
     * Append nodes for Resources services for the specified server.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @exception Exception if an exception occurs building the tree
     */
    protected void getResources(TreeControlNode p_ServerNode, MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {
        // Resources node
        TreeControlNode nodeDeployments = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "resources", "icon/resources.gif"
            , p_Resources.getMessage("treenode.jonas.server.resources"), null, "content", false);
        p_ServerNode.addChild(nodeDeployments);

        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        // Detail Service node
        // - database resources
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.databaseService(), serverName)) {
            getResourceDatabase(nodeDeployments, p_Resources);
        }
        // - jms resources
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.jmsService(), serverName)) {
            getJmsResource(nodeDeployments, p_Resources);
        }
        // - mail resources
        if (JonasAdminJmx.hasMBeanName(JonasObjectName.mailService(), serverName)) {
            getMailResource(nodeDeployments, p_Resources);
        }
    }

    /**
     * Append nodes for Mail Resources for the specified server.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @exception Exception if an exception occurs building the tree
     */
    protected void getMailResource(TreeControlNode p_ServerNode, MessageResources p_Resources)
        throws Exception {
        // Mail resources node
        TreeControlNode nodeDeployments = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "mail", "icon/mail.gif"
            , p_Resources.getMessage("treenode.jonas.server.resources.mail")
            , "EditDeploy.do?type=" + WhereAreYou.DEPLOYMENT_STRING_MAILFACTORY, "content", false);
        p_ServerNode.addChild(nodeDeployments);
    }

    /**
     * Append nodes for Jms Resource for the specified server.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @exception Exception if an exception occurs building the tree
     */
    protected void getJmsResource(TreeControlNode p_ServerNode, MessageResources p_Resources)
        throws Exception {
        // Jms resources node
        TreeControlNode nodeDeployments = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "jms", "icon/jms.gif"
            , p_Resources.getMessage("treenode.jonas.server.resources.jms"), "ListJmsResources.do"
            , "content", false);
        p_ServerNode.addChild(nodeDeployments);
    }

    /**
     * Append nodes for Database Resource for the specified server.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @exception Exception if an exception occurs building the tree
     */
    protected void getResourceDatabase(TreeControlNode p_ServerNode, MessageResources p_Resources)
        throws Exception {
        // Database Resources node
        TreeControlNode nodeDeployments = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "database", "icon/Database.gif"
            , p_Resources.getMessage("treenode.jonas.server.resources.database")
            , "EditDeploy.do?type=" + WhereAreYou.DEPLOYMENT_STRING_DATASOURCE, "content", false);
        p_ServerNode.addChild(nodeDeployments);
    }

    /**
     * Append nodes for Security for the specified server.
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     * @exception Exception if an exception occurs building the tree
     */
    protected void getSecurity(TreeControlNode p_ServerNode, MessageResources p_Resources
        , HttpServletRequest p_Request)
        throws Exception {

        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        // Detect JOnAS item presents
        boolean bJonasSecurityService = JonasAdminJmx.hasMBeanName(JonasObjectName.securityService(), serverName);
        // Detect Catalina items present
        boolean bCatalinaRealm = false;
        if (oWhere.isCatalinaServer()) {
            bCatalinaRealm = JonasAdminJmx.hasMBeanName(CatalinaObjectName.catalinaRealm(oWhere.
                getCurrentCatalinaServiceName()), serverName);
        }
        // Add nodes
        if ((bJonasSecurityService) || (bCatalinaRealm)) {
            // Active action
            String sAction = null;
            if (bJonasSecurityService) {
                sAction = "ListRealms.do?realm=all";
            }
            else if (bCatalinaRealm) {
                sAction = "EditSecurityCatalinaRealm.do";
            }
            // Security node
            TreeControlNode nodeSecurity = new TreeControlNode(p_ServerNode.getName()
                + WhereAreYou.NODE_SEPARATOR + "security", "icon/security.gif"
                , p_Resources.getMessage("treenode.jonas.server.security"), sAction, "content", false);
            p_ServerNode.addChild(nodeSecurity);
            // Detail Security node for JOnAS service
            if (bJonasSecurityService) {
                getSecurityFactories(nodeSecurity, p_Resources, p_Request);
            }
        }
    }

    /**
     * Append node for the Security catalina realm
     *
     * @param p_SecurityNode Catalina Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getSecurityCatalinaRealm(TreeControlNode p_SecurityNode
        , MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {

        // Add node
        TreeControlNode oNode = new TreeControlNode(p_SecurityNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "catalina.realm", "icon/security.gif"
            , p_Resources.getMessage("treenode.jonas.server.security.catalina.realm"), null
            , "content", false);
        p_SecurityNode.addChild(oNode);
    }

    /**
     * Append nodes for Security factories for the specified server.
     *
     * @param p_SecurityNode Security node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @exception Exception if an exception occurs building the tree
     */
    public void getSecurityFactories(TreeControlNode p_SecurityNode, MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {
        ArrayList al = null;
        String sName = null;
        TreeControlNode nodeSecurityFactories = null;
        TreeControlNode nodeSecurityFactory = null;
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
                SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        // Security Memory factories
        al = JonasAdminJmx.getSecurityMemoryFactories(serverName);
        if (al.size() > 0) {
            // Security factories node
            nodeSecurityFactories = new TreeControlNode(p_SecurityNode.getName()
                + WhereAreYou.NODE_SEPARATOR + "factory.memory", "icon/security_memory.gif"
                , p_Resources.getMessage("treenode.jonas.server.security.factory.memory")
                , "ListRealms.do?realm=memory", "content", false);
            p_SecurityNode.addChild(nodeSecurityFactories);
            // List Security factories
            for (int i = 0; i < al.size(); i++) {
                sName = al.get(i).toString();
                // Security factory node
                nodeSecurityFactory = new TreeControlNode(nodeSecurityFactories.getName()
                    + WhereAreYou.NODE_SEPARATOR + sName, "icon/security_memory.gif", sName
                    , "EditMemoryRealm.do?resource=" + sName, "content", false);
                nodeSecurityFactories.addChild(nodeSecurityFactory);
                // Add detail to memory security node
                //getSecurityMemoryFactory(nodeSecurityFactory, p_Resources, sName);
            }
        }
        // Security Datasource factories
        al = JonasAdminJmx.getSecurityDatasourceFactories(serverName);
        if (al.size() > 0) {
            // Security factories node
            nodeSecurityFactories = new TreeControlNode(p_SecurityNode.getName()
                + WhereAreYou.NODE_SEPARATOR + "factory.datasource", "icon/security_database.gif"
                , p_Resources.getMessage("treenode.jonas.server.security.factory.datasource")
                , "ListRealms.do?realm=datasource", "content", false);
            p_SecurityNode.addChild(nodeSecurityFactories);
            // List Security factories
            for (int i = 0; i < al.size(); i++) {
                sName = al.get(i).toString();
                // Security factory node
                nodeSecurityFactory = new TreeControlNode(nodeSecurityFactories.getName()
                    + WhereAreYou.NODE_SEPARATOR + sName, "icon/security_database.gif", sName
                    , "EditDatasourceRealm.do?resource=" + sName, "content", false);
                nodeSecurityFactories.addChild(nodeSecurityFactory);
            }
        }
        // Security Ldap factories
        al = JonasAdminJmx.getSecurityLdapFactories(serverName);
        if (al.size() > 0) {
            // Security factories node
            nodeSecurityFactories = new TreeControlNode(p_SecurityNode.getName()
                + WhereAreYou.NODE_SEPARATOR + "factory.ldap", "icon/security_ldap.gif"
                , p_Resources.getMessage("treenode.jonas.server.security.factory.ldap")
                , "ListRealms.do?realm=ldap", "content", false);
            p_SecurityNode.addChild(nodeSecurityFactories);
            // List Security factories
            for (int i = 0; i < al.size(); i++) {
                sName = al.get(i).toString();
                // Security factory node
                nodeSecurityFactory = new TreeControlNode(nodeSecurityFactories.getName()
                    + WhereAreYou.NODE_SEPARATOR + sName, "icon/security_ldap.gif", sName
                    , "EditLdapRealm.do?resource=" + sName, "content", false);
                nodeSecurityFactories.addChild(nodeSecurityFactory);
            }
        }
    }

    /**
     * Append nodes for Memory Security Factory for the specified server.
     *
     * @param p_SecurityMemoryNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_ResourceFactory The name of resource
     * @exception Exception if an exception occurs building the tree
     */
    protected void getSecurityMemoryFactory(TreeControlNode p_SecurityMemoryNode
        , MessageResources p_Resources, String p_ResourceFactory)
        throws Exception {
        TreeControlNode node = null;
        // Users node
        node = new TreeControlNode(p_SecurityMemoryNode.getName() + WhereAreYou.NODE_SEPARATOR
            + "users", "icon/security_memory.gif"
            , p_Resources.getMessage("treenode.jonas.server.security.factory.memory.users")
            , "EditMemoryRealmUsers.do?resource=" + p_ResourceFactory, "content", false);
        p_SecurityMemoryNode.addChild(node);
        // Groups node
        node = new TreeControlNode(p_SecurityMemoryNode.getName() + WhereAreYou.NODE_SEPARATOR
            + "groups", "icon/security_memory.gif"
            , p_Resources.getMessage("treenode.jonas.server.security.factory.memory.groups")
            , "EditMemoryRealmGroups.do?resource=" + p_ResourceFactory, "content", false);
        p_SecurityMemoryNode.addChild(node);
        // Roles node
        node = new TreeControlNode(p_SecurityMemoryNode.getName() + WhereAreYou.NODE_SEPARATOR
            + "roles", "icon/security_memory.gif"
            , p_Resources.getMessage("treenode.jonas.server.security.factory.memory.roles")
            , "EditMemoryRealmRoles.do?resource=" + p_ResourceFactory, "content", false);
        p_SecurityMemoryNode.addChild(node);
    }

    /**
     * Append nodes for the Servlet server
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getProtocols(TreeControlNode p_ServerNode, MessageResources p_Resources
        , HttpServletRequest p_Request)
        throws Exception {
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
                SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        // Catalina server
        if (JonasAdminJmx.hasMBeanName(CatalinaObjectName.catalinaServer(), serverName)) {
            getCatalinaProtocols(p_ServerNode, p_Resources, p_Request);
        }
    }

    /**
     * Append nodes for the Catalina server
     *
     * @param p_ServerNode Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getCatalinaProtocols(TreeControlNode p_ServerNode, MessageResources p_Resources
        , HttpServletRequest p_Request)
        throws Exception {
        // Add Catalina server node
        TreeControlNode catalinaNode = new TreeControlNode(p_ServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "protocols", "icon/protocol.gif"
            , p_Resources.getMessage("treenode.jonas.server.protocols")
            , "ListCatalinaConnectors.do", "content", false);
        p_ServerNode.addChild(catalinaNode);
        // Add Connectors nodes
        getCatalinaConnector(catalinaNode, p_Resources, p_Request);
    }

    /**
     * Append node for the Connector catalina server
     *
     * @param p_CatalinaServerNode Catalina Server node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    protected void getCatalinaConnector(TreeControlNode p_CatalinaServerNode
        , MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {

        // Add Connector node
        TreeControlNode connectorNode = new TreeControlNode(p_CatalinaServerNode.getName()
            + WhereAreYou.NODE_SEPARATOR + "connectors", "icon/connectors.gif"
            , p_Resources.getMessage("treenode.jonas.server.protocols.connectors")
            , "ListCatalinaConnectors.do", "content", false);
        p_CatalinaServerNode.addChild(connectorNode);

        getCatalinaDetailConnectors(connectorNode, p_Resources, p_Request);

    }

    /**
     * Append nodes for all the Connectors catalina server
     *
     * @param p_ConnectorNode Connector node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getCatalinaDetailConnectors(TreeControlNode p_ConnectorNode
        , MessageResources p_Resources, HttpServletRequest p_Request)
        throws Exception {

        // Get WhereAreYou
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
            SESSION_NAME);

        String serverName = oWhere.getCurrentJonasServerName();
        // Get the domain name
        String sDomain = oWhere.getCurrentCatalinaDomainName();
        // Get the list of connectors
        ArrayList al = new ArrayList();
        Iterator it = JonasAdminJmx.getListMBeanName(CatalinaObjectName.catalinaConnectors(sDomain),
                serverName).
            iterator();
        while (it.hasNext()) {
            al.add(new ConnectorItem(new ObjectName(it.next().toString())
                , oWhere.getApplicationServerPort(), serverName));
        }
        // Sort
        Collections.sort(al, new ConnectorItemByPort());
        // Build the nodes
        TreeControlNode node;
        ConnectorItem oConnector;
        String sLabel;
        for (int i = 0; i < al.size(); i++) {
            oConnector = (ConnectorItem) al.get(i);
            String nodeName = p_ConnectorNode.getName()
                + WhereAreYou.NODE_SEPARATOR
                + sDomain
                + WhereAreYou.NODE_SEPARATOR
                + oConnector.getPort();
            String address = oConnector.getAddress();
            if (address != null) {
                nodeName = nodeName + address;
            }
            node = new TreeControlNode(nodeName, "icon/connector.gif"
                , oConnector.getLabel()
                , "EditCatalinaConnector.do?select=" + oConnector.getObjectName(), "content", false);
            p_ConnectorNode.addChild(node);
        }
    }

    /**
     * Append node for JORAM platform management.
     *
     * @param pDomainNode Domain node for the tree control
     * @param jonasServerName the name of the JOnAS server to which the current JORAM server is connected
     * @param pResources  The MessageResources for our localized messages
     * @param p_Request The servlet request we are processing
     *
     * @exception Exception  If an exception occurs when building the tree.
     */
    public void getJoramPlatform(TreeControlNode pDomainNode, String jonasServerName,
                                    MessageResources pResources, HttpServletRequest p_Request)
        throws Exception {

        ObjectName joramPlatformON = JoramObjectName.joramPlatform();
        if (!JonasAdminJmx.hasMBeanName(joramPlatformON, jonasServerName)) {
            // No Joram to manage
            // reset localServerId in case we just switched management context
            // from a server which has Joram to this server which does not
            if (p_Request.getSession().getAttribute("localId") != null) {
                p_Request.getSession().setAttribute("localId", null);
            }
            return;
        }
        Set adapterOns = JonasManagementRepr.queryNames(JoramObjectName.joramAdapter(), jonasServerName);
        if (adapterOns.isEmpty()) {
            return;
        }
        ObjectName joramAdapterON = (ObjectName) adapterOns.iterator().next();

        // Joram platform present, create node for it
        TreeControlNode platformNode =
          new TreeControlNode(pDomainNode.getName()
                  + WhereAreYou.NODE_SEPARATOR
                  + "joramplatform",
                              "icon/service_jms.gif",
                              pResources.getMessage("treenode.joramplatform"),
                              "EditJoramPlatform.do",
                              "content",
                              false);

        // Create node for the local server (Joram server to which the admin client is connected)
        pDomainNode.addChild(platformNode);

        try {
            getJoramServers(platformNode, jonasServerName, joramPlatformON, pResources, p_Request);
        } catch (Exception e) {
            // TO DO
        }
    }

    /**
     * Append nodes for Joram server defined in tbe platform
     * @param platformNode     Joram platform node
     * @param jonasServerName the name of the JOnAS server to which the current JORAM server is connected
     * @param joramPlatformON  ObjectName of Joram Platform MBean
     * @param pResources The MessageResources for our localized messages
     * @param p_Request  The servlet request we are processing
     * @throws Exception If an exception occurs when building the tree.
     */
    public void getJoramServers(TreeControlNode platformNode
            , String jonasServerName
            , ObjectName joramPlatformON
            , MessageResources pResources
            , HttpServletRequest p_Request) throws Exception {

        if (joramPlatformON == null) {
            joramPlatformON = JoramObjectName.joramPlatform();
        }
        ObjectName joramAdapterON = (ObjectName) (JonasManagementRepr.queryNames(JoramObjectName.joramAdapter(), jonasServerName)).iterator().next();
        boolean collocatedServer = true;
        Object attributeValue = null;
        if (JonasManagementRepr.isRegistered(joramAdapterON, jonasServerName)) {
            attributeValue = JonasManagementRepr.getAttribute(joramAdapterON, "CollocatedServer", jonasServerName);
            if (attributeValue != null) {
                collocatedServer = ((Boolean) attributeValue).booleanValue();
            }
        }
        // get local Joram server
        String localId = null;
        attributeValue = JonasManagementRepr.getAttribute(joramPlatformON, "LocalServerId", jonasServerName);
        if (attributeValue != null) {
            Integer localIdInt = (Integer) attributeValue;
            localId = localIdInt.toString();
        }
        // Create the node for the currently managed JORAM server
        TreeControlNode currentServerNode = null;
        String nodeName = null;
        String icon = "icon/service_jms.gif";
        String label = null;
        String action = "EditJoramServer.do?id=" + localId;
        if (collocatedServer) {
            nodeName = platformNode.getName() + WhereAreYou.NODE_SEPARATOR + "joramlocalserver";
            label = pResources.getMessage("treenode.joramplatform.joramlocalserver") + " (" + localId + ")";
        } else {
            nodeName = platformNode.getName() + WhereAreYou.NODE_SEPARATOR + "joramcurrentserver";
            label = pResources.getMessage("treenode.joramplatform.joramcurrentserver") + " (" + localId + ")";
        }
        currentServerNode =  new TreeControlNode(nodeName, icon, label, action, "content", false);
        platformNode.addChild(currentServerNode);

        // Add local server's resources
        getJoramResources(currentServerNode, jonasServerName, localId, pResources, p_Request);

        p_Request.getSession().setAttribute("localId", localId);
        p_Request.getSession().setAttribute("collocatedServer", new Boolean(collocatedServer));

        // get the other (remote) Joram servers
        List list = (List) JonasManagementRepr.getAttribute(joramPlatformON, "ServersIds", jonasServerName);
        if (list != null) {
            Iterator it = list.iterator();
            Integer serverId;
            String id;
            TreeControlNode remoteServerNode = null;
            while (it.hasNext()) {
                serverId = (Integer) it.next();
                id = serverId.toString();
                String joramremoteserver = null;
                if (!id.equals(localId)) {
                    joramremoteserver = "joramremoteserver" + id;
                    nodeName = platformNode.getName() + WhereAreYou.NODE_SEPARATOR + joramremoteserver;
                    label = pResources.getMessage("treenode.joramplatform.joramremoteserver") + " (" + id + ")";
                    action = "EditJoramServer.do?id=" + id;
                    remoteServerNode = new TreeControlNode(nodeName, icon, label, action, "content", false);
                    platformNode.addChild(remoteServerNode);
                    // Add remote server's resources
                    getJoramResources(remoteServerNode, jonasServerName, id, pResources, p_Request);
                }
            }
        }
    }
    /**
     * Append nodes for Joram DEstinations created in a Joram server
     * @param joramServerNode     Joram server node
     * @param jonasServerName the name of the JOnAS server to which the current JORAM server is connected
     * @param serverId            Joram server id
     * @param pResources The MessageResources for our localized messages
     * @param p_Request  The servlet request we are processing
     * @throws Exception If an exception occurs when building the tree.
     */
    public void getJoramResources(TreeControlNode joramServerNode, String jonasServerName, String serverId,
            MessageResources pResources, HttpServletRequest p_Request) throws Exception {

        String joramServerNodeName = joramServerNode.getName();

        // Get all the destinations
        ObjectName joramAdminOn = JoramObjectName.joramAdmin();
        List destList = (List) JonasManagementRepr.getAttribute(joramAdminOn, "Destinations", jonasServerName);
        ArrayList destArray = new ArrayList();
        if (destList != null && !destList.isEmpty()) {
            Iterator it = destList.iterator();
            while (it.hasNext()) {
                ItemDestination destinationItem = getDestinationItem((String) it.next(), jonasServerName);
                if (destinationItem.getServerId().equals(serverId)) {
                    String destinationType = destinationItem.getType();
                    if ("queue".equals(destinationType) || "queue.dmq".equals(destinationType)) {
                        // insert in head
                        destArray.add(0, destinationItem);
                    } else if ("topic".equals(destinationType)) {
                        // append
                        destArray.add(destinationItem);
                    }
                }
            }
        }
        // Add sub-nodes for destinations belonging to the server
        for (int i = 0; i < destArray.size(); i++) {
            ItemDestination item = (ItemDestination) destArray.get(i);
            String name = item.getName();
            String type = item.getType();
            TreeControlNode destinationNode = null;
            String nodeName = null;
            String action = null;
            String icon = null;
            String label = null;
            if (type.equals("queue")) {
                nodeName = joramServerNodeName + WhereAreYou.NODE_SEPARATOR + "joramqueue" + name;
                icon = "icon/jms_queue.gif";
                label = pResources.getMessage("treenode.joramplatform.queue") + " (" + name + ")";
                action = "EditJoramQueue.do?name=" + name + "&id=" + serverId;
            } else if (type.equals("topic")) {
                nodeName = joramServerNodeName + WhereAreYou.NODE_SEPARATOR + "joramtopic" + name;
                icon = "icon/jms_topic.gif";
                label = pResources.getMessage("treenode.joramplatform.topic") + " (" + name + ")";
                action = "EditJoramTopic.do?name=" + name + "&id=" + serverId;
            } else if (type.equals("queue.dmq")) {
                nodeName = joramServerNodeName + WhereAreYou.NODE_SEPARATOR + "joramqueue" + name;
                icon = "icon/jms_queue.gif";
                label = pResources.getMessage("treenode.joramplatform.queue.dmq") + " (" + name + ")";
                action = "EditJoramQueue.do?name=" + name + "&id=" + serverId;
            }
            if (item.getOn() == null) {
                if (!item.isRegistered()) {
                    Object[] asParam = {
                            new Integer(serverId), name
                    };
                    String[] asSignature = {
                            "int", "java.lang.String"
                    };
                    if (type.equals("queue")) {
                        JonasManagementRepr.invoke(joramAdminOn, "createQueue", asParam, asSignature, jonasServerName);
                    } else if (type.equals("topic")) {
                        JonasManagementRepr.invoke(joramAdminOn, "createTopic", asParam, asSignature, jonasServerName);
                    }
                } else {
                    action = null;
                }
            }
            destinationNode = new TreeControlNode(nodeName, icon, label, action, "content", false);
            if (destinationNode != null) {
                joramServerNode.addChild(destinationNode);
            }
        }
    }

    /**
     * Append nodes for all defined MBeans.
     *
     * @param domainNode Root node for the tree control
     * @param resources The MessageResources for our localized messages
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getMBeans(TreeControlNode domainNode, MessageResources resources, HttpServletRequest p_Request)
        throws Exception {
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
                SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        TreeControlNode nodeMBeans = new TreeControlNode(domainNode.getName()
                + WhereAreYou.NODE_SEPARATOR
                + "mbeans"
                , "icon/mbeans.gif"
                , resources.getMessage("treenode.allmbeans")
                , "ListMBeans.do", "content", false);
        domainNode.addChild(nodeMBeans);

        ArrayList[] als = JonasAdminJmx.getFamiliesMbeansLists(serverName);
        if (als[MbeanItem.FAMILY_J2EE].size() > 0) {
            getJ2eeMBeans(nodeMBeans, resources, als[MbeanItem.FAMILY_J2EE]);
        }
        if (als[MbeanItem.FAMILY_OWNER].size() > 0) {
            getOwnerMBeans(nodeMBeans, resources, als[MbeanItem.FAMILY_OWNER]);
        }
        if (als[MbeanItem.FAMILY_UNKNOWN].size() > 0) {
            getUnknownMBeans(nodeMBeans, resources, als[MbeanItem.FAMILY_UNKNOWN]);
        }
    }

    /**
     * Append nodes for all defined Owner MBeans.
     *
     * @param p_ParentNode Parent node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_List The list of Mbeans
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getOwnerMBeans(TreeControlNode p_ParentNode, MessageResources p_Resources
        , ArrayList p_List)
        throws Exception {

        TreeControlNode nodeMBeans = new TreeControlNode(p_ParentNode.getName()
                + WhereAreYou.NODE_SEPARATOR
                + "owner"
                , "icon/mbeans.gif"
                , p_Resources.getMessage("treenode.mbeans.owner")
                , "ListOwnerMBeans.do", "content", false);
        p_ParentNode.addChild(nodeMBeans);
        // Sort list
        Collections.sort(p_List, new BeanComparator(new String[] {
            "domain", "type", "objectName"}));

        // Detail MBean node
        String sLastDomain = "";
        String sLastType = "";
        TreeControlNode nodeMBean = null;
        TreeControlNode nodeDomain = null;
        TreeControlNode nodeType = null;
        TreeControlNode nodeParent = null;
        OwnerMbeanItem oItem;

        Iterator it = p_List.iterator();
        while (it.hasNext()) {
            oItem = (OwnerMbeanItem) it.next();

            nodeParent = nodeMBeans;
            if (oItem.getDomain() != null) {
                // Domain node
                if (!oItem.getDomain().equals(sLastDomain)) {
                    sLastDomain = oItem.getDomain();
                    nodeDomain = new TreeControlNode(nodeParent.getName()
                        + WhereAreYou.NODE_SEPARATOR + oItem.getDomain(), "icon/mbeandomain.gif"
                        , oItem.getDomain(), null, "content", false);
                    nodeMBeans.addChild(nodeDomain);
                }
                nodeParent = nodeDomain;

                if (oItem.getType() != null) {
                    // Type node
                    if (!oItem.getType().equals(sLastType)) {
                        sLastType = oItem.getType();
                        nodeType = new TreeControlNode(nodeParent.getName()
                            + WhereAreYou.NODE_SEPARATOR + oItem.getType(), "icon/mbeantype.gif"
                            , oItem.getType(), null, "content", false);
                        nodeDomain.addChild(nodeType);
                    }
                    nodeParent = nodeType;
                }
            }

            // Mbean node
            nodeMBean = new TreeControlNode(p_ParentNode.getName()
                    + WhereAreYou.NODE_SEPARATOR
                    + oItem.getObjectName()
                    , "icon/mbean.gif"
                    , oItem.getObjectName()
                    , "ListMBeanDetails.do?select=" + URLEncoder.encode(oItem.getObjectName(), "UTF-8")
                    , "content", false);
            nodeParent.addChild(nodeMBean);

        }
    }

    /**
     * Append nodes for all defined J2EE MBeans.
     *
     * @param p_ParentNode Parent node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_List The list of Mbeans
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getJ2eeMBeans(TreeControlNode p_ParentNode, MessageResources p_Resources
        , ArrayList p_List)
        throws Exception {

        TreeControlNode nodeMBeans = new TreeControlNode(p_ParentNode.getName()
                + WhereAreYou.NODE_SEPARATOR
                + "j2ee"
                , "icon/mbeans.gif"
                , p_Resources.getMessage("treenode.mbeans.j2ee")
                , "ListJ2eeMBeans.do", "content", false);
        p_ParentNode.addChild(nodeMBeans);
        // Sort list
        Collections.sort(p_List, new BeanComparator(new String[] {
            "domain", "j2eeType", "name", "objectName"}));

        // Detail MBean node
        J2eeMbeanItem oItem;
        String sLastDomain = "";
        String sLastType = "";
        TreeControlNode nodeMBean = null;
        TreeControlNode nodeDomain = null;
        TreeControlNode nodeType = null;
        TreeControlNode nodeParent = null;

        Iterator it = p_List.iterator();
        while (it.hasNext()) {
            oItem = (J2eeMbeanItem) it.next();

            nodeParent = nodeMBeans;
            if (oItem.getDomain() != null) {
                // Domain node
                if (!oItem.getDomain().equals(sLastDomain)) {
                    sLastDomain = oItem.getDomain();
                    nodeDomain = new TreeControlNode(nodeParent.getName()
                        + WhereAreYou.NODE_SEPARATOR + oItem.getDomain(), "icon/mbeandomain.gif"
                        , oItem.getDomain(), null, "content", false);
                    nodeMBeans.addChild(nodeDomain);
                }
                nodeParent = nodeDomain;
            }
            if (oItem.getJ2eeType() != null) {
                // Type node
                if (!oItem.getJ2eeType().equals(sLastType)) {
                    sLastType = oItem.getJ2eeType();
                    nodeType = new TreeControlNode(nodeParent.getName()
                        + WhereAreYou.NODE_SEPARATOR + oItem.getJ2eeType(), "icon/mbeantype.gif"
                        , oItem.getJ2eeType(), null, "content", false);
                    nodeDomain.addChild(nodeType);
                }
                nodeParent = nodeType;
            }

            // Mbean node
            nodeMBean = new TreeControlNode(p_ParentNode.getName()
                    + WhereAreYou.NODE_SEPARATOR
                    + oItem.getObjectName()
                    , "icon/mbean.gif"
                    , oItem.getObjectName()
                    , "ListMBeanDetails.do?select=" + URLEncoder.encode(oItem.getObjectName(), "UTF-8")
                    , "content", false);
            nodeParent.addChild(nodeMBean);

        }
    }

    /**
     * Append nodes for all defined Unknown MBeans.
     *
     * @param p_ParentNode Parent node for the tree control
     * @param p_Resources The MessageResources for our localized messages
     * @param p_List The list of Mbeans
     *
     * @exception Exception if an exception occurs building the tree
     */
    public void getUnknownMBeans(TreeControlNode p_ParentNode, MessageResources p_Resources
        , ArrayList p_List)
        throws Exception {

        TreeControlNode nodeMBeans = new TreeControlNode(p_ParentNode.getName()
                + WhereAreYou.NODE_SEPARATOR
                + "unknown"
                , "icon/mbeans.gif"
                , p_Resources.getMessage("treenode.mbeans.unknown")
                , "ListUnknownMBeans.do", "content", false);
        p_ParentNode.addChild(nodeMBeans);
        // Sort list
        Collections.sort(p_List, new BeanComparator(new String[] {
            "domain", "objectName"}));

        // Detail MBean node
        MbeanItem oItem;
        String sLastDomain = "";
        TreeControlNode nodeMBean = null;
        TreeControlNode nodeDomain = null;
        TreeControlNode nodeType = null;
        TreeControlNode nodeParent = null;

        Iterator it = p_List.iterator();
        while (it.hasNext()) {
            oItem = (MbeanItem) it.next();

            nodeParent = nodeMBeans;
            if (oItem.getDomain() != null) {
                // Domain node
                if (!oItem.getDomain().equals(sLastDomain)) {
                    sLastDomain = oItem.getDomain();
                    nodeDomain = new TreeControlNode(nodeParent.getName()
                        + WhereAreYou.NODE_SEPARATOR + oItem.getDomain(), "icon/mbeandomain.gif"
                        , oItem.getDomain(), null, "content", false);
                    nodeMBeans.addChild(nodeDomain);
                }
                nodeParent = nodeDomain;

            }

            // Mbean node
            nodeMBean = new TreeControlNode(p_ParentNode.getName()
                    + WhereAreYou.NODE_SEPARATOR
                    + oItem.getObjectName()
                    , "icon/mbean.gif"
                    , oItem.getObjectName()
                    , "ListMBeanDetails.do?select=" + URLEncoder.encode(oItem.getObjectName(), "UTF-8")
                    , "content", false);
            nodeParent.addChild(nodeMBean);

        }
    }

    /**
     * Append nodes Attributes and Operations for a defined MBean.
     *
     * @param nodeMBean The MBean node
     * @param onMBean The MBean Object name
     * @param resources Resource
     * @throws Exception
     */
    protected void getMBeanInfo(TreeControlNode nodeMBean, ObjectName onMBean
        , MessageResources resources, HttpServletRequest p_Request)
        throws Exception {
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(WhereAreYou.
                SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        // Get all infos of a MBean
        MBeanInfo oMBeanInfo = JonasManagementRepr.getMBeanInfo(onMBean, serverName);
        // Get attributes infos
        MBeanAttributeInfo[] aoMBeanAttributeInfo = oMBeanInfo.getAttributes();
        if (aoMBeanAttributeInfo.length > 0) {
            // Append attributes node
            TreeControlNode nodeAttributes = new TreeControlNode("Attributes"
                + WhereAreYou.NODE_SEPARATOR + onMBean.toString(), "icon/JonasQuestion.gif"
                , resources.getMessage("treenode.allmbeans.attributes"), null, "content", false);
            nodeMBean.addChild(nodeAttributes);
            // Loop to append each attribute node
            for (int i = 0; i < aoMBeanAttributeInfo.length; i++) {
                TreeControlNode nodeAttr = new TreeControlNode(String.valueOf(i)
                    + WhereAreYou.NODE_SEPARATOR + onMBean.toString() + WhereAreYou.NODE_SEPARATOR
                    + aoMBeanAttributeInfo[i].getName(), "icon/property.gif"
                    , aoMBeanAttributeInfo[i].getName(), null, "content", false);
                nodeAttributes.addChild(nodeAttr);
            }
        }
        // Get operations infos
        MBeanOperationInfo[] aoMBeanOperationInfo = oMBeanInfo.getOperations();
        if (aoMBeanOperationInfo.length > 0) {
            // Append operations node
            TreeControlNode nodeOperations = new TreeControlNode("Operations"
                + WhereAreYou.NODE_SEPARATOR + onMBean.toString(), "icon/JonasQuestion.gif"
                , resources.getMessage("treenode.allmbeans.operations"), null, "content", false);
            nodeMBean.addChild(nodeOperations);
            // Loop to append each operation node
            for (int i = 0; i < aoMBeanOperationInfo.length; i++) {
                TreeControlNode nodeOpe = new TreeControlNode(String.valueOf(i)
                    + WhereAreYou.NODE_SEPARATOR + onMBean.toString() + WhereAreYou.NODE_SEPARATOR
                    + aoMBeanOperationInfo[i].getName(), "icon/action.gif"
                    , aoMBeanOperationInfo[i].getName(), null, "content", false);
                nodeOperations.addChild(nodeOpe);
            }
        }
    }

    /**
     * Create a ItemDestination object from a String structured as follows:
     * type=queue/topic, name=destName, id=#x.y.z
     * @param joramAdminDestination String containing destination description
     * @param serverName the name of the JOnAS server to which the current JORAM server is connected
     * @return ItemDestination containing name, type, id and ObjectName of the MBean associated to the corresponding destination
     * @throws MalformedObjectNameException could not construct destination ObjectName
     */
    public ItemDestination getDestinationItem(String joramAdminDestination, String serverName) throws MalformedObjectNameException {
        ItemDestination destinationItem = new ItemDestination();
        ObjectName destinationOn = null;
        StringTokenizer st = new StringTokenizer(joramAdminDestination, ",");
        String type = null;
        String name = null;
        String id = null;
        String serverId = null;
        while (st.hasMoreTokens()) {
            // A couple has the following structure: key=value
            String couple = st.nextToken().trim();
            int index = couple.indexOf("=");
            String key = couple.substring(0, index);
            String value = couple.substring(index + 1, couple.length());
            if (key.equals("type")) {
                type = value;
                destinationItem.setType(type);
            }
            if (key.equals("name")) {
                name = value;
                destinationItem.setName(name);
            }
            if (key.equals("id")) {
                id = value;
                destinationItem.setId(id);
                int indexBefore = id.indexOf("#");
                int indexAfter = id.indexOf(".", indexBefore);
                serverId = id.substring(indexBefore + 1, indexAfter);
                destinationItem.setServerId(serverId);
            }
        }
        if (name != null && type != null && id != null) {
            if (type.equals("topic")) {
                destinationOn = JoramObjectName.joramTopic(name);
            } else if (type.equals("queue")) {
                destinationOn = JoramObjectName.joramQueue(name);
            } else if (type.equals("queue.dmq")) {
                destinationOn = JoramObjectName.joramDMQ(name);
            }
            if (destinationOn != null
                    &&
                    JonasAdminJmx.hasMBeanName(destinationOn, serverName)) {
                destinationItem.setRegistered(true);
                // exists a destination MBean with the given type and name, check the id
                String foundId = (String) JonasManagementRepr.getAttribute(destinationOn, "Name", serverName);
                if (id.equals(foundId)) {
                    destinationItem.setOn(destinationOn);
                }
            }
        }
        return destinationItem;
    }

    /**
     * Append nodes for monitoring
     */
    protected void getMonitoring(TreeControlNode p_DomainNode, MessageResources p_Resources
            , HttpServletRequest p_Request, String domainName, String serverName)
            throws Exception {

        String domainNodeName = p_DomainNode.getName();
        TreeControlNode nodeMonitoring = new TreeControlNode(domainNodeName
                + WhereAreYou.NODE_SEPARATOR + "monitoring", "icon/monitoring.gif"
                , p_Resources.getMessage("treenode.jonas.domain.monitoring"), null, "content", true);

        p_DomainNode.addChild(0, nodeMonitoring);
        getMonitoringNodeList(nodeMonitoring, p_Resources, p_Request, domainName, serverName);
        getMonitoringClusterList(nodeMonitoring, p_Resources, p_Request, domainName, serverName);
        //getClusterDaemonList(nodeMonitoring, p_Resources, p_Request, domainName);
    }

    /**
     * Append nodes for servers monitoring
     */
    protected void getMonitoringNodeList(TreeControlNode p_ParentNode, MessageResources p_Resources
            , HttpServletRequest p_Request, String domainName, String serverName)
            throws Exception {
        // server proxy
        Iterator itNames = JonasAdminJmx.getListMbean(new ObjectName(domainName + ":type=ServerProxy,*"), serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName elem = (ObjectName) itNames.next();
            TreeControlNode node = new TreeControlNode(p_ParentNode.getName()
                    + WhereAreYou.NODE_SEPARATOR + elem.getKeyProperty("name"), "icon/BalJonasTree.gif"
                    , elem.getKeyProperty("name"), "DisplayNodeInfo.do?node=" + elem.getKeyProperty("name"), "content", true);

            p_ParentNode.addChild(node);
        }
    }

    /**
     * Append nodes for clusters monitoring
     */
    protected void getMonitoringClusterList(TreeControlNode p_ParentNode, MessageResources p_Resources
            , HttpServletRequest p_Request, String domainName, String serverName)
            throws Exception {

        String clusterType;
        String iconPath;
        String membersAttribute;
        String clusterActionPage;
        String memberActionPage;

        // tomcat cluster
        clusterType = "TomcatCluster";
        iconPath = "icon/domain_jonas.gif";
        membersAttribute = "Members";
        clusterActionPage = "TomcatClusterInfo.do?clust=";
        memberActionPage = "TomcatMemberInfo.do";

        displayClusterMembers(domainName, p_ParentNode, clusterType,
                   iconPath, membersAttribute,
                   clusterActionPage, memberActionPage,
                   domainName, serverName);


        // loadbalancing cluster
        clusterType = "JkCluster";
        iconPath = "icon/domain_jonas.gif";
        membersAttribute = "Members";
        clusterActionPage = "JkClusterInfo.do?clust=";
        memberActionPage = "JkMemberInfo.do";

        displayClusterMembers(domainName, p_ParentNode, clusterType,
                   iconPath, membersAttribute,
                   clusterActionPage, memberActionPage,
                   domainName, serverName);

        // CMI cluster
        clusterType = "CmiCluster";
        iconPath = "icon/domain_jonas.gif";
        membersAttribute = "Members";
        clusterActionPage = "CmiClusterInfo.do?clust=";
        memberActionPage = "CmiMemberInfo.do";

        displayClusterMembers(domainName, p_ParentNode, clusterType,
                   iconPath, membersAttribute,
                   clusterActionPage, memberActionPage,
                   domainName, serverName);

        // EjbHa cluster
        clusterType = "EjbHaCluster";
        iconPath = "icon/domain_jonas.gif";
        membersAttribute = "Members";
        clusterActionPage = "EjbHaClusterInfo.do?clust=";
        memberActionPage = "EjbHaMemberInfo.do";

        displayClusterMembers(domainName, p_ParentNode, clusterType,
                   iconPath, membersAttribute,
                   clusterActionPage, memberActionPage,
                   domainName, serverName);

        // Joram cluster
        clusterType = "JoramCluster";
        iconPath = "icon/domain_jonas.gif";
        membersAttribute = "Members";
        clusterActionPage = "JoramClusterInfo.do?clust=";
        memberActionPage = "JoramMemberInfo.do";

        displayClusterMembers(domainName, p_ParentNode, clusterType,
                   iconPath, membersAttribute,
                   clusterActionPage, memberActionPage,
                   domainName, serverName);

        // Logical cluster
        clusterType = "LogicalCluster";
        iconPath = "icon/domain_jonas.gif";
        membersAttribute = "Members";
        clusterActionPage = "LogicalClusterInfo.do?clust=";
        memberActionPage = "LogicalMemberInfo.do";

        displayClusterMembers(domainName, p_ParentNode, clusterType,
                   iconPath, membersAttribute,
                   clusterActionPage, memberActionPage,
                   domainName, serverName);
    }
    /**
     *
     * @param sDomainName
     * @param p_ParentNode
     * @param clusterType
     * @param iconPath
     * @param membersAttribute
     * @param clusterActionPage
     * @param memberActionPage
     */
    private void displayClusterMembers(String sDomainName, TreeControlNode p_ParentNode, String clusterType,
            String iconPath, String membersAttribute,
            String clusterActionPage, String memberActionPage, String domainName, String serverName) throws Exception {
        Iterator itNames = null;

        boolean isLogicalCluster = false;
        if (clusterType.equals("LogicalCluster")) {
            isLogicalCluster = true;
        }
        itNames = JonasAdminJmx.getListMbean(new ObjectName(sDomainName + ":type=" + clusterType + ",*"), serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName on = (ObjectName) itNames.next();
            String clusterName = on.getKeyProperty("name");
            if (clusterName.equals(domainName)) {
                continue;
            }
            String clusterNodeName = clusterName + " - (" + on.getKeyProperty("type") + ")";
            // Cluster node
            TreeControlNode nodeCluster = new TreeControlNode(p_ParentNode.getName()
                    + WhereAreYou.NODE_SEPARATOR + clusterNodeName, iconPath
                    , clusterNodeName, clusterActionPage + clusterName, "content", true);
            p_ParentNode.addChild(nodeCluster);

            String[] members = null;
            members = (String[]) JonasManagementRepr.getAttribute(on, membersAttribute, serverName);
            String memberAction = null;
            if (members != null) {
                for (int i = 0; i < members.length; i++) {
                    ObjectName onMember = new ObjectName(members[i]);
                    String memberName = onMember.getKeyProperty("name");
                    if ("LogicalCluster".equals(clusterType)) {
                        memberAction = null;
                    } else {
                        memberAction = memberActionPage
                        + "?member=" + memberName
                        + "&clust=" + clusterName;
                    }
                    // Members node
                    TreeControlNode node = new TreeControlNode(nodeCluster.getName()
                            + WhereAreYou.NODE_SEPARATOR + memberName, "icon/BalJonasTree.gif"
                            , memberName
                            , memberAction, "content", true);

                    nodeCluster.addChild(node);
                }
            }
        }
    }
    /**
     * Append nodes for cluster daemons
     */
    protected void getClusterDaemonList(TreeControlNode p_ParentNode, MessageResources p_Resources
            , HttpServletRequest p_Request, String domainName, String serverName)
    throws Exception {

        // clusterDaemon proxy
        Iterator itNames = JonasAdminJmx.getListMbean(new ObjectName(domainName + ":type=ClusterDaemonProxy,*"), serverName).iterator();
        while (itNames.hasNext()) {
            ObjectName elem = (ObjectName) itNames.next();
            TreeControlNode node = new TreeControlNode(p_ParentNode.getName()
                    + WhereAreYou.NODE_SEPARATOR + "ClusterDaemonProxy" + elem.getKeyProperty("name"), "icon/BalJonasGreen.gif"
                    , elem.getKeyProperty("name"), "DaemonProxyClusterInfo.do?node=" + elem.getKeyProperty("name"), "content", true);

            p_ParentNode.addChild(node);
        }
    }

    // MQ Connector support
    //----------------------
    /**
     *
     */
    public void getJonasMqConnectorPlatform(TreeControlNode pServerNode,
            String sServerName, MessageResources pResources,
            HttpServletRequest p_Request) throws Exception {
        /*
         * retrieve the domain name
         */
        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(
                WhereAreYou.SESSION_NAME);
        String sDomainName = oWhere.getCurrentDomainName();

        TreeControlNode platformNode = new TreeControlNode(pServerNode
                .getName()
                + WhereAreYou.NODE_SEPARATOR + "jonasmqconnect",
                "icon/service_jms.gif", pResources
                        .getMessage("treenode.joansmqconnect.name"),
                "JonasMqConnectPlatform.do", "content", false);

        pServerNode.addChild(platformNode);

        //ObjectName mqOnPattern = new ObjectName(sDomainName + ":type=JonasMQConnector,*");
        ObjectName[] mqOns = MqObjectNames.getConnectorsON(sDomainName, sServerName);
        for (int i = 0; i < mqOns.length; i++) {
            ObjectName on = (ObjectName) mqOns[i];
            String connectorName = on.getKeyProperty("name");
            TreeControlNode serverNode = new TreeControlNode(platformNode
                    .getName()
                    + WhereAreYou.NODE_SEPARATOR
                    + "jonasmqconnector"
                    + WhereAreYou.NODE_SEPARATOR + connectorName,
                    "icon/jms_connector.gif", connectorName,
                    "JonasMqConnect.do?operation=view&connector=" + connectorName,
                    "content", false);
            platformNode.addChild(serverNode);
            getJonasMqDestinations(serverNode, connectorName, sServerName, pResources, p_Request);
        }
    }
    /**
     *
     * Build the destination nodes
     */
    public void getJonasMqDestinations(TreeControlNode pMQNode, String connectorName,
            String sServerName, MessageResources pResources,
            HttpServletRequest p_Request) throws Exception {

        WhereAreYou oWhere = (WhereAreYou) p_Request.getSession().getAttribute(
                WhereAreYou.SESSION_NAME);
        String sDomainName = oWhere.getCurrentDomainName();
        //ObjectName mqDestPattern = new ObjectName(sDomainName + ":type=MQDestination,JonasMQConnector=" + connectorName+ ",*");
        //System.err.println("JOnASTreeBuilder querying " + mqDestPattern + " for server " + sServerName);
        ObjectName mqDestPattern = MqObjectNames.getDestinationsON(sDomainName, connectorName);
        Set destOns = JonasManagementRepr.queryNames(mqDestPattern, sServerName);
        for (Iterator i = destOns.iterator(); i.hasNext();) {
            ObjectName on = (ObjectName) i.next();
            String destName = on.getKeyProperty("name");
            boolean isTopic = ((Boolean) JonasManagementRepr.getAttribute(on, "IsTopic", sServerName)).booleanValue();
            TreeControlNode serverNode = new TreeControlNode(pMQNode.getName()
                    + WhereAreYou.NODE_SEPARATOR + "destination"
                    + WhereAreYou.NODE_SEPARATOR + destName,
                    "icon/" + (isTopic ? "jms_topic.gif" : "jms_queue.gif"), destName,
                    "JonasMqConnectDestinationEdit.do?operation=view&jndiName=" + destName + "&connector=" + connectorName,
                    "content", false);
            pMQNode.addChild(serverNode);
        }
    }
}
