/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2005 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 1any 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.jonasadmin.test.util;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;

import junit.framework.TestCase;

import org.ow2.jonas.adm.AdmInterface;
import org.ow2.jonas.lib.management.javaee.J2eeObjectName;
import org.omg.CORBA.ORB;

import com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.TableCell;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

/**
 * Define a class to add useful methods for test the examples
 *  - Deploy ear, war and beans
 *  - Retrieve initial context
 * @author Florent Benoit
 */
public class JonasAdminTestCase extends TestCase {

    /**
     * URL of the login page
     *
     */
    protected static final String URL_JONASADMIN = "/jonasAdmin/";

    /**
     * NAME of FRAME content
     */
    protected static final String FRAME_CONTENT = "content";

    /**
     * NAME of FRAME tree
     */
    protected static final String FRAME_TREE = "tree";

    /**
     * NAME of FRAME top
     */
    protected static final String FRAME_TOP = "top";

    /**
     * URL of the deployment of EARs
     */
    protected static final String URL_JONASADMIN_DEPLOYEAR = "/jonasAdmin/EditDeploy.do?type=ear";

    /**
     * URL of the deployment of JARs
     */
    protected static final String URL_JONASADMIN_DEPLOYJAR = "/jonasAdmin/EditDeploy.do?type=jar";

    /**
     * Name of the property file of jonasAdmin tests
     */
    private static final String JONASADMINTEST_PROPERTY_NAME = "jonasAdminTests.properties";
    /**
     * JoramAdmin MBean's OBJECT_NAME
     */
    private static final String JORAM_ADMIN_ON = "joramClient:type=JoramAdmin";
    /**
     * Name of the JOnAS server used for tests
     */
    private static String jonasName = "jonas";
    /**
     * Name of the domain
     */
    private static String domainName = "jonas";
    /**
     * Initial context used for lookup
     */
    private static Context ictx = null;

    /**
     * JOnAS admin used for communicate via JMX to JOnAS
     */
    private static AdmInterface admI = null;

    /**
     * JMX connector
     */
    private static JMXConnector connector = null;

    /**
     * MBean Server Connection
     */
    private static MBeanServerConnection currentServerConnection = null;

    /**
     * Client ORB
     */
    private static ORB orb =null;

    /**
     * Conversation used for HttpUnit
     */
    protected static WebConversation wc = null;

    /**
     * URL used for the constructor
     */
    protected String url = null;

    /**
     * URL used to return to Welcome.jsp
     */
    protected String urlWelcome = null;

    /**
     * URL used to log out
     */
    protected String urlLogOut = null;


    /**
     * Prefix for build URLs
     */
    protected String prefixUrl = null;

    /**
     * JOnAS and jonasAdmin properties
     */
    protected JProperties jProp = null;

    /**
     * jonasAdmin test properties
     */
    protected Properties configFile;

    /**
     * jonasAdmin port
     */
    protected String port;

    /**
     * Add to the specified url the prefix
     * @param url relative URL
     * @return absolute path of URL
     */
    protected String getAbsoluteUrl (String url) {
        return (this.prefixUrl + url);
    }

    /**
     * Initialize the port used by tests and the prefix
     */
    private void init() {
        // Port
        port = System.getProperty("http.port");
        if (port == null) {
            port = "9000";
        }

        // urls
        prefixUrl = "http://localhost:" + port;
        urlWelcome = prefixUrl + "/jonasAdmin/Welcome.do";
        urlLogOut = prefixUrl + "/jonasAdmin/logOut.do";

        // Properties
        jProp = new JProperties();

        try {
            configFile = jProp.getProperties(JONASADMINTEST_PROPERTY_NAME);
        } catch (Exception e) {
            System.err.println("Cannot find file : " + JONASADMINTEST_PROPERTY_NAME + ". " + e);
            e.printStackTrace();
        }

    }

    /**
     * Constructor with a specified name
     * @param s the name
     */
    public JonasAdminTestCase(String s) {
        super(s);
        init();
    }

    /**
     * Constructor with a specified name and url
     * @param s the name
     * @param url the url which can be used
     */
    public JonasAdminTestCase(String s, String url) {
        super(s);
        init();
        this.url = getAbsoluteUrl(url);
    }

    /**
     * Get initialContext
     * @return the initialContext
     * @throws NamingException if the initial context can't be retrieved
     */
    private Context getInitialContext() throws NamingException {
        return new InitialContext();
    }

    /**
     * Common setUp routine, used for every test.
     * @throws Exception if an error occurs
     */
    protected void setUp() throws Exception {

        // WebConversation to jonasAdmin
        wc = JonasAdminConnexion.getWc();
        if (wc == null) {
            wc = JonasAdminConnexion.createWc();
        }

        try {
            // get InitialContext
            if (ictx == null) {
                ictx = getInitialContext();
            }
            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }

        } catch (NamingException e) {
            System.err.println("Cannot setup test: " + e);
            e.printStackTrace();
        }

        // Get a MBean Server connection and set currentServerConnection variable
        initMBeanServer();
    }


    /**
     * Load an ear file in the jonas server
     * @param filename ear file, without ".ear" extension
     * @throws Exception if an error occurs
     */
    public void useEar(String filename) throws Exception {

        try {
            // Load ear in JOnAS if not already loaded.
            if (ictx == null) {
                ictx = getInitialContext();
            }

            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }

            //Test in both directories (apps/ and apps/autoload)
            String appsFileName = filename + ".ear";
            String autoloadAppsFileName = "autoload" + File.separator + filename + ".ear";
            if (!admI.isEarLoaded(appsFileName) && !admI.isEarLoaded(autoloadAppsFileName)) {
                //if the file was in autoload, it was loaded
                admI.addEar(appsFileName);
            }

        } catch (Exception e) {
            throw new Exception("Cannot load Ear : " + e.getMessage());
        }
    }


    /**
     * Unload a ear file in the jonas server
     * @param filename ear file, without ".ear" extension
     * @throws Exception if an error occurs
     */
    public void unUseEar(String filename) throws Exception {
        try {
            // Unload ear in EARServer if not already loaded.
            if (ictx == null) {
                ictx = getInitialContext();
            }
            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }
            if (admI.isEarLoaded(filename + ".ear")) {
                admI.removeEar(filename + ".ear");
            }
        } catch (Exception e) {
            throw new Exception("Cannot unload Bean : " + e.getMessage());
        }
    }

    /**
     * Load a war file in the jonas server
     * @param filename war file, without ".war" extension
     * @throws Exception if an error occurs
     */
    public void useWar(String filename) throws Exception {

        try {
            // Load war in JOnAS if not already loaded.
            if (ictx == null) {
                ictx = getInitialContext();
            }

            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }

            //Test in both directories (apps/ and apps/autoload)
            String webappsFileName = filename + ".war";
            String autoloadWebappsFileName = "autoload" + File.separator + filename + ".war";
            if (!admI.isWarLoaded(webappsFileName) && !admI.isWarLoaded(autoloadWebappsFileName)) {
                //if the file was in autoload, it was loaded
                admI.addWar(webappsFileName);
            }

        } catch (Exception e) {
            throw new Exception("Cannot load War : " + e.getMessage());
        }
    }

    /**
     * Load a bean jar file in the jonas server
     * @param filename jar file, without ".jar" extension
     * @throws Exception if an error occurs
     */
    public void useBeans(String filename) throws Exception {
        try {
            // Load bean in EJBServer if not already loaded.
            if (ictx == null) {
                ictx = getInitialContext();
            }
            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }
            if (!admI.isLoaded(filename + ".jar")) {
                admI.addBeans(filename + ".jar");
            }
        } catch (Exception e) {
            throw new Exception("Cannot load Bean : " + e.getMessage());
        }
    }


    /**
     * Unload a bean jar file in the jonas server
     * @param filename jar file, without ".jar" extension
     * @throws Exception if an error occurs
     */
    public void unUseBeans(String filename) throws Exception {
        try {
            // Load bean in EJBServer if not already loaded.
            if (ictx == null) {
                ictx = getInitialContext();
            }
            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }
            if (admI.isLoaded(filename + ".jar")) {
                admI.removeBeans(filename + ".jar");
            }
        } catch (Exception e) {
            throw new Exception("Cannot unload Bean : " + e.getMessage());
        }
    }


    /**
     * Load a rar file in the jonas server
     * @param filename rar file, without ".rar" extension
     * @throws Exception if an error occurs
     */
    public void useRar(String filename) throws Exception {

        try {
            // Load rar in JOnAS if not already loaded.
            if (ictx == null) {
                ictx = getInitialContext();
            }

            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }

            //Test in both directories (rars/ and rars/autoload)
            String raFileName = filename + ".rar";
            String autoloadRaFileName = "autoload" + File.separator + filename + ".rar";
            if (!admI.isRarLoaded(raFileName) && !admI.isRarLoaded(autoloadRaFileName)) {
                //if the file was in autoload, it was loaded
                admI.addRar(raFileName);
            }

        } catch (Exception e) {
            throw new Exception("Cannot load Rar : " + e.getMessage());
        }
    }


    /**
     * Rar is loaded in the jonas server
     * @param filename rar file, without ".rar" extension
     * @return true if the rar is loaded, else false
     * @throws Exception if an error occurs
     */
    public boolean isRarLoaded(String filename) throws Exception {

        boolean found = false;

        try {
            // Load rar in JOnAS if not already loaded.
            if (ictx == null) {
                ictx = getInitialContext();
            }

            if (admI == null) {
                admI = (AdmInterface) PortableRemoteObject.narrow(ictx.lookup(jonasName + "_Adm"), AdmInterface.class);
            }

            //Test in both directories (rars/ and rars/autoload)
            String raFileName = filename + ".rar";
            String autoloadRaFileName = "autoload" + File.separator + filename + ".rar";
            if (admI.isRarLoaded(raFileName) || admI.isRarLoaded(autoloadRaFileName)) {
                //if the file was in autoload, it was loaded
                found = true;
            }

        } catch (Exception e) {
            throw new Exception("Cannot load Rar : " + e.getMessage());
        }

        return found;
    }

    /**
     * Create a mail factory in jonas server
     * @param mail factory name of the datasource
     * @param properties properties of the mail factory
     * @throws Exception if an error occurs
     */
    protected void createMailFactory(String mailFactory, Properties properties) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("jonas:type=service,name=mail");

        // add properties in 'datasource'.properties
        JonasAdminFiles.writeConfigFile(mailFactory + ".properties", properties);

        Object[] params = new Object[] {mailFactory, properties, new Boolean(true)};
        server.invoke(on, "createMailFactoryMBean", params, new String[] {String.class.getName(), Properties.class.getName(), Boolean.class.getName()});

    }

    /**
     * Unbind a mail factory in jonas server
     * @param mailFactory name of the mail factory
     * @throws Exception if an error occurs
     */
    protected void unBindMailFactory(String mailFactory) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("jonas:type=service,name=mail");

        Object[] params = new Object[] {mailFactory};
        server.invoke(on, "unbindMailFactoryMBean", params, new String[] {String.class.getName()});
    }

    /**
     * Return if the mail factory is in mail factory list
     * @param mailFactory the name of the mail factory
     * @return true if the mail factory is in list, false else.
     * @throws Exception if an error occurs.
     */
    protected boolean isInMailFactoryList(String mailFactory) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("jonas:type=service,name=mail");

        List list = (List) server.getAttribute(on, "MailFactoryPropertiesFiles");

        return list.contains(mailFactory);
    }

    /**
     * Load a datasource in jonas server
     * @param datasource name of the datasource
     * @param properties properties of the datasource
     * @throws Exception if an error occurs
     */
    protected void useDatasource(String datasource, Properties properties) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("jonas:type=service,name=database");

        if (!((Boolean) server.invoke(on, "isLoadedDataSource", new Object[] {datasource}, new String[] {String.class.getName()})).booleanValue()) {
            // add properties in 'datasource'.properties
            JonasAdminFiles.writeConfigFile(datasource + ".properties", properties);

            Object[] params = new Object[] {datasource, properties, new Boolean(true)};
            server.invoke(on, "loadDataSource", params, new String[] {String.class.getName(), Properties.class.getName(), Boolean.class.getName()});
        }
    }

    /**
     * Check if database service is started (dbm)
     * @return true if dbm started
     * @throws Exception if an error occurs
     */
    protected boolean isDatabaseService() throws Exception {
        boolean result = false;
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("jonas:type=service,name=database");
        if (server.isRegistered(on)) {
            result = true;
        }
        return result;
    }

    /**
     * Check if the Joram RAR is deplyed
     * @return true if dbm started
     * @throws Exception if an error occurs
     */
    protected boolean isJoramRar() throws Exception {
        boolean result = false;
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance(JORAM_ADMIN_ON);
        if (server.isRegistered(on)) {
            result = true;
        }
        return result;
    }

    /**
     * Unload a datasource in jonas server
     * @param datasource name of the datasource
     * @throws Exception if an error occurs
     */
    protected void unUseDatasource(String datasource) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("jonas:type=service,name=database");

        if (((Boolean) server.invoke(on, "isLoadedDataSource", new Object[] {datasource}, new String[] {String.class.getName()})).booleanValue()) {

            Object[] params = new Object[] {datasource};
            server.invoke(on, "unloadDataSource", params, new String[] {String.class.getName()});
        }
    }

    /**
     * Load a datasource in jonas server
     * @param datasource name of the datasource
     * @return boolean true if the datasource is loaded, false else
     * @throws Exception if an error occurs
     */
    protected boolean isLoadedDatasource(String datasource) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("jonas:type=service,name=database");

        return ((Boolean) server.invoke(on, "isLoadedDataSource", new Object[] {datasource}, new String[] {String.class.getName()})).booleanValue();
    }

    /**
     * Create a topic in a joram server
     * @param name name of the topic
     * @param idString id of the current joram server
     * @throws Exception if an error occurs
     */
    protected void createTopic(String name, int idString) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("joramClient:type=JoramAdapter,*");
        ObjectName joramAdapterON = (ObjectName) server.queryNames(on, null).iterator().next();

        Object[] params = new Object[] {new Integer(idString), name};
        server.invoke(joramAdapterON, "createTopic", params, new String[] {"int", String.class.getName()});
    }

    /**
     * Create a queue in a joram server
     * @param name name of the queue
     * @param idString id of the current joram server
     * @throws Exception if an error occurs
     */
    protected void createQueue(String name, int idString) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("joramClient:type=JoramAdapter,*");
        ObjectName joramAdapterON = (ObjectName) server.queryNames(on, null).iterator().next();

        Object[] params = new Object[] {new Integer(idString), name};
        server.invoke(joramAdapterON, "createQueue", params, new String[] {"int", String.class.getName()});
    }

    /**
     * Create a user in a joram server
     * @param name name of the user
     * @param password password of the user
     * @throws Exception if an error occurs
     */
    protected void createLocalJmsUser(String name, String password) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("joramClient:type=JoramAdapter,*");
        ObjectName joramAdapterON = (ObjectName) server.queryNames(on, null).iterator().next();

        Object[] params = new Object[] {name, password};
        server.invoke(joramAdapterON, "createUser", params, new String[] {"java.lang.String", "java.lang.String"});
    }


    /**
     * Call the main method of a specific class with empty args
     * @param classToLoad name of class which contains the main method
     * @throws Exception if it fails
     */
    protected void callMainMethod(String classToLoad) throws Exception {
        callMainMethod(classToLoad, new String[]{});
    }


    /**
     * Call the main method of a specific class and the specific args
     * @param classToLoad name of class which contains the main method
     * @param args args to give to the main method
     * @throws Exception if it fails
     */
    protected void callMainMethod(String classToLoad, String[] args) throws Exception {
        //Build classloader
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        URL[] urls = new URL[1];
        urls[0] = new File(System.getProperty("jonas.root") + File.separator + "examples" + File.separator + "classes").toURL();
        URLClassLoader loader = new URLClassLoader(urls);
        Thread.currentThread().setContextClassLoader(loader);
        Class clazz = loader.loadClass(classToLoad);
        Class[] argList = new Class[] {args.getClass()};
        Method meth = clazz.getMethod("main", argList);
        Object appli = meth.invoke(null, new Object[]{args});
    }

    /**
     * Get current time
     * @return A String Time with the format yyyy-MM-dd.HH-mm-ss
     */
    protected String getTime() {
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();
        SimpleDateFormat formatter;
        formatter = new SimpleDateFormat("yyyy-MM-dd.HH-mm-ss");
        return formatter.format(date);
    }

    /**
     * Undeploy an EAR
     * @param name String of EAR Name
     * @throws Exception if error occurs
     */
    protected void undeployEar(String name) throws Exception {
        String fileName = name + ".ear";

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        // Disable exception thrown on error status
        HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);

        WebResponse wr = wc.getResponse(getAbsoluteUrl(URL_JONASADMIN_DEPLOYEAR));
        WebForm[] webForms = wr.getForms();
        WebForm webForm = webForms[0];

        String params = webForm.getParameterValue("undeploy");
        WebForm.Scriptable script = webForm.getScriptableObject();

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);

        if (params.length() == 0) {
            params += fileName;
        } else {
            params += "," + fileName;
        }

        script.setParameterValue("undeploy", params);

        WebResponse submitUndeploy = webForm.submit();

        webForms = submitUndeploy.getForms();
        webForm = webForms[0];

        WebResponse endResp = webForm.submit();
    }

    /**
     * Undeploy all EAR
     * @throws Exception if error occurs
     */
    protected void undeployAllEar() throws Exception {
        WebResponse wr = wc.getResponse(getAbsoluteUrl(URL_JONASADMIN_DEPLOYEAR));
        undeployAll(wr);
    }

    /**
     * Undeploy all Jars
     * @throws Exception if error occurs
     */
    protected void undeployAllJar() throws Exception {
        WebResponse wr = wc.getResponse(getAbsoluteUrl(URL_JONASADMIN_DEPLOYJAR));
        undeployAll(wr);
    }

    /**
     * Undeploy all
     * @throws Exception if error occurs
     */
    protected void undeployAll(WebResponse wr) throws Exception {

        WebForm[] webForms = wr.getForms();
        WebForm webForm = webForms[0];

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        // Disable exception thrown on error status
        HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);

        String params = webForm.getParameterValue("deploy");
        WebForm.Scriptable script = webForm.getScriptableObject();

        if (params.length() == 0) {
            params += webForm.getParameterValue("undeploy");
        } else {
            params += "," + webForm.getParameterValue("undeploy");
        }

        script.setParameterValue("undeploy", params);

        WebResponse submitUndeploy = webForm.submit();

        webForms = submitUndeploy.getForms();
        webForm = webForms[0];

        WebResponse endResp = webForm.submit();

        wc.getResponse(getAbsoluteUrl(URL_JONASADMIN));
    }

    /**
     * Verify number of tabs and the selected tab
     * @param tabTable the tab table
     * @param nbTabs number of tabs
     * @param selectedTab the numero of the selected tab
     */
    protected void testTabs(WebTable tabTable, int nbTabs, int selectedTab, String msg) {
        TableCell selectedCell;
        // - number of tabs
        assertEquals("There are not " + nbTabs + " tabs. " + msg,
                nbTabs, (tabTable.getColumnCount() + 1) / 2);
        // - selected tab
        selectedCell = tabTable.getTableCell(1, (selectedTab * 2) - 2);
        assertEquals("It is not the selected tab. ", 1, selectedCell.getElementsWithAttribute("src", "/jonasAdmin/images/dot.gif").length);
    }

    /**
     * Get MBean Server connection
     * @throws Exception if an error occurs
     */
    private void initMBeanServer() throws Exception {
        String sCarolURL = jProp.getRegistryUrl();
        String carolProtocol = jProp.getRegistryProtocol();
        URI carolURL = new URI(sCarolURL);
        int portNb = carolURL.getPort();
        String port = String.valueOf(portNb);
        String url = null;
        Map env = null;
        if (carolProtocol.equals("jrmp")) {
            // Treat JRMP case
            url = "service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jrmpconnector_" + jonasName;
        } else if (carolProtocol.equals("iiop")) {
            // Treat IIOP case
            url = "service:jmx:iiop:///jndi/iiop://localhost:" + port + "/iiopconnector_" + jonasName;
            env = new HashMap();
            if (orb == null) {
                initORB();
            }
            env.put("java.naming.corba.orb", orb);
        } else if (carolProtocol.equals("cmi")) {
            // Treat CMI
            url = "service:jmx:rmi:///jndi/cmi://localhost:" + port + "/cmiconnector_" + jonasName;
        }

        JMXServiceURL connURL = null;
        try {
            connURL = new JMXServiceURL(url);
        } catch (MalformedURLException e) {
            throw new Exception("Can't create JMXServiceURL with string: " + url);
        }

        try {
            connector = JMXConnectorFactory.newJMXConnector(connURL, env);
        } catch (MalformedURLException e1) {
            throw new Exception("there is no provider for the protocol in " + url);
        } catch (java.io.IOException e) {
            throw new Exception("Connector client cannot be made because of a communication problem (used URL: " + url + ")");
        }
        try {
            connector.connect(env);
            currentServerConnection = connector.getMBeanServerConnection();
        } catch (java.io.IOException ioe) {
            throw new Exception("connection could not be made because of a communication problem");
        }
    }

    /**
     * Get MBean Server connection
     * @return a MBeanServer Connection
     * @throws Exception if an error occurs
     */
    protected MBeanServerConnection getMBeanServer() throws Exception {
        return currentServerConnection;
    }

    /**
     * Close MBean Server connection
     * @throws Exception if an error occurs
     */
    protected void closeMBeanServer() throws Exception {

        try {
            if (connector != null) {
                connector.close();
            }
        } catch (Exception e) {
            throw new Exception("connection could not be close because of a communication problem.");
        }
    }

    /**
     * Create an orb for the client
     *
     */
    private static void initORB() {
        orb = ORB.init(new String[0], null);
    }

    /**
     * Tear Down cleanUp action
     * @throws Exception
     */
    public void tearDown() throws Exception {
        // Close MBean Server Connection
        closeMBeanServer();
    }

    /**
     * Print a debug message
     * @param msg The message
     */
    public void debug(String msg) {
        System.out.println("DEBUG: " + msg);
    }

    protected ObjectName getJCAConnectionFactory(String name, String jcaResourceName) {
        ObjectName on = J2eeObjectName.getJCAConnectionFactory(domainName, jcaResourceName, jonasName, name);
        return on;
    }

    protected String getStringMBeanAttribute(ObjectName on, String attName) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        return (String) server.getAttribute(on, attName);
    }

    protected Integer getIntegerMBeanAttribute(ObjectName on, String attName) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        return (Integer) server.getAttribute(on, attName);
    }
}
