/* Richard A. DeVenezia * SUGI 29 - "Greetings from the Edge" * www.devenezia.com/papers */ import java.util.*; import java.sql.*; import javax.swing.JOptionPane; public class Gateway implements Runnable, GatewayInterface { private boolean end = false; private boolean ready = false; public synchronized void end () { this.end = true; } private Hashtable connections; // handle --> Connection or Statement private Hashtable statements; // handle --> Connection or Statement private Hashtable resultSets; // handle to Statement --> ResultSet private Hashtable resultSetMetaDatas; // handle to Statement --> ResultSetMetaData private int numberOfHandles; java.text.DecimalFormat nf = new java.text.DecimalFormat ("########"); //--------------------------------------------------------------------------- public Gateway (int numberOfHandlesToManage) { this.numberOfHandles = numberOfHandlesToManage; this.connections = new Hashtable (numberOfHandlesToManage); this.statements = new Hashtable (); this.resultSets = new Hashtable (); this.resultSetMetaDatas = new Hashtable (); } //--------------------------------------------------------------------------- private Integer getHandle () { Integer handle; // has to be an object so that it can be used in a Hashtable do { handle = new Integer ( (int) Math.floor (Math.random() * 1e8)); } while ( connections.containsKey (handle) || statements.containsKey(handle) || resultSets.containsKey(handle) ); return handle; } //--------------------------------------------------------------------------- private Object getObjectOfKey(Hashtable H, Object key, boolean clearMessage) throws Exception { Object object = H.get (key); if (object == null) { Thread.currentThread().sleep(500); throw new Exception ("Invalid handle."); } return object; } //--------------------------------------------------------------------------- private Connection getConnectionOfHandle(int handle, boolean clearMessage) throws Exception { Integer key = new Integer(handle); return (Connection) getObjectOfKey (connections, key, clearMessage); } //--------------------------------------------------------------------------- private Statement getStatementOfHandle(int handle, boolean clearMessage) throws Exception { Integer key = new Integer(handle); return (Statement) getObjectOfKey (statements, key, clearMessage); } //--------------------------------------------------------------------------- private ResultSet getResultSetOfHandle(int handle, boolean clearMessage) throws Exception { Integer key = new Integer(handle); return (ResultSet) getObjectOfKey (resultSets, key, clearMessage); } //--------------------------------------------------------------------------- private ResultSetMetaData getResultSetMetaDataOfHandle(int handle, boolean clearMessage) throws Exception { Integer key = new Integer(handle); return (ResultSetMetaData) getObjectOfKey (resultSetMetaDatas, key, clearMessage); } //--------------------------------------------------------------------------- public int getConnectionHandle (String driverClass, String databaseURL, String username, String password) throws Exception { Integer cHandle = getHandle(); Connection con ; if (connections.size() == numberOfHandles) { System.out.println ("No more handles available."); throw new Exception ("No more handles available."); } System.out.println ("loading "+driverClass); Class.forName(driverClass); System.out.println ("connecting to "+databaseURL); con = DriverManager.getConnection (databaseURL, username, password); System.out.println ("connected"); connections.put (cHandle, con); System.out.println ("Connection handle " + nf.format(cHandle) + " is for " + username + " connected to " + databaseURL); return cHandle.intValue(); } //--------------------------------------------------------------------------- public int getStatementHandle (int cHandle, boolean updatable) throws Exception { Integer sHandle = getHandle (); Connection con ; Statement st; con = getConnectionOfHandle (cHandle, true); if (!updatable) st = con.createStatement (); st = con.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); statements.put (sHandle, st); System.out.println ("Statement handle " + nf.format(sHandle) + " ready"); return sHandle.intValue(); } //--------------------------------------------------------------------------- public void closeConnectionHandle (int handle) throws Exception { Integer key = new Integer(handle); Connection con = getConnectionOfHandle (handle, false); for (Enumeration e = statements.keys() ; e.hasMoreElements() ;) { Integer skey = (Integer) e.nextElement(); Statement st = (Statement) statements.get(skey); if (st.getConnection() == con) { closeStatementHandle (skey.intValue()); } } con.close(); connections.remove (key); System.out.println ("Connection handle " + nf.format(handle) + " was closed"); } //--------------------------------------------------------------------------- public void closeStatementHandle (int handle) throws Exception { Integer key = new Integer(handle); Statement st = getStatementOfHandle (handle, false); for (Enumeration e = resultSets.keys() ; e.hasMoreElements() ;) { Integer rkey = (Integer) e.nextElement(); ResultSet rs = (ResultSet) resultSets.get(rkey); if (rs.getStatement() == st) { closeResultSetHandle (rkey.intValue()); } } st.close(); statements.remove (key); System.out.println ("Statement handle " + nf.format(handle) + " was closed"); } //--------------------------------------------------------------------------- public void closeResultSetHandle (int handle) throws Exception { Integer key = new Integer (handle); ResultSet rs = getResultSetOfHandle (handle, false); rs.close(); resultSets.remove (key); resultSetMetaDatas.remove (key); System.out.println ("ResultSet handle " + nf.format(handle) + " was closed"); } //--------------------------------------------------------------------------- public void executeUpdate (int sHandle, String sql) throws Exception { Statement st = getStatementOfHandle (sHandle, true); System.out.println ("handle " + nf.format(sHandle) + " is executing update: " + sql); int rowCount = st.executeUpdate (sql); System.out.println ("handle " + nf.format(sHandle) + " updated " + rowCount + " rows"); } //--------------------------------------------------------------------------- // returns handle to a ResultSet public int executeQuery (int sHandle, String sql) throws Exception { Integer rHandle = getHandle(); Statement st = getStatementOfHandle (sHandle, true); System.out.println ("handle " + nf.format(sHandle) + " is executing query: " + sql); ResultSet rs = st.executeQuery (sql); ResultSetMetaData rsmd = rs.getMetaData(); resultSets.put (rHandle, rs); resultSetMetaDatas.put (rHandle, rsmd); return rHandle.intValue(); } //--------------------------------------------------------------------------- public boolean nextRow (int rHandle) throws Exception { ResultSet rs = getResultSetOfHandle (rHandle, true); return rs.next(); } //--------------------------------------------------------------------------- public double getValue (int rHandle, int colNum) throws Exception { ResultSet rs = getResultSetOfHandle (rHandle, true); return rs.getDouble((int)colNum); } //--------------------------------------------------------------------------- public String getText (int rHandle, int colNum) throws Exception { ResultSet rs = getResultSetOfHandle (rHandle, true); return rs.getString((int)colNum); } //--------------------------------------------------------------------------- public void setValue (int rHandle, int colNum, double value) throws Exception { ResultSet rs = getResultSetOfHandle (rHandle, true); rs.updateDouble((int)colNum, value); } //--------------------------------------------------------------------------- public void setText (int rHandle, int colNum, String text) throws Exception { ResultSet rs = getResultSetOfHandle (rHandle, true); rs.updateString((int)colNum,text); } //--------------------------------------------------------------------------- public void insertRow (int rHandle) throws Exception { ResultSet rs = getResultSetOfHandle (rHandle, true); rs.insertRow(); } //--------------------------------------------------------------------------- public void moveToInsertRow (int rHandle) throws Exception { ResultSet rs = getResultSetOfHandle (rHandle, true); rs.moveToInsertRow(); } //--------------------------------------------------------------------------- public String getColumnName (int rHandle, int colNum) throws Exception { ResultSetMetaData rsmd = getResultSetMetaDataOfHandle (rHandle, true); return rsmd.getColumnName((int)colNum); } //--------------------------------------------------------------------------- public int getColumnType (int rHandle, int colNum) throws Exception { ResultSetMetaData rsmd = getResultSetMetaDataOfHandle (rHandle, true); return rsmd.getColumnType((int)colNum); } //--------------------------------------------------------------------------- public int getColumnCount (int rHandle) throws Exception { ResultSetMetaData rsmd = getResultSetMetaDataOfHandle (rHandle, true); return rsmd.getColumnCount(); } //--------------------------------------------------------------------------- public int getColumnDisplaySize (int rHandle, int colNum) throws Exception { ResultSetMetaData rsmd = getResultSetMetaDataOfHandle (rHandle, true); return rsmd.getColumnDisplaySize((int)colNum); } //--------------------------------------------------------------------------- public void run() { System.out.println ("gateway running"); try { while(!end) { Thread.sleep(50); } } catch (InterruptedException e) {} System.out.println ("run done"); } }