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