001: // JdbcServer.java
002: // $Id: JdbcServer.java,v 1.29 2001/03/13 14:10:03 ylafon Exp $
003: // (c) COPYRIGHT MIT, INRIA and Keio, 2000.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005: package org.w3c.tools.jdbc;
006:
007: import java.sql.DatabaseMetaData;
008: import java.sql.SQLException;
009: import java.sql.ResultSet;
010: import java.util.Vector;
011: import java.util.HashMap;
012: import java.util.Properties;
013:
014: /**
015: * @version $Revision: 1.29 $
016: * @author Benoît Mahé (bmahe@w3.org)
017: */
018: public class JdbcServer {
019:
020: public static final boolean debug = false;
021:
022: String uri = null;
023: String user = null;
024: String password = null;
025:
026: /**
027: * Our connection manager.
028: */
029: ConnectionManager manager = null;
030:
031: /**
032: * Our server state
033: */
034: JdbcServerState state = null;
035:
036: /**
037: * The cached servers, index is the jdbc URI
038: */
039: protected static HashMap servers = new HashMap();
040:
041: /**
042: * the drivers loaded
043: */
044: protected static Vector drivers = new Vector();
045:
046: /**
047: * Default properties
048: */
049: protected static Properties defaultProps = new Properties();
050:
051: /**
052: * Get our server state (used to store things)
053: * @return a JdbcServerState instance.
054: */
055: protected final JdbcServerState getState() {
056: return state;
057: }
058:
059: /**
060: * Get the Server object from the cache, if it is not present, try
061: * to create one. A driver must have been selected.
062: * @param uri the jdbc URI of the DB server
063: * @param user the user name
064: * @param password the password
065: * @return an instance of JdbcServer
066: */
067: public static JdbcServer getServer(String uri, String user,
068: String password) {
069: return getServer(uri, user, password, null, System
070: .getProperties());
071: }
072:
073: /**
074: * Get the Server object from the cache, if it is not present, try
075: * to create one.
076: * @param uri the jdbc URI of the DB server
077: * @param props the Jdbc properties
078: * @return an instance of JdbcServer
079: */
080: public static JdbcServer getServer(String uri, Properties props) {
081: return getServer(uri, Jdbc.getUser(props), Jdbc
082: .getPassword(props), Jdbc.getDriver(props), props);
083: }
084:
085: /**
086: * Get the Server object from the cache, if it is not present, try
087: * to create one.
088: * @param uri the jdbc URI of the DB server
089: * @param user the user name
090: * @param password the password
091: * @param driver the JDBC driver name
092: * @return an instance of JdbcServer
093: */
094: public static JdbcServer getServer(String uri, String user,
095: String password, String driver) {
096: return getServer(uri, user, password, driver, defaultProps);
097: }
098:
099: /**
100: * Get the Server object from the cache, if it is not present, try
101: * to create one.
102: * @param uri the jdbc URI of the DB server
103: * @param user the user name
104: * @param password the password
105: * @param driver the JDBC driver name
106: * @param props the Jdbc properties
107: * @return an instance of JdbcServer
108: */
109: public static JdbcServer getServer(String uri, String user,
110: String password, String driver, Properties props) {
111: // register the driver
112: if (drivers == null)
113: drivers = new Vector(4);
114:
115: if ((driver != null) && (!drivers.contains(driver))) {
116: try {
117: Class.forName(driver);
118: } catch (Exception ex) {
119: ex.printStackTrace();
120: }
121: drivers.addElement(driver);
122: }
123:
124: String key = null;
125: if (user != null) {
126: key = uri + "?" + user;
127: } else {
128: key = uri;
129: }
130: JdbcServer server = null;
131: server = (JdbcServer) servers.get(key);
132:
133: if (server != null) {
134: server.updateProperties(props);
135: return server;
136: }
137: // no cached server
138: ConnectionManager manager = ConnectionManager.getManager(props);
139: server = new JdbcServer(uri, user, password, manager);
140: servers.put(key, server);
141: return server;
142: }
143:
144: protected void updateProperties(Properties props) {
145: this .manager = ConnectionManager.getManager(props);
146: }
147:
148: /**
149: * Unregister a connection from the idle list.
150: * Unregistering a connection means that the server shouldn't keep
151: * track of it any more. This can happen in two situations:
152: * <ul>
153: * <li>The connection won't be reusable, so there is no point
154: * for the server to try to keep track of it. In this case, the
155: * connection is forgotten, and the caller will terminate it by invoking
156: * the connection's input stream close method.
157: * <li>The connection has successfully handle a connection, and the
158: * connection is about to be reused. During the time of the request
159: * processing, the server looses track of this connection, which will
160: * register itself again when back to idle.
161: * @param conn The connection to unregister from the idle list.
162: */
163: public synchronized void unregisterConnection(JdbcConnection conn) {
164: manager.notifyUse(conn);
165: }
166:
167: public void deleteConnection(JdbcConnection conn) {
168: manager.deleteConnection(conn);
169: }
170:
171: public ResultSet runRequest(String command, boolean close)
172: throws SQLException {
173: return runQuery(command, close);
174: }
175:
176: public ResultSet runQuery(String command, boolean close)
177: throws SQLException {
178: if (debug) {
179: System.err.println(">>> " + command);
180: }
181:
182: ResultSet reply = null;
183: JdbcConnection conn = null;
184:
185: // Allocate a connection and run the request:
186: int maxretry = 3;
187: boolean closed = close;
188: for (int i = 0; (reply == null) && (i < maxretry); i++) {
189: if ((conn = manager.getConnection(this )) == null)
190: continue;
191: try {
192: reply = conn.performQuery(command);
193: } catch (SQLException ex) {
194: if (debug) {
195: ex.printStackTrace();
196: }
197: closed = true;
198: throw ex;
199: } finally {
200: if (closed) {
201: conn.delete();
202: } else {
203: manager.notifyIdle(conn);
204: }
205: }
206: }
207: if (conn == null) {
208: throw new SQLException("Can't connect to database");
209: }
210: return reply;
211: }
212:
213: public int runUpdate(String command, boolean close)
214: throws SQLException {
215: if (debug) {
216: System.err.println(">>> " + command);
217: }
218:
219: int reply = -1;
220: JdbcConnection conn = null;
221:
222: // Allocate a connection and run the request:
223: int maxretry = 3;
224: for (int i = 0; (reply == -1) && (i < maxretry); i++) {
225: if ((conn = manager.getConnection(this )) == null)
226: continue;
227: try {
228: reply = conn.performUpdate(command);
229: } catch (SQLException ex) {
230: if (debug) {
231: ex.printStackTrace();
232: System.err.println(">>> STATE : "
233: + ex.getSQLState());
234: System.err.println(">>> code : "
235: + ex.getErrorCode());
236: }
237: close = true;
238: throw ex;
239: } finally {
240: if (close) {
241: conn.delete();
242: } else {
243: manager.notifyIdle(conn);
244: }
245: }
246: }
247: if (conn == null) {
248: throw new SQLException("Can't connect to database");
249: }
250: return reply;
251: }
252:
253: /**
254: * Get the MetaData of the tables.
255: * @return a DatabaseMetaData instance
256: */
257: public DatabaseMetaData getMetaData() throws SQLException {
258: DatabaseMetaData reply = null;
259: JdbcConnection conn = null;
260:
261: // Allocate a connection and run the request:
262: int maxretry = 3;
263: for (int i = 0; (reply == null) && (i < maxretry); i++) {
264: if ((conn = manager.getConnection(this )) == null)
265: continue;
266: try {
267: reply = conn.getMetaData();
268: } finally {
269: manager.notifyIdle(conn);
270: }
271: }
272: if (conn == null) {
273: throw new SQLException("Can't connect to database");
274: }
275: return reply;
276: }
277:
278: public String toString() {
279: return uri;
280: }
281:
282: /**
283: * Constructor
284: * @param uri the jdbc URI of the DB server
285: * @param user the user name
286: * @param password the password
287: * @param manager the connection manager
288: */
289: protected JdbcServer(String uri, String user, String password,
290: ConnectionManager manager) {
291: this .uri = uri;
292: this .user = user;
293: this .password = password;
294: this .state = new JdbcServerState(this);
295: this.manager = manager;
296: }
297:
298: }
|