001: /*
002: * @(#) SmartPoolFactory 1.0 02/08/01
003: */
004:
005: package org.smartlib.pool.core;
006:
007: import org.apache.log4j.Logger;
008:
009: import java.io.*;
010: import java.sql.*;
011:
012: /**
013: * <tt>SmartPoolFactory</tt> provides a Singleton interface to the
014: * implementation of the PoolManager Interface.
015: * An object of <tt>SmartPoolFactory</tt> should be loaded with the
016: * configuration file prior to calling any static methods on the class.
017: *
018: * Once a object is loaded it maintains a single instance of PoolManager
019: * across all objects and static methods can be directly invoked on the class
020: * without creating any other instance of <tt>SmartPoolFactory<tt>.
021: *
022: * // Creating an instance .
023: * <pre>
024: * SmartPoolFactory = new SmartPoolFactory();
025: * </pre><p>
026: *
027: *
028: * // using <tt>SmartPoolFactory</tt> once it is initialised.
029: * <pre>
030: * Connection conn = SmartPoolFactory.getConnection();
031: * </pre><p>
032: *
033: * It is <b>advisable</b> to load the <tt>SmartPoolFactory</tt> on your
034: * application boot up (start-up-servlet in a web application), so that
035: * it is available for other components from the word go.
036: *
037: * @author Sachin Shekar Shetty
038: * @version 1.0, 02/08/01
039: *
040: */
041:
042: public class SmartPoolFactory {
043:
044: private Logger logger = Logger.getLogger(SmartPoolFactory.class);
045:
046: //static for Singleton
047: private static PoolManager pm = null;
048:
049: private static boolean shutDown = false;
050:
051: private void startPool(File file) throws ConnectionPoolException {
052:
053: // maintaining Singleton
054: if (pm == null)
055: pm = new PoolManagerImpl(file);
056:
057: }
058:
059: /**
060: * This constructor intialises the SmartPoolClass , reads the
061: * configuration from <code>file</code> and loads the PoolManger.
062: *
063: * @param file The configuration file.
064: * @exception ConnectionPoolException if there is any problem
065: * initialising the pools
066: */
067: public SmartPoolFactory(File file) throws ConnectionPoolException {
068:
069: if (pm != null)
070: throw new ConnectionPoolException(
071: "This Class follows a Singleton Pattern. Instance has already been created and initialized.");
072: if (file == null)
073: throw new IllegalArgumentException("file cannot be null");
074: startPool(file);
075:
076: }
077:
078: /**
079: * This constructor intialises the SmartPoolClass , reads the
080: * configuration from system property and loads the PoolManger.
081: *
082: * @exception ConnectionPoolException if there is any problem
083: * initialising the pools
084: */
085: public SmartPoolFactory() throws ConnectionPoolException {
086:
087: String fileName = System
088: .getProperty(PoolConstants.CONFIG_FILE_SYSTEM_PROPERTY);
089: if (logger.isDebugEnabled()) {
090: logger.debug("Config File System Property: " + fileName);
091: }
092:
093: if (pm != null && !shutDown)
094: throw new ConnectionPoolException(
095: "This Class follows a Singleton Pattern. Instance has already been created and is active.");
096: if (fileName == null && fileName.trim().length() != 0)
097: throw new IllegalArgumentException(
098: "System Property:"
099: + PoolConstants.CONFIG_FILE_SYSTEM_PROPERTY
100: + " cannnot be null for this constructor invocation, set it to location of the smart pool config file.");
101:
102: startPool(new File(fileName));
103:
104: }
105:
106: /**
107: * This constructor intialises the SmartPoolClass , reads the
108: * configuration from <code>fileName</code> and loads the PoolManger.
109: *
110: * @param file The absolute configuration file path.
111: * @exception ConnectionPoolException if there is any problem
112: * initialising the pools
113: */
114: public SmartPoolFactory(String fileName)
115: throws ConnectionPoolException {
116:
117: if (pm != null)
118: throw new ConnectionPoolException(
119: "This Class follows a Singleton Pattern. Instance has already been created and initialized.");
120: if (fileName == null || fileName.trim().equals(""))
121: throw new IllegalArgumentException(
122: "filename cannot be null/empty");
123: File file = new File(fileName);
124: startPool(file);
125:
126: }
127:
128: private static void checkAndThrow() throws ConnectionPoolException {
129:
130: if (pm == null)
131: throw new ConnectionPoolException(
132: "PoolManager is not initialised ,"
133: + "Please create an object first with the configuration");
134:
135: }
136:
137: /**
138: * This method returns a Connection from the default connection pool.
139: * The owner of this pool is marked as N/A indicating unknown.
140: *
141: * <b>Note: This method blocks if the pool size has reached it's
142: * maximum size and no free connections are available
143: * until a free connection is available.</b> The time period for which this
144: * method blocks depends on the connection-wait-time-out specified in
145: * the configuration file.
146: *
147: *
148: * @return Connection from the default pool
149: * @exception ConnectionPoolException if there is any problem
150: * getting connection.
151: */
152:
153: public static Connection getConnection()
154: throws ConnectionPoolException {
155:
156: checkAndThrow();
157: return pm.getConnection();
158:
159: }
160:
161: /**
162: * This method returns a Connection from the pool <code>poolName</code>.
163: * The owner of this pool is marked as N/A indicating unknown.
164: *
165: * <b>Note: This method blocks if the pool size has reached it's
166: * maximum size and no free connections are available
167: * until a free connection is available.</b> The time period for which this
168: * method blocks depends on the connection-wait-time-out specified in
169: * the configuration file.
170: *
171: *
172: * @param poolName Name of the pool.
173: * @return Connection from the pool
174: * @exception ConnectionPoolException if there is any problem
175: * getting connection.
176: */
177:
178: public static Connection getConnection(String poolName)
179: throws ConnectionPoolException {
180:
181: checkAndThrow();
182: return pm.getConnection(poolName);
183:
184: }
185:
186: /**
187: * This method returns a Connection from the pool <code>poolName</code>.
188: * The owner of this connection is identified by <code>owner</code> .
189: *
190: * <b>Note: This method blocks if the pool size has reached it's
191: * maximum size and no free connections are available
192: * until a free connection is available.</b> The time period for which this
193: * method blocks depends on the connection-wait-time-out specified in
194: * the configuration file.
195: *
196: *
197: * @param poolName Name of the pool.
198: * @param owner String identifying the owner.
199: * @return Connection from the pool
200: *
201: * @exception ConnectionPoolException if there is any problem
202: * getting connection.
203: */
204:
205: public static Connection getConnection(String poolName, String owner)
206: throws ConnectionPoolException {
207:
208: checkAndThrow();
209: return pm.getConnection(poolName, owner);
210:
211: }
212:
213: /**
214: * This method adds a connection leak listener.The methods of
215: * <code>cle</code> will be called when a leak is detected as per the
216: * pool configuration.
217: *
218: * @param poolName Name of the pool.
219: * @param cle Class implementing ConnectionLeakListener interface.
220: * @exception ConnectionPoolException If there is any problem
221: * adding ConnectionLeakListener.
222: */
223: public static void addConnectionLeakListener(String poolName,
224: ConnectionLeakListener cle) throws ConnectionPoolException {
225:
226: checkAndThrow();
227: pm.addConnectionLeakListener(poolName, cle);
228:
229: }
230:
231: /**
232: * This method removes a connection leak listener.<code>cle</code> will
233: * not get any further notifications.
234: *
235: * @param poolName Name of the pool.
236: * @param cle Class implementing ConnectionLeakListener interface.
237: * @exception ConnectionPoolException if there is any problem
238: * removing ConnectionLeakListener.
239: */
240:
241: public static void removeConnectionLeakListener(String poolName,
242: ConnectionLeakListener cle) throws ConnectionPoolException {
243:
244: checkAndThrow();
245: pm.removeConnectionLeakListener(poolName, cle);
246:
247: }
248:
249: /**
250: * This method returns the instance of PoolMonitor for the pool
251: * <code>poolName</code>
252: *
253: * @param poolName Name of the pool.
254: * @return Instance of PoolMonitor to monitor the state of the pool.
255: * @exception ConnectionPoolException
256: *
257: */
258:
259: public static MultiPoolMonitor getPoolMonitor(String poolName)
260: throws ConnectionPoolException {
261:
262: checkAndThrow();
263: return pm.getMultiPoolMonitor(poolName);
264: }
265:
266: /**
267: * This method shuts down the pool, that is closes all connections to the database,
268: * the pool can no longer be used unless reinitialised using a new SmartPoolFactory instance.
269: */
270: public static void shutDown() {
271: shutDown = true;
272: pm.shutDown();
273: }
274:
275: public static void main(String arg[]) throws Exception {
276:
277: SmartPoolFactory smp = new SmartPoolFactory(
278: "c:\\windows\\desktop\\org.smartlib.pool.test.xml");
279: Connection conn = smp.getConnection();
280:
281: }
282:
283: }
|