/*
 * 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
 * 
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */


package org.objectweb.jonas.dbm;

import java.io.PrintWriter;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import javax.sql.XADataSource;
import org.objectweb.jonas.common.Log;
import org.objectweb.jonas.jtm.TransactionService;
import org.objectweb.jonas.service.ServiceManager;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;

/**
 * @author Philippe Durieux
 * Contributor(s): 
 */
public class DataSourceFactory implements ObjectFactory {

    static private Logger logger = null;

    public Object getObjectInstance(Object refObj, Name name, Context nameCtx, Hashtable env) throws Exception {

	Reference ref = (Reference) refObj;
	String clname = ref.getClassName();
        if (logger == null) {
            logger = Log.getLogger(Log.JONAS_DBM_PREFIX);
        }
	logger.log(BasicLevel.DEBUG, "entering for "+clname);

	// Old fashioned Connection Manager
	if (clname.equals("org.objectweb.jonas.dbm.ConnectionManager")) {
	    String dsname = (String)ref.get("datasource.name").getContent();
	    ConnectionManager ds = ConnectionManager.getConnectionManager(dsname);
	    if (ds == null) {
		// The DataSource was not in this EJBServer: Create it.
		logger.log(BasicLevel.DEBUG, "Creating a new Connection Manager for "+dsname);
		try {
		    ds = new ConnectionManager();
		    ds.setDataSourceName(dsname);
		    ds.setUrl((String)ref.get("datasource.url").getContent());
		    ds.setClassName((String)ref.get("datasource.classname").getContent());
		    ds.setUserName((String)ref.get("datasource.username").getContent());
		    ds.setPassword((String)ref.get("datasource.password").getContent());
		    ds.setTransactionIsolation((String)ref.get("datasource.isolationlevel").getContent());
		    ds.poolConfigure((String)ref.get("connchecklevel").getContent(),
				     (String)ref.get("connmaxage").getContent(),
				     (String)ref.get("connteststmt").getContent());
		} catch (Exception e) {
		    logger.log(BasicLevel.ERROR, "DataSourceFactory error: "+e);
		}
	    } else {
		// The DataSource is already in this EJBServer: Just return it.
		logger.log(BasicLevel.DEBUG, "return the matching ConnectionManager");
	    }
	    return ds;
	}

	// New style JonasXAPoolDataSource
	if (clname.equals("org.objectweb.jonas.dbm.JonasXAPoolDataSource")) {
	    String dsname = (String)ref.get("dataSourceName").getContent();
	    JonasXAPoolDataSource ds = (JonasXAPoolDataSource)DataBaseServiceImpl.getXAPoolDataSource(dsname);
	    if (ds == null) {
		//This part does not work for the moment : TBD

		// The DataSource was not in this EJBServer: Create it.
		ds = new JonasXAPoolDataSource();
                boolean debug = logger.isLoggable(BasicLevel.DEBUG);
		ds.setDebug(debug);
		if (debug) {
		    ds.setLogWriter(Log.getLogWriter("org.objectweb.jonas.dbm"));
		}

		ds.setCheckLevelObject(Integer.parseInt((String)ref.get("checkLevelObject").getContent()));
		ds.setJdbcTestStmt((String)ref.get("jdbcTestStmt").getContent());
		ds.setLifeTime(Integer.parseInt((String)ref.get("lifeTime").getContent()));
		ds.setMaxSize(Integer.parseInt((String)ref.get("maxSize").getContent()));
		ds.setMinSize(Integer.parseInt((String)ref.get("minSize").getContent()));
		ds.setDataSourceName((String)ref.get("dataSourceName").getContent());
		TransactionService ts =
		    (TransactionService) ServiceManager.getInstance().getTransactionService();
		ds.setTransactionManager(ts.getTransactionManager());
		ds.setXAFactory((String)ref.get("XAFactory").getContent());
		try {
		    CommonDataSource connect = null;
		    Context ictx;
		    ictx =  new InitialContext();	// get the initial context
		    connect = (CommonDataSource)ictx.lookup(ds.getDataSourceName());
		    connect.setTransactionManager(ts.getTransactionManager());
		    ds.xads = (XADataSource)connect;
		} catch(javax.naming.NamingException e) {
		    logger.log(BasicLevel.ERROR, "Error javax.naming.NamingException in DataSourceFactory:getObjectInstance");
		}

		logger.log(BasicLevel.DEBUG, "return a new ConnectionManager");
	    } else {
		// The DataSource is already in this EJBServer: Just return it.
		logger.log(BasicLevel.DEBUG, "return the matching ConnectionManager");
	    }
	    return ds;
	}
	logger.log(BasicLevel.ERROR, "no object found for "+clname);
	return null;
    }
}
