001: /**
002: * Copyright (C) 2001 Yasna.com. All rights reserved.
003: *
004: * ===================================================================
005: * The Apache Software License, Version 1.1
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution,
020: * if any, must include the following acknowledgment:
021: * "This product includes software developed by
022: * Yasna.com (http://www.yasna.com)."
023: * Alternately, this acknowledgment may appear in the software itself,
024: * if and wherever such third-party acknowledgments normally appear.
025: *
026: * 4. The names "Yazd" and "Yasna.com" must not be used to
027: * endorse or promote products derived from this software without
028: * prior written permission. For written permission, please
029: * contact yazd@yasna.com.
030: *
031: * 5. Products derived from this software may not be called "Yazd",
032: * nor may "Yazd" appear in their name, without prior written
033: * permission of Yasna.com.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL YASNA.COM OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of Yasna.com. For more information
051: * on Yasna.com, please see <http://www.yasna.com>.
052: */package com.Yasna.forum.database;
053:
054: import java.sql.*;
055: import com.Yasna.forum.*;
056:
057: import javax.sql.DataSource;
058: import javax.naming.InitialContext;
059:
060: /**
061: * Central manager of database connections. All methods are static so that they
062: * can be easily accessed throughout the classes in the database package.
063: */
064: public class DbConnectionManager {
065:
066: private static DbConnectionProvider connectionProvider;
067: private static Object providerLock = new Object();
068: private static boolean AppServerPooler = false;
069: private static boolean checkedPooler = false;
070: private static DataSource appServerSource;
071: public static final String CONTEXT_JDBC_NAME = SystemProperty
072: .getProperty("JNDI.dataprovider");
073:
074: /**
075: * Returns a database connection from the currently active connection
076: * provider.
077: */
078: public static Connection getConnection() {
079: Connection con = null;
080: if (appServerSource == null && !checkedPooler) {
081: checkedPooler = true;
082: try {
083: InitialContext ctxt = new InitialContext();
084: appServerSource = (DataSource) ctxt
085: .lookup(CONTEXT_JDBC_NAME);
086: AppServerPooler = true;
087: System.err
088: .println("Yazd got a connection provider from app server ("
089: + CONTEXT_JDBC_NAME + ")");
090: } catch (Exception e) {
091: System.err
092: .println("Failed to find an application datasource ("
093: + CONTEXT_JDBC_NAME
094: + "): "
095: + e.getMessage());
096: }
097: }
098: if (connectionProvider == null && !AppServerPooler) {
099: synchronized (providerLock) {
100: if (connectionProvider == null) {
101: //Attempt to load the connection provider classname as
102: //a Yazd property.
103: String className = PropertyManager
104: .getProperty("connectionProvider.className");
105: if (className != null) {
106: //Attempt to load the class.
107: try {
108: Class conClass = Class.forName(className);
109: connectionProvider = (DbConnectionProvider) conClass
110: .newInstance();
111: } catch (Exception e) {
112: System.err
113: .println("Warning: failed to create the "
114: + "connection provider specified by connection"
115: + "Provider.className. Using the default pool.");
116: connectionProvider = new DbConnectionDefaultPool();
117: }
118: } else {
119: connectionProvider = new DbConnectionDefaultPool();
120: }
121: connectionProvider.start();
122: }
123: }
124: }
125: if (AppServerPooler) {
126: try {
127: con = appServerSource.getConnection();
128: } catch (Exception e) {
129: System.err
130: .println("There was a problem obtaining a connection from application server :"
131: + e.getMessage());
132: }
133: } else {
134: con = connectionProvider.getConnection();
135: }
136: if (con == null) {
137: System.err
138: .println("WARNING: DbConnectionManager.getConnection() "
139: + "failed to obtain a connection.");
140: }
141: return con;
142: }
143:
144: /**
145: * Returns the current connection provider. The only case in which this
146: * method should be called is if more information about the current
147: * connection provider is needed. Database connections should always be
148: * obtained by calling the getConnection method of this class.
149: */
150: public static DbConnectionProvider getDbConnectionProvider() {
151: return connectionProvider;
152: }
153:
154: /**
155: * Sets the connection provider. The old provider (if it exists) is shut
156: * down before the new one is started. A connection provider <b>should
157: * not</b> be started before being passed to the connection manager
158: * because the manager will call the start() method automatically.
159: */
160: public static void setDbConnectionProvider(
161: DbConnectionProvider provider) {
162: synchronized (providerLock) {
163: if (connectionProvider != null) {
164: connectionProvider.destroy();
165: connectionProvider = null;
166: }
167: connectionProvider = provider;
168: provider.start();
169: }
170: }
171:
172: }
|