/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2009 Bull S.A.S
 * Contact: jonas-team@ow2.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: JonasBaseAction.java 20598 2010-11-17 22:12:53Z alitokmen $
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.jonasadmin;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.management.ObjectName;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.Globals;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.ow2.jonas.lib.management.domain.proxy.server.ServerProxy;
import org.ow2.jonas.lib.management.extensions.base.BaseManagement;
import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;
import org.ow2.jonas.lib.management.javaee.J2eeObjectName;
import org.ow2.jonas.lib.util.Log;
import org.ow2.jonas.management.extensions.base.api.J2EEMBeanAttributeInfo;
import org.ow2.jonas.management.extensions.base.api.ManagementException;
import org.ow2.jonas.webapp.jonasadmin.service.ServiceItem;
import org.ow2.jonas.webapp.taglib.TreeControl;
import org.ow2.jonas.webapp.taglib.TreeControlNode;

/**
 * @author Michel-Ange ANTON
 * @author Florent Benoit (changes for struts 1.2.2)
 */

public abstract class JonasBaseAction extends Action {

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

    public static final int DEPTH_DOMAIN = 1;

    public static final int DEPTH_SERVER = 2;

    /**
     * Global Forward error page name.
     */
    public static final String GLOBAL_ERROR_FORWARD = "Global Error";

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

    /**
     * The MessageResources we will be retrieving messages from.
     */
    protected MessageResources m_Resources = null;

    protected HttpSession m_Session = null;

    protected ActionMessages m_Errors = null;

    protected WhereAreYou m_WhereAreYou = null;

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

    public abstract ActionForward executeAction(ActionMapping p_Mapping, ActionForm p_Form, HttpServletRequest p_Request,
            HttpServletResponse p_Response) throws IOException, ServletException;

    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an <code>ActionForward</code> instance describing where and how
     * control should be forwarded, or <code>null</code> if the response has
     * already been completed.
     * @param p_Mapping The ActionMapping used to select this instance
     * @param p_Form The optional ActionForm bean for this request (if any)
     * @param p_Request The HTTP request we are processing
     * @param p_Response The HTTP response we are creating
     * @return The forward where redirect
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    @Override
    public ActionForward execute(final ActionMapping p_Mapping, final ActionForm p_Form, final HttpServletRequest p_Request,
            final HttpServletResponse p_Response) throws IOException, ServletException {

        ActionForward oActionForward = null;

        // Instance variables
        initialize(p_Request);

        // Verify that a instance of WhereAreYou object exists
        if (m_WhereAreYou == null) {
            oActionForward = (p_Mapping.findForward("Main Index"));
        } else {
            oActionForward = executeAction(p_Mapping, p_Form, p_Request, p_Response);
        }
        return oActionForward;
    }

    /**
     * Initialize the instance variables.
     * @param p_Request The HTTP request we are processing
     */
    protected void initialize(final HttpServletRequest p_Request) {
        // Acquire the resources that we need
        m_Session = p_Request.getSession();
        if (m_Resources == null) {
            m_Resources = (MessageResources) getServlet().getServletContext().getAttribute(Globals.MESSAGES_KEY);
        }
        m_Errors = new ActionMessages();
        m_WhereAreYou = (WhereAreYou) m_Session.getAttribute(WhereAreYou.SESSION_NAME);

    }

    /**
     * Return the name of the branch in the tree for the selected node.
     * @param p_Width Depth of the branch
     * @return The branch name
     */
    protected String getTreeBranchName(final int p_Width) {
        StringBuffer sb = new StringBuffer();
        try {
            StringTokenizer st = new StringTokenizer(m_WhereAreYou.getSelectedNameNode(), WhereAreYou.NODE_SEPARATOR);
            for (int i = 0; (st.hasMoreTokens() && (i < p_Width)); i++) {
                if (i > 0) {
                    sb.append(WhereAreYou.NODE_SEPARATOR);
                }
                sb.append(st.nextToken());
            }
        } catch (NullPointerException e) {
            // none action
        }
        return sb.toString();
    }

    /**
     * Add a global error in <code>m_Errors</code>instance of
     * <code>m_ErrorsActionMessages</code> and log it.
     * @param p_Throwable Error to add
     */
    protected void addGlobalError(final Throwable p_Throwable) {
        String sMessResource;
        String sMessageError = p_Throwable.getMessage();
        if (sMessageError == null) {
            sMessResource = m_Resources.getMessage("error.global.log", p_Throwable.getClass().getName());
            // getServlet().log(sMessResource, p_Throwable);
            Logger logger = Log.getLogger(Log.JONAS_ADMIN_PREFIX);
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG, sMessResource);
            }
            m_Errors.add("error.global", new ActionMessage("error.global", p_Throwable.getClass().getName()));
        } else {
            sMessResource = m_Resources.getMessage("error.global.message.log", p_Throwable.getClass().getName(), sMessageError);
            // getServlet().log(sMessResource, p_Throwable);
            Logger logger = Log.getLogger(Log.JONAS_ADMIN_PREFIX);
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG, sMessResource);
            }
            m_Errors.add("error.global", new ActionMessage("error.global.message", p_Throwable.getClass().getName(),
                    sMessageError));
        }
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param on Instance of ObjectName to access to MBean
     * @param param invoke parameters
     * @param signature invoke parameters signature
     */
    protected Object invoke(final ObjectName on, final String operation, final Object[] param, final String[] signature) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        return JonasManagementRepr.invoke(on, operation, param, signature, pServer);
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected String getStringAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        String s = (String) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
        return s;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected String[] getStringArrayAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        String[] s = (String[]) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
        return s;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @param p_Value Value to write
     */
    protected void setStringAttribute(final ObjectName p_ObjectName, final String ps_AttrName, final String p_Value) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        JonasManagementRepr.setAttribute(p_ObjectName, ps_AttrName, p_Value, pServer);
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected int getIntegerAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Integer o = (Integer) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
            return o.intValue();
        } catch (Exception e) {
            addGlobalError(e);
        }
        return 0;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected String toStringIntegerAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String serverName = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Integer o = (Integer) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, serverName);
            return o.toString();
        } catch (Exception e) {
            addGlobalError(e);
        }
        return null;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @param p_Value Value to write
     */
    protected void setIntegerAttribute(final ObjectName p_ObjectName, final String ps_AttrName, final int p_Value) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        JonasManagementRepr.setAttribute(p_ObjectName, ps_AttrName, new Integer(p_Value), pServer);
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @param p_Value Value to write
     */
    protected void setIntegerAttribute(final ObjectName p_ObjectName, final String ps_AttrName, final String p_Value) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        if ((p_Value != null) && (p_Value.length() > 0)) {
            JonasManagementRepr.setAttribute(p_ObjectName, ps_AttrName, new Integer(p_Value), pServer);
        }
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected long getLongAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Long o = (Long) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
            return o.longValue();
        } catch (Exception e) {
            addGlobalError(e);
        }
        return 0;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected int getIntAttribute(final ObjectName objectName, final String attrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Integer o = (Integer) JonasManagementRepr.getAttribute(objectName, attrName, pServer);
            return o.intValue();
        } catch (Exception e) {
            addGlobalError(e);
        }
        return 0;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected String toStringLongAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Long o = (Long) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
            return o.toString();
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return null;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @param p_Value Value to write
     */
    protected void setLongAttribute(final ObjectName p_ObjectName, final String ps_AttrName, final long p_Value) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        JonasManagementRepr.setAttribute(p_ObjectName, ps_AttrName, new Long(p_Value), pServer);
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected long getShortAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Short o = (Short) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
            return o.longValue();
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return 0;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected String toStringShortAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Short o = (Short) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
            return o.toString();
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return null;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @param p_Value Value to write
     */
    protected void setShortAttribute(final ObjectName p_ObjectName, final String ps_AttrName, final long p_Value) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        JonasManagementRepr.setAttribute(p_ObjectName, ps_AttrName, new Long(p_Value), pServer);
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected boolean getBooleanAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Boolean o = (Boolean) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
            return o.booleanValue();
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return false;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected String toStringBooleanAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            Boolean o = (Boolean) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer);
            return o.toString();
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return null;
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @param p_Value Value to write
     */
    protected void setBooleanAttribute(final ObjectName p_ObjectName, final String ps_AttrName, final boolean p_Value) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        JonasManagementRepr.setAttribute(p_ObjectName, ps_AttrName, new Boolean(p_Value), pServer);
    }

    /**
     * MBean <code>ObjectName</code> accessor.
     * @param p_ObjectName Instance of ObjectName to access to MBean
     * @param ps_AttrName Attribute name of MBean
     * @return The value of attribute
     */
    protected List getListAttribute(final ObjectName p_ObjectName, final String ps_AttrName) {
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        try {
            return ((List) JonasManagementRepr.getAttribute(p_ObjectName, ps_AttrName, pServer));
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return new ArrayList();
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @return The value of attribute
     */
    protected String getStringAttribute(final Properties p_Props, final String ps_AttrName) {
        return p_Props.getProperty(ps_AttrName);
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Default The returned value if the attribute don't exists in the
     *        properties
     * @return The value of attribute
     */
    protected String getStringAttribute(final Properties p_Props, final String ps_AttrName, final String p_Default) {
        return p_Props.getProperty(ps_AttrName, p_Default);
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Value Value to write
     */
    protected void setStringAttribute(final Properties p_Props, final String ps_AttrName, final String p_Value) {
        if (p_Value != null) {
            p_Props.setProperty(ps_AttrName, p_Value);
        }
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Value Value to write
     * @param p_Default The forced value if the value is null or empty
     */
    protected void setStringAttribute(final Properties p_Props, final String ps_AttrName, final String p_Value,
            final String p_Default) {
        if ((p_Value != null) && (p_Value.length() == 0)) {
            p_Props.setProperty(ps_AttrName, p_Default);
        } else {
            p_Props.setProperty(ps_AttrName, p_Value);
        }
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @return The value of attribute (return 0 if attribute don't exists)
     */
    protected int getIntegerAttribute(final Properties p_Props, final String ps_AttrName) {
        return getIntegerAttribute(p_Props, ps_AttrName, 0);
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Default The returned value if the attribute don't exists in the
     *        properties
     * @return The value of attribute
     */
    protected int getIntegerAttribute(final Properties p_Props, final String ps_AttrName, final int p_Default) {
        try {
            String s = getStringAttribute(p_Props, ps_AttrName);
            if (s != null) {
                return Integer.parseInt(s);
            }
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return p_Default;
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Value Value to write
     */
    protected void setIntegerAttribute(final Properties p_Props, final String ps_AttrName, final int p_Value) {
        p_Props.setProperty(ps_AttrName, String.valueOf(p_Value));
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @return The value of attribute (return 0 if attribute don't exists)
     */
    protected long getLongAttribute(final Properties p_Props, final String ps_AttrName) {
        return getLongAttribute(p_Props, ps_AttrName, 0L);
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Default The returned value if the attribute don't exists in the
     *        properties
     * @return The value of attribute
     */
    protected long getLongAttribute(final Properties p_Props, final String ps_AttrName, final long p_Default) {
        try {
            String s = getStringAttribute(p_Props, ps_AttrName);
            if (s != null) {
                return Long.parseLong(s);
            }
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return p_Default;
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Value Value to write
     */
    protected void setLongAttribute(final Properties p_Props, final String ps_AttrName, final long p_Value) {
        p_Props.setProperty(ps_AttrName, String.valueOf(p_Value));
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @return The value of attribute (return false if attribute don't exists)
     */
    protected boolean getBooleanAttribute(final Properties p_Props, final String ps_AttrName) {
        return getBooleanAttribute(p_Props, ps_AttrName, false);
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Default The returned value if the attribute don't exists in the
     *        properties
     * @return The value of attribute
     */
    protected boolean getBooleanAttribute(final Properties p_Props, final String ps_AttrName, final boolean p_Default) {
        try {
            String s = getStringAttribute(p_Props, ps_AttrName);
            if (s != null) {
                return Boolean.getBoolean(s);
            }
        } catch (Exception e) {
            addGlobalError(e);
            // None
        }
        return p_Default;
    }

    /**
     * Properties accessor.
     * @param p_Props Instance of Properties
     * @param ps_AttrName Attribute name of Properties
     * @param p_Value Value to write
     */
    protected void setBooleanAttribute(final Properties p_Props, final String ps_AttrName, final boolean p_Value) {
        p_Props.setProperty(ps_AttrName, String.valueOf(p_Value));
    }
    /**
     * Get properties from stringified property table.
     * @param ps_Props stringified property table
     * @return properties.
     */
    protected Properties getPropsFromString(final String ps_Props) {
        // Clean the string
        String sProps = ps_Props.trim();
        sProps = removeChar(sProps, '\r');
        sProps = removeChar(sProps, '\n');
        Properties sp = new Properties();
        StringTokenizer st = new StringTokenizer(sProps, ",");
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            int pos = token.indexOf("=");
            String propName = token.substring(0, pos);
            String propValue = token.substring(pos + 1);
            sp.setProperty(propName, propValue);
        }
        return sp;
    }

    /**
     * Remove a specific character in a String Do not use replaceAll as it is a
     * JDK 1.4 method.
     * @param string the given string
     * @param c character to remove in the String
     * @return a string
     */
    protected static String removeChar(final String string, final char c) {
        StringBuffer sb = new StringBuffer();
        sb.setLength(string.length());
        int i = 0;
        for (int j = 0; j < string.length(); j++) {
            char cur = string.charAt(j);
            if (cur != c) {
                sb.setCharAt(i++, cur);
            }
        }
        return sb.toString();
    }

    /**
     * Refresh the entire management tree.
     * @throws Exception any.
     */
    protected void refreshTree(final HttpServletRequest p_Request) throws Exception {
        // Get current tree
        TreeControl oControl = m_WhereAreYou.getTreeControl();
        // tree root
        TreeControlNode root = oControl.getRoot();
        // domain node
        TreeControlNode domainNode = oControl.findNode("domain");
        if (domainNode != null) {
            // Enable auto-refresh mode
            oControl.enableAutoRefresh();
            // Remove node
            domainNode.remove();
            // Build node and his children
            JonasTreeBuilder oBuilder = new JonasTreeBuilder();
            // TODO Flex integration
            // oBuilder.getDomainNode(root, m_Resources, p_Request);
            oBuilder.getRootNode(root, m_Resources, p_Request);
            // Disable auto-refresh mode
            oControl.disableAutoRefresh();
        }
    }
    /**
     * refresh service's tree.
     * @param request the http request.
     * @throws Exception any.
     */
    protected void refreshServicesTree(final HttpServletRequest request) throws Exception {
        String serverName = m_WhereAreYou.getCurrentJonasServerName();
        String domainName = m_WhereAreYou.getCurrentDomainName();
        // Get current tree
        TreeControl oControl = m_WhereAreYou.getTreeControl();
        // Build node and his children
        JonasTreeBuilder oBuilder = new JonasTreeBuilder();

        String servicesNodeName = "domain" + WhereAreYou.NODE_SEPARATOR + serverName + WhereAreYou.NODE_SEPARATOR + "services";
        // The node representing services in the jonasAdmin tree.
        TreeControlNode servicesNode = oControl.findNode(servicesNodeName);
        if (servicesNode != null) {
            // TreeControlNode serverNode= servicesNode.getParent();
            TreeControlNode[] aoNodes = servicesNode.findChildren();
            for (int i = 0; i < aoNodes.length; i++) {
                aoNodes[i].remove();
            }
            // Enable auto-refresh mode
            oControl.enableAutoRefresh();
            // servicesNode.remove();
            boolean refreshServices = true;
            // oBuilder.getServices(serverNode, m_Resources, request,
            // domainName, serverName, refreshServices);
            oBuilder.getServicesNodes(servicesNode, m_Resources, request, domainName, serverName, refreshServices);
            // Disable auto-refresh mode
            oControl.disableAutoRefresh();
            // Force display to refresh
            m_WhereAreYou.setTreeToRefresh(true);
        }
    }

    /**
     * Refresh the domain deployment nodes of the tree.
     * @param p_Request the http request
     * @throws Exception any.
     */
    protected void refreshDomainDeployTree(final HttpServletRequest p_Request) throws Exception {
        // Get current tree
        TreeControl oControl = m_WhereAreYou.getTreeControl();
        TreeControlNode domainNode = oControl.findNode("domain");
        if (domainNode != null) {
            // Enable auto-refresh mode
            oControl.enableAutoRefresh();
            // Remove node
            // Build node and his children
            JonasTreeBuilder oBuilder = new JonasTreeBuilder();
            oBuilder.getDomainDeploy(oControl.findNode("domain"), m_Resources, p_Request);
            // Disable auto-refresh mode
            oControl.disableAutoRefresh();
        }

    }

    /**
     * @return the current server's JONAS_BASE.
     */
    protected String getJonasBase() {
        String pDomain = m_WhereAreYou.getCurrentDomainName();
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        ObjectName j2eeServerOn = J2eeObjectName.J2EEServer(pDomain, pServer);
        String jonasBase = getStringAttribute(j2eeServerOn, "jonasBase");
        if (!jonasBase.endsWith(File.separator)) {
            jonasBase = jonasBase.concat(File.separator);
        }
        return jonasBase;
    }

    /**
     * Gets the server name for given provider url.
     * @param providerUrl get name for this
     * @param checkWithinInThis check in this list
     * @return
     */
    public static String getNameForProvider(final String providerUrl, final Collection<?> checkWithinInThis) {

        String urlCp = providerUrl;
        String host = urlCp.substring(urlCp.lastIndexOf("/") + 1, urlCp.lastIndexOf(":"));
        if (host.startsWith("127")) {
            urlCp = urlCp.replace(host, "localhost");
        }
        for (Object object : checkWithinInThis) {
            ServerProxy srv = (ServerProxy) object;
            List urls = srv.getUrls();
            String url;
            for (int i = 0; i < urls.size(); i++) {
                url = urls.get(i).toString();
                if (url.contains(urlCp)) {
                    return srv.getName();
                }
            }
        }
        return null;
    }
    /**
     * Get service item.
     * @param serviceName the service name.
     * @return the service item.
     */
    public ServiceItem getServerItem(final String serviceName) {
        boolean active = isActive(serviceName);
        if (ServiceName.JMX.getName().equals(serviceName)) {
            String forward = "ActionEditJmxServer";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.jmx");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("mandatory");
            return item;
        }
        if (ServiceName.REGISTRY.getName().equals(serviceName)) {
            String forward = "ActionListRegistry";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.registry");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("mandatory");
            return item;
        }
        if (ServiceName.CMI.getName().equals(serviceName)) {
            String forward = "ActionDisplayCmi";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.cmi");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.HA.getName().equals(serviceName)) {
            String forward = null;
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.ha");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.EAR.getName().equals(serviceName)) {
            String forward = "ActionListAppContainers";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.ear");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("container");
            return item;
        }
        if (ServiceName.EJB2.getName().equals(serviceName)) {
            String forward = "ActionListContainers";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.ejb2Containers");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("container");
            return item;
        }
        if (ServiceName.EJB3.getName().equals(serviceName)) {
            String forward = "ActionListContainers";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.ejb3Containers");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("container");
            return item;
        }
        if (ServiceName.WEB.getName().equals(serviceName)) {
            String forward = "ActionListWebContainers";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.web");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("container");
            return item;
        }
        if (ServiceName.DBM.getName().equals(serviceName)) {
            String forward = "ActionListDatabases";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.database");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.DB.getName().equals(serviceName)) {
            String forward = null;
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.db");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.RESOURCE.getName().equals(serviceName)) {
            String forward = "ActionListResourceAdapters";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.resource");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("container");
            return item;
        }
        if (ServiceName.JTM.getName().equals(serviceName)) {
            String forward = "ActionEditJtmService";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.transaction");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("technical");
            return item;
        }
        if (ServiceName.MAIL.getName().equals(serviceName)) {
            String forward = "ActionEditMailService";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.mail");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.SECURITY.getName().equals(serviceName)) {
            String forward = "ActionEditServiceSecurity";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.security");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("mandatory");
            return item;
        }
        if (ServiceName.DISCOVERY.getName().equals(serviceName)) {
            String forward = "ActionEditServiceDiscovery";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.discovery");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.DEPMONITOR.getName().equals(serviceName)) {
            String forward = "ActionEditServiceDepmonitor";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.depmonitor");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.WM.getName().equals(serviceName)) {
            String forward = "ActionEditWorkmanagerService";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.workmanager");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.WC.getName().equals(serviceName)) {
            String forward = "ActionEditWorkcleanerService";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.workcleaner");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.WS.getName().equals(serviceName)) {
            String forward = "ActionListWebService";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.webservices");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("container");
            return item;
        }
        if (ServiceName.WSDLPUBLISHER.getName().equals(serviceName)) {
            String forward = null;
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.wsdlpublisher");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("webservices");
            return item;
        }
        if (ServiceName.JAXRPC.getName().equals(serviceName)) {
            String forward = null;
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.jaxrpc");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("webservices");
            return item;
        }
        if (ServiceName.JAXWS.getName().equals(serviceName)) {
            String forward = null;
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.jaxws");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("webservices");
            return item;
        }
        if (ServiceName.VERSIONING.getName().equals(serviceName)) {
            String forward = "ActionEditVersioningService";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.versioning");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        if (ServiceName.SMARTCLIENT.getName().equals(serviceName)) {
            String forward = "ActionEditSmartclientService";
            String messageName = m_Resources.getMessage("treenode.jonas.server.services.smartclient");
            ServiceItem item = new ServiceItem(messageName, active, forward);
            item.setPropName(serviceName);
            item.setCategory("other");
            return item;
        }
        return null;
    }
    /**
     * <code>true</code> if the given service is active.
     * @param serviceName the service name.
     * @return <code>true</code> if the given service is active.
     */
    public boolean isActive(final String serviceName) {
        String pDomain = m_WhereAreYou.getCurrentDomainName();
        String pServer = m_WhereAreYou.getCurrentJonasServerName();
        ObjectName j2eeServerOn = J2eeObjectName.J2EEServer(pDomain, pServer);
        String operation = "getServiceState";
        String[] param = new String[1];
        param[0] = serviceName;
        String[] signature = {"java.lang.String"};
        String state = (String) JonasManagementRepr.invoke(j2eeServerOn, operation, param, signature, pServer);
        if ("RUNNING".equals(state)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Get management attributes.
     * @param objectName <code>objectName</code>
     * @param serverName server name.
     * @return attributes for the given objectName.
     */
    public J2EEMBeanAttributeInfo[] getAttributes(final ObjectName objectName, final String serverName) {
        try {
            return BaseManagement.getInstance().getAttributes(objectName, serverName);
        } catch (ManagementException e) {
            ;
        }
        return null;
    }

}
