/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 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
 *
 * Initial developer(s): ____________________________________.
 * Contributor(s): Marc Dutoo, 
 * JOnAS 2.4 Murad Meghani (Murad.Meghani@compuware.com) killServer and stopServer
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */


package org.objectweb.jonas.adm;

import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NameClassPair;
import org.objectweb.common.RemoteObject;
import org.objectweb.common.Env;
import org.objectweb.jonas.common.JProp;
import org.objectweb.jonas.common.Log;
import org.objectweb.jonas.container.EJBServiceImpl;
import org.objectweb.jonas.jtm.TransactionServiceImpl;
import org.objectweb.jonas.naming.CompNamingContext;
import org.objectweb.jonas.naming.NamingManager;
import org.objectweb.jonas.registry.RegistryManager;
import org.objectweb.jonas.service.Service;
import org.objectweb.jonas.service.ServiceException;
import org.objectweb.jonas.service.ServiceManager;
import org.objectweb.jonas_ejb.container.Container;


/**
 * This class implements a remote interface used for administering
 *      the server.
 * @author Philippe Coq, Philippe Durieux
 * Contributor(s): Marc Dutoo, 
 * JOnAS 2.4 Murad Meghani (Murad.Meghani@compuware.com) killServer and stopServer
 * 
 */
public class Adm extends RemoteObject implements AdmInterface {

    public static final String ADMNAME_SUFFIX = "_Adm";

    private ServiceManager sm = null;
    private EJBServiceImpl ejbserv  = null;
    private TransactionServiceImpl tm = null;
    private JProp jonasProperties = null;
    private InitialContext ictx = null;
    private boolean isNotEJB = false;   // = true if TMServer or Tomcat standalone

    /**
     * Adm constructor
     */
    public Adm(JProp jp, boolean isNotEJB) throws RemoteException, NamingException, ServiceException {

	jonasProperties = jp;
	this.isNotEJB = isNotEJB;

	// Get Service references
	sm = ServiceManager.getInstance();
	if (isNotEJB == false) {
	    ejbserv = (EJBServiceImpl) sm.getEjbService();
	}
        try{
            tm = (TransactionServiceImpl) sm.getTransactionService();
        }catch(ServiceException e){
        }

	// Get an Initial Context and
	// registers the JOnAS Server Name to JNDI
	String name = null;
        name = jonasProperties.getValue("jonas.name", "jonas") + ADMNAME_SUFFIX;
	try {
	    if (Env.isDavid()) 
		ictx = NamingManager.getInstance().getCorbaInitialContext();
	    else
		ictx = NamingManager.getInstance().getInitialContext();

	    ictx.bind(name, this);
        } catch (NameAlreadyBoundException e) {
	    throw e;
	} catch (NamingException e) {
	    throw e;
	}
    }

    // ------------------------------------------------------------------
    //  AdmInterface implementation
    // ------------------------------------------------------------------

    /**
     * get Topics. 
     * Assumes that all Loggers are TopicalLoggers.
     * TODO : put part common with JAdmin in Log
     */
    public String [] getTopics() throws RemoteException {
	return Log.getInstance().getTopics();
    }

    /**
     * get Topic Level
     * TODO : put part common with JAdmin in Log
     */
    public String getTopicLevel(String topic) throws RemoteException {
	return Log.getInstance().getTopicLevel(topic);
    }

    /**
     * set Topic Level
     * TODO : put part common with JAdmin in Log
     */
    public void setTopicLevel(String topic, String l) throws RemoteException {
	Log.getInstance().setTopicLevel(topic, l);
    }
	
    /**
     * Create a container and load beans in it
     * @parameter fileName name of the ejb-jar or xml file
     */
    public void addBeans(String fileName) throws RemoteException {
	if (isNotEJB) return;
	ejbserv.createContainer(fileName);
    }

    /**
     * Remove the container identified by fileName and remove all beans in it
     * @parameter fileName name of the ejb-jar or xml file 
     */
    public void removeBeans(String fileName) throws RemoteException {
	if (isNotEJB) return;
	ejbserv.removeContainer(fileName);
    }

    /**
     * returns true if beans are already loaded in server.
     * @parameter fileName name of the ejb-jar or xml file
     */
    public boolean isLoaded(String fileName) throws RemoteException {
	return (ejbserv.getContainer(fileName) != null);
    }
	
    /**
     * List beans of all JOnAS containers
     */
    public String [] listBeans() throws RemoteException {

	if (isNotEJB) return new String[0];

	Container[] lcont = ejbserv.listContainers();
	Vector lbeans = new Vector();
	for( int j = 0; j<lcont.length; j++) {
	    String[] lbn = lcont[j].listBeanNames();
	    String contname = lcont[j].getName();
	    for( int k = 0; k<lbn.length; k++){
		String s = new String(contname + ": " + lbn[k]);
		lbeans.addElement(s);
	    } 
	}
	String[] ret = new String[lbeans.size()];
	lbeans.copyInto(ret);

	return ret;
    }

    /**
     * List JNDI context
     */
    public Vector listContext() throws RemoteException {
	String name = null;
	Vector ret  = new Vector();
	try {
	    NamingEnumeration ne;

	    if (Env.isDavid()) {
		// list CosNaming and rmiregistry
		ne = NamingManager.getInstance().getCorbaInitialContext().list("");
		for (Enumeration e = ne; e.hasMoreElements(); ) {
		    name = ((NameClassPair) e.nextElement()).getName();
		ret.addElement(name);
		}
	    }

	    ne = NamingManager.getInstance().getInitialContext().list("");
	    for (Enumeration e = ne; e.hasMoreElements(); ) {
		name = ((NameClassPair) e.nextElement()).getName();
		ret.addElement(name);
	    }
	} catch (Exception ex) {
	    throw new RemoteException("Cannot list JNDI context", ex);
	}
	return ret;
    }

    /**
     * List Environment
     */
    public Properties listEnv() {
	return jonasProperties.getFilesEnv();
    }

    /**
     * Stop the Server without stopping the JVM
     */
    public void stopServer() throws RemoteException {
	try {
	    sm.stopServices();
	} catch (ServiceException e) {
	    throw new RemoteException("Cannot stop services: ", e);
	}

    }
 

    /**
     * Stop  the Server and  stop the JVM
     */
    public void killServer() throws RemoteException {
	stopServer();
	System.exit(0);
    }


    /**
     * To test if an Adm is reachable
     */
    public boolean ping() throws RemoteException {
	return isNotEJB;
    }

    /**
     * set the default value for transaction timeout
     */
    public void setTransactionTimeout(int timeout) throws RemoteException {
        if(tm != null)
            tm.setCurrentTimeOut(new Integer(timeout));
    }

    /**
     * run the garbage collector
     */
    public void runGC() throws RemoteException {
	Runtime.getRuntime().gc();
    }
    
    /**
     * sync all entity instances outside transactions
     */
    public void syncAllEntities() throws RemoteException {
	if (isNotEJB) return;
	ejbserv.syncAllEntities();
    }
}

 

