package org.openswing.swing.server;
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.rp.database.*;
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Database Connection Manager: it manager database connections, using a free connection pooler.
* This class requires a "pooler.ini" file having the following properties:
* </p>
* <ul>
* <li>"logLevel" - possible values: debug = 4, info = 3, warn = 2, error = 1, fatal = 0
* <li>"driverClass" - JDBC driver class name
* <li>"maxCount" - maximum number of opened connections inside the pooler
* <li>"minCount" - minimum number of opened connections inside the pooler
* <li>"user" - database username
* <li>"password" - database password
* <li>"url" - JDBC database connection URL
* <li>"loginTimeout" - timeout (in seconds) on database login ("0" no timeout)
* <li>"holdTimeout" - timemout (in seconds) on holding opened a connection
* <li>"waitTimeout" - timeout (in milliseconds) on waiting an available connection
* </ul>
* <p>The following are pre-defined:</p>
* <ul>
* <li>"logLevel" = 1
* <li>"maxCount" = 5
* <li>"minCount" = 1
* <li>"loginTimeout" = 0
* <li>"holdTimeout" = 1000
* <li>"waitTimeout" = 10000
* </ul>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
*
* <p> This file is part of OpenSwing Framework.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the (LGPL) Lesser General Public
* License as published by the Free Software Foundation;
*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author may be contacted at:
* maurocarniel@tin.it</p>
*
* @author Mauro Carniel
* @version 1.0
*/
public class PoolerConnectionSource implements ConnectionSource {
/** pooler */
private RPDataSource pool = null;
public PoolerConnectionSource() {
}
/**
* Create a "pooler.ini" file with mandatory parameters only.
* @param driverClass JDBC driver class name
* @param user database username
* @param password database password
* @param url JDBC database connection URL
*/
public final void saveProperties(ServletContext context,String driverClass,String user,String password,String url) {
try {
Properties props = new Properties();
props.setProperty("driverClass", driverClass);
props.setProperty("user", user);
props.setProperty("password", password);
props.setProperty("url", url);
props.save(new FileOutputStream(this.getClass().getResource("/").getPath().replaceAll("%20"," ")+"pooler.ini"), "POOLER PROPERTIES");
}
catch (Throwable ex) {
context.log("Error while creating connection pooler",ex);
}
}
/**
* Initialize the connection pooler.
* Called by ConnectionManager.initConnectionSource method.
* @param context servlet context; used to retrieve database connection settings
*/
public boolean initPooler(HttpServlet servlet) {
try {
// load file "pooler.ini" config properties
Properties props = new Properties();
props.load(new FileInputStream(this.getClass().getResource("/").getPath().replaceAll("%20"," ")+"pooler.ini"));
if (props.getProperty("logLevel")==null || props.getProperty("logLevel").equals(""))
props.setProperty("logLevel","1");
props.setProperty("autoCommit", "false");
if (props.getProperty("maxCount")==null || props.getProperty("maxCount").equals(""))
props.setProperty("maxCount","50");
if (props.getProperty("minCount")==null || props.getProperty("minCount").equals(""))
props.setProperty("minCount","1");
if (props.getProperty("loginTimeout")==null || props.getProperty("loginTimeout").equals(""))
props.setProperty("loginTimeout","0");
if (props.getProperty("holdTimeout")==null || props.getProperty("holdTimeout").equals(""))
props.setProperty("holdTimeout","1000");
if (props.getProperty("waitTimeout")==null || props.getProperty("waitTimeout").equals(""))
props.setProperty("waitTimeout","10000");
props.setProperty("statementCacheSize", "10");
//p = new RPDataSource(p, log); //use this instead of the next line to turn on logging
pool = new RPDataSource(props);
return true;
}
catch (FileNotFoundException ex) {
try {
if ("true".equals(servlet.getInitParameter("suppressInitPoolerError")))
return false;
}
catch (Exception exx) {}
ex.printStackTrace();
servlet.getServletContext().log("Error while creating connection pooler: file not found in\n"+new File("pooler.ini").getAbsolutePath(),ex);
return false;
}
catch (Throwable ex) {
ex.printStackTrace();
servlet.getServletContext().log("Error while creating connection pooler",ex);
return false;
}
}
/**
* @param context servlet context; used to retrieve database connection settings
* @return new database connection
*/
public Connection getConnection(ServletContext context) throws Exception {
Connection conn = pool.getConnection();
try { conn.setTransactionIsolation(java.sql.Connection.TRANSACTION_READ_COMMITTED); } catch (Exception ex) {}
conn.setAutoCommit(false);
return conn;
}
/**
* Release a database connection
* @param conn database connection to release
* @param context servlet context; used to retrieve database connection settings
*/
public void releaseConnection(Connection conn,ServletContext context) {
try {
conn.rollback();
conn.close();
}
catch (SQLException ex) {
context.log("Error while releasing the database connection",ex);
}
}
}