/*-----------------------------------------------------------------------------
 *
 * Enhydra JdbcS
 * The Initial Developer of the Original Code is Lutris Technologies Inc.
 * Portions created by Lutris are Copyright 1997-2000 Lutris Technologies Inc.
 * All Rights Reserved.
 *
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * www.enhydra.org/license/epl.html
 *
 * Software distributed under the License is distributed on an "ASIS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * -----------------------------------------------------------------------------
 * $Id$
 * -----------------------------------------------------------------------------
 */
package org.enhydra.jdbc.core;

import java.io.Serializable;
import java.io.PrintWriter;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;

/**
 * Provides a Data Source which can be used to generate JDBC connections.
 * <P>
 * This class is generic in the sense that it does not rely upon anything other
 * than standard Java APIs. It uses java.sql.DriverManager and preconfigured
 * properties to construct a JDBC connection.
 */
public class CoreDataSource implements Referenceable, ObjectFactory, Serializable {

    // Standard Data Source properties
    private int		loginTimeout;		// timeout for database logins
    transient public  PrintWriter logWriter;		// the log writer
    public  String	user;			// user for the database
    public  String	password;		// password for the database
    private String	description;		// description of the datasource
    private boolean	debug;			// debug flag
    private boolean	verbose;		// verbose flag
    private JdbcThreadFactory threadFactory;    // thread factory

    /**
     * Constructor
     */
    public CoreDataSource() {
	loginTimeout = 60;		// Default value for loginTimeout
	logWriter = null;
	user      = null;
	password  = null;
	description = null;
	debug     = false;
	verbose   = false;
	threadFactory = null;
	log("CoreDataSource is created");
    } // Constructors

    /**
     * Setter/Getter defined for standard properties
     */
    public String getDescription() 		{return description;}
    public String getPassword()			{return password;}
    public String getUser()			{return user;}
    public JdbcThreadFactory getThreadFactory() {
	return threadFactory;
    }
    public boolean isDebug() 			{return debug;}
    public boolean isVerbose() 			{return verbose;}

    public void setDescription (String description) 	{this.description = description;}
    public void setPassword (String password) 		{this.password = password;}
    public void setUser (String user) 			{this.user = user;}
    public void setDebug(boolean debug) 		{this.debug = debug;}
    public void setVerbose(boolean verbose) 		{this.verbose = verbose;}
    public void setThreadFactory(JdbcThreadFactory f) {
	this.threadFactory = f;
    }

    public PrintWriter getLogWriter() {
	return logWriter;		// return the log writer
    } // method getLogWriter

    public void setLogWriter(PrintWriter out) {
	this.logWriter = out;
    } //method setLogWriter

    /**
     * shutdown is a placeholder for datasources which should shut down
     * any pools which they maintain.
     */
    public void shutdown(boolean force) {
    }

    /**
     * Outputs a log message to the log writer.
     */
    public void log (String msg) {
	if (isDebug()) {
	    if (logWriter == null) return;	// check for no logging
	    logWriter.println(msg);
	}
    } // method log

    public void setLoginTimeout(int seconds) {
	loginTimeout = seconds;
    } // method setLoginTimeout


    public int getLoginTimeout() {
	return loginTimeout;
    } // method getLoginTimeout

    /**
     * Methods inherited from referenceable
     */
    public Reference getReference() throws NamingException {
	// Note that we use getClass().getName() to provide the factory
	// class name. It is assumed that this class, and all of its
	// descendants are their own factories.

	Reference ref = new Reference(getClass().getName(), getClass().getName(), null);
	ref.add(new StringRefAddr("user", getUser()));
	ref.add(new StringRefAddr("password", getPassword()));
	ref.add(new StringRefAddr("description", getDescription()));
	ref.add(new StringRefAddr("loginTimeout", Integer.toString(getLoginTimeout())));
	log("CoreDataSource:getReference object returned");
	return ref;
    } // method getReference

    /**
     * Methods inherited from ObjectFactory
     */
    public Object getObjectInstance(Object refObj, Name name, Context nameCtx, Hashtable env) throws Exception {
	Reference ref = (Reference)refObj;

	this.setUser((String)ref.get("user").getContent());
	this.setPassword((String)ref.get("password").getContent());
	this.setDescription((String)ref.get("description").getContent());
	this.setLoginTimeout(Integer.parseInt((String)ref.get("loginTimeout").getContent()));
	log("CoreDataSource:getObjectInstance instance created");
	return this;
    } // method getObjectInstance

} // class CoreDataSource
