Annotation of java/classes/org/w3c/tools/jdbc/ConnectionManager.java, revision 1.5

1.1       bmahe       1: // ConnectionManager.java
1.5     ! ylafon      2: // $Id: ConnectionManager.java,v 1.4 2000/06/16 11:58:45 bmahe Exp $
1.1       bmahe       3: // (c) COPYRIGHT MIT, INRIA and Keio, 2000.
                      4: // Please first read the full copyright statement in file COPYRIGHT.html
                      5: package org.w3c.tools.jdbc;
                      6: 
                      7: import java.sql.SQLException;
                      8: import java.util.Hashtable;
1.3       bmahe       9: import java.util.Properties;
1.1       bmahe      10: 
                     11: import org.w3c.util.LRUList;
                     12: import org.w3c.util.SyncLRUList;
1.3       bmahe      13: import org.w3c.util.PropertyMonitoring;
                     14: import org.w3c.util.ObservableProperties;
1.1       bmahe      15: 
                     16: /**
1.5     ! ylafon     17:  * @version $Revision: 1.4 $
1.1       bmahe      18:  * @author  Beno�t Mah� (bmahe@w3.org)
                     19:  */
1.3       bmahe      20: 
                     21: class ManagerDescription {
                     22:     ConnectionManager manager = null;
                     23:     Properties  properties = null;
                     24:        
                     25:     final ConnectionManager getManager() {
                     26:        return manager;
                     27:     }
                     28:        
                     29:     final boolean sameProperties(Properties props) {
                     30:        return props == properties;
                     31:     }
                     32:        
                     33:     ManagerDescription(ConnectionManager manager, Properties props) {
                     34:        this.manager    = manager;
                     35:        this.properties = props;
                     36:     }
                     37: }
                     38: 
                     39: public class ConnectionManager implements PropertyMonitoring {
1.1       bmahe      40: 
1.5     ! ylafon     41:     public final static boolean debug = false;
1.1       bmahe      42: 
1.4       bmahe      43:     protected int conn_count = 0;
                     44:     protected int conn_max   = 10;
1.3       bmahe      45: 
1.4       bmahe      46:     Properties props = null;
1.3       bmahe      47: 
                     48:     /**
                     49:      * To keep track of existing managers
                     50:      */
                     51:     private static ManagerDescription managers[] = null;
1.1       bmahe      52: 
                     53:     /**
                     54:      * The LRU list of connections.
                     55:      */
                     56:     protected LRUList connectionsLru = null;
                     57: 
                     58:     /**
                     59:      * The cached servers, index is the jdbc URL
                     60:      */
                     61:     protected Hashtable servers = null;
                     62: 
                     63:     /**
1.3       bmahe      64:      * PropertyMonitoring implementation.
                     65:      */
1.4       bmahe      66:     public boolean propertyChanged(String name) {
                     67:        if (name.equals(Jdbc.MAX_CONNECTIONS_P)) {
                     68:           conn_max = Jdbc.getMaxConn(props);
                     69:           return true;
                     70:        }
                     71:        return false;
1.3       bmahe      72:     }
                     73: 
                     74:     /**
1.1       bmahe      75:      * Get a connection to the given server.
                     76:      * @param server the jdbc server.
                     77:      * @return a JdbcConnection or null if there is no connection available.
                     78:      */
                     79:     protected JdbcConnection getConnection(JdbcServer server) {
1.4       bmahe      80:        JdbcServerState ss   = server.getState();
                     81:        JdbcConnection  conn = null;
                     82: 
1.1       bmahe      83:        while ( true ) {
1.4       bmahe      84:            synchronized (this) {
                     85:                while ( true ) {
                     86:                    conn = ss.getConnection();
                     87:                    if ( conn == null )
                     88:                        break;
                     89:                    if (debug) {
                     90:                        System.out.println("Reusing connection. ");
                     91:                    }
                     92:                    if (conn.markUsed())
                     93:                        return conn;
                     94:                }
                     95:                if (negotiateConnection(server)) {
                     96:                    conn = allocateConnection(server);
                     97:                    if ( conn.markUsed() ) {
                     98:                        return conn;
                     99:                    } else {
                    100:                        // Failed to establish a fresh connection !
                    101:                        return null;
                    102:                    }
1.1       bmahe     103:                }
                    104:            }
                    105:            // Wait for a connection to become available:
                    106:            try {
1.2       bmahe     107:                waitForConnection(server);
1.1       bmahe     108:            } catch (InterruptedException ex) {
                    109:            }   
                    110:        }
                    111:     }
                    112: 
                    113:     /**
                    114:      * Connections management - Allocate a new connection for this server.
                    115:      * @param server the JdbcServer
                    116:      * @return a newly created connection or null
                    117:      */
                    118:     protected JdbcConnection allocateConnection(JdbcServer server) {
1.4       bmahe     119:        if (debug) {
                    120:            System.out.println("Allocating new connection to "+server);
                    121:        }
1.2       bmahe     122:        JdbcConnection conn = new JdbcConnection(server);
1.1       bmahe     123:        notifyConnection(conn);
                    124:        return conn;
                    125:     }
                    126: 
                    127:     protected boolean negotiateConnection(JdbcServer server) {
1.4       bmahe     128:        if (conn_count >= conn_max) {
                    129:            // remove the oldest idle Connection
                    130:            JdbcConnection conn = (JdbcConnection) connectionsLru.removeTail();
                    131:            if (conn == null) { // no idle connection
                    132:                return false;
                    133:            } else {
                    134:                if (debug) {
                    135:                    System.out.println("DELETING IDLE CONNECTION!!!");
                    136:                }
                    137:                conn.delete();
                    138:            }
                    139:        }
                    140:        return true;
1.1       bmahe     141:     }
                    142: 
                    143:     protected void deleteConnection(JdbcConnection conn) {
                    144:        JdbcServerState ss = conn.getServer().getState();
                    145:        ss.deleteConnection(conn);
                    146:        synchronized(this) {
                    147:            --conn_count;
                    148:            if (debug)
                    149:                System.out.println("+++ delete conn_count: " + conn_count);
                    150:            notify();
                    151:        }
                    152:     }
                    153:     
                    154:     /**
                    155:      * A new connection has just been created.
                    156:      * @param conn the new connection
                    157:      */
                    158:     protected synchronized void notifyConnection(JdbcConnection conn) {
                    159:        ++conn_count;
                    160:     }
                    161: 
                    162:     /**
                    163:      * The given connection is about to be used.
                    164:      * Update our list of available servers.
                    165:      * @param conn The idle connection.
                    166:      */
                    167:     public void notifyUse(JdbcConnection conn) {
                    168:        if (debug)
                    169:            System.out.println("+++ JdbcConnection used");
                    170:        connectionsLru.remove(conn);
                    171:     }
                    172: 
                    173:     /**
                    174:      * The given connection can be reused, but is now idle.
                    175:      * @param conn The connection that is now idle.
                    176:      */
                    177:     public synchronized void notifyIdle(JdbcConnection conn) {
                    178:        if (debug)
                    179:            System.out.println("+++ JdbcConnection idle");
                    180:        connectionsLru.toHead(conn);
                    181:        JdbcServerState ss = conn.getServer().getState();
                    182:        ss.registerConnection(conn);
                    183:        notify();
                    184:     }
                    185: 
                    186:     /**
                    187:      * Wait for a connection to come up.
                    188:      * @param server, the target server.
                    189:      * @exception InterruptedException If interrupted..
                    190:      */
                    191: 
                    192:     protected synchronized void waitForConnection(JdbcServer server)
                    193:        throws InterruptedException
                    194:     {
                    195:        wait();
                    196:     }
                    197: 
1.3       bmahe     198:     /**
                    199:      * Get an instance of the Jdbc manager.
                    200:      * This method returns an actual instance of the Jdbc manager. It may
                    201:      * return different managers, if it decides to distribute the load on
                    202:      * different managers (avoid the ConnectionManager being a bottleneck).
                    203:      * @return An application wide instance of the Jdbc manager.
                    204:      */
                    205: 
                    206:     public static synchronized ConnectionManager getManager(Properties p) { 
                    207:        if (managers != null) {
                    208:            for (int i = 0 ; i < managers.length ; i++) {
                    209:                if ( managers[i] == null )
                    210:                    continue;
                    211:                if ( managers[i].sameProperties(p) ) {
                    212:                    return managers[i].getManager();
                    213:                }
                    214:            }
                    215:        }
                    216:        ConnectionManager manager = new ConnectionManager(p);
                    217:        if (managers != null) {
                    218:            ManagerDescription nm[]= new ManagerDescription[managers.length+1];
                    219:            System.arraycopy(managers, 0, nm, 0, managers.length);
                    220:            nm[managers.length] = new ManagerDescription(manager, p);
                    221:        } else {
                    222:            managers    = new ManagerDescription[1];
                    223:            managers[0] = new ManagerDescription(manager, p);
                    224:        }
                    225:        return manager;
                    226:     }
                    227: 
                    228:     public static ConnectionManager getManager() {
                    229:        return getManager(System.getProperties());
1.1       bmahe     230:     }
                    231: 
1.3       bmahe     232:     private ConnectionManager(Properties p) {
1.4       bmahe     233:        this.props          = p;
1.3       bmahe     234:        this.connectionsLru = new SyncLRUList();
                    235:        this.servers        = new Hashtable();
1.4       bmahe     236:        if (props instanceof ObservableProperties) {
                    237:            ((ObservableProperties) props).registerObserver(this);
1.3       bmahe     238:        }
1.4       bmahe     239:        int max = Jdbc.getMaxConn(props);
                    240:        this.conn_max = ( max != -1 ? max : this.conn_max);
1.1       bmahe     241:     }
                    242:     
                    243: }

Webmaster