/*
* jPOS Project [http://jpos.org]
* Copyright (C) 2000-2017 jPOS Software SRL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jpos.tpl;
import org.jpos.core.Configurable;
import org.jpos.core.Configuration;
import org.jpos.core.ConfigurationException;
import org.jpos.util.LogEvent;
import org.jpos.util.LogSource;
import org.jpos.util.Logger;
import java.sql.*;
/**
* DataSource implementation used by PersistentPeer implementations
* @author <a href="mailto:apr@cs.com.uy">Alejandro P. Revilla</a>
* @version $Id$
*/
public class PersistentEngine implements LogSource, Configurable {
Configuration cfg;
Logger logger;
String realm;
/**
* @param cfg Configuration
* @param logger logger
* @param realm logger's realm
* @throws ConfigurationException
*/
public PersistentEngine (Configuration cfg, Logger logger, String realm)
throws ConfigurationException
{
super();
this.cfg = cfg;
this.logger = logger;
this.realm = realm;
initEngine ();
}
/**
* no args constructor
*/
public PersistentEngine () {
super();
}
/**
* Implements Configurable
* @param cfg Configuration
* @throws ConfigurationException
*/
public void setConfiguration (Configuration cfg)
throws ConfigurationException
{
this.cfg = cfg;
initEngine();
}
private void initEngine () throws ConfigurationException {
initJDBC();
}
private void initJDBC() throws ConfigurationException {
try {
Class.forName(cfg.get("jdbc.driver")).newInstance();
} catch (Exception e) {
throw new ConfigurationException (e);
}
}
public synchronized Connection getConnection() {
for (;;) {
try {
String url = cfg.get ("jdbc.url");
String user = cfg.get ("jdbc.user");
String pass = cfg.get ("jdbc.password");
return DriverManager.getConnection(url,user,pass);
} catch (SQLException e) {
Logger.log (new LogEvent(this, "sql-connection", e));
try {
Thread.sleep (2000);
} catch (InterruptedException ex) { }
}
}
}
public void releaseConnection (Connection conn) {
// Connection pooling hook
try {
conn.close();
} catch (SQLException e) {
Logger.log (new LogEvent(this, "sql-release-connection", e));
}
}
public void setLogger (Logger logger, String realm) {
this.logger = logger;
this.realm = realm;
}
public String getRealm () {
return realm;
}
public Logger getLogger() {
return logger;
}
/**
* finds a peer for this object
* @param obj Main object
* @throws NoPeerException
*/
public PersistentPeer getPeer (Object obj) throws NoPeerException {
if (obj instanceof PersistentPeer)
return (PersistentPeer) obj;
else {
try {
Class c = Class.forName (obj.getClass().getName()+"Peer");
return (PersistentPeer) c.newInstance();
} catch (Exception e) {
throw new NoPeerException (e.toString());
}
}
}
/**
* Execute SQL Update
* @param sql sql command
* @exception SQLException
*/
public void executeUpdate (String sql) throws SQLException {
Connection conn = getConnection();
try {
executeUpdate (sql, conn);
} finally {
releaseConnection (conn);
}
}
/**
* Execute SQL Update
* @param sql sql command
* @param conn sql connection
* @exception SQLException
*/
public void executeUpdate (String sql, Connection conn)
throws SQLException
{
Statement s = null;
try {
s = conn.createStatement();
if (logger != null && logger.hasListeners())
Logger.log (new LogEvent (this, "sql-update", sql));
s.executeUpdate (sql);
} finally {
if (s != null)
s.close();
}
}
/**
* Execute SQL Query.
* @param sql sql command
* @param conn sql connection
* @return ResultSet (please close() it after using - thanks)
* @exception SQLException
*/
public ResultSet executeQuery (String sql, Connection conn)
throws SQLException
{
Statement s = null;
ResultSet rs;
s = conn.createStatement();
if (logger != null && logger.hasListeners())
Logger.log (new LogEvent (this, "sql-query", sql));
return s.executeQuery (sql);
}
/**
* creates a new persistent object
* @param o object to create
* @throws NoPeerException
* @throws SQLException
*/
public void create (Object o)
throws NoPeerException, SQLException
{
PersistentPeer peer = getPeer(o);
peer.setPersistentEngine (this);
peer.create (o);
}
/**
* load object from persistent storage
* @param o object to load
* @throws NoPeerException
* @throws SQLException
*/
public void load (Object o)
throws NoPeerException, SQLException, NotFoundException
{
PersistentPeer peer = getPeer(o);
peer.setPersistentEngine (this);
peer.load (o);
}
/**
* remove object from persistent storage
* @param o object to load
* @throws NoPeerException
* @throws SQLException
*/
public void remove (Object o)
throws NoPeerException, SQLException, NotFoundException
{
PersistentPeer peer = getPeer(o);
peer.setPersistentEngine (this);
peer.remove (o);
}
/**
* update object to persistent storage
* @param o object to load
* @throws NoPeerException
* @throws SQLException
*/
public void update (Object o)
throws NoPeerException, SQLException, NotFoundException
{
PersistentPeer peer = getPeer(o);
peer.setPersistentEngine (this);
peer.update(o);
}
public long getOID (Connection conn) throws SQLException {
String sql = "SELECT last_insert_id()";
ResultSet rs = executeQuery (sql, conn);
if (rs.isBeforeFirst())
rs.next();
long oid = rs.getLong (1);
rs.close();
return oid;
}
}