001: /*
002: * CoadunationLib: The coaduntion implementation library.
003: * Copyright (C) 2006 Rift IT Contracting
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
018: *
019: * XMLConfigurationException.java
020: *
021: * DBSourceManager.java
022: *
023: * This object is responsible for managing the database sources used by the
024: * coadunation environments.
025: */
026:
027: // package path
028: package com.rift.coad.lib.db;
029:
030: // java import
031: import java.util.Map;
032: import java.util.HashMap;
033: import java.util.HashSet;
034: import java.util.Set;
035: import java.util.Iterator;
036: import java.util.StringTokenizer;
037: import javax.naming.Reference;
038: import javax.naming.StringRefAddr;
039: import java.util.HashMap;
040:
041: // logging import
042: import org.apache.log4j.Logger;
043:
044: // coadunation imports
045: import com.rift.coad.lib.configuration.ConfigurationFactory;
046: import com.rift.coad.lib.configuration.Configuration;
047: import com.rift.coad.lib.naming.ContextManager;
048: import com.rift.coad.lib.loader.MasterClassLoader;
049:
050: /**
051: * This object is responsible for managing the database sources used by the
052: * coadunation environments.
053: *
054: * @author Brett Chaldecott
055: */
056: public class DBSourceManager {
057:
058: // class constants
059: private final static String DB_SOURCES = "db_sources";
060: private final static String DB_SOURCE = "db_source";
061: private final static String DB_CONTEXT = "java:comp/env/jdbc";
062: private final static String DB_CONTEXT_ID = "db_context";
063:
064: // the singleton reference.
065: private static DBSourceManager singleton = null;
066:
067: // member variables
068: protected Logger log = Logger.getLogger(DBSourceManager.class
069: .getName());
070: private ContextManager contextManager = null;
071: private String jndiBase = null;
072:
073: /**
074: * Creates a new instance of DBSourceManager
075: *
076: * @exception DBException
077: */
078: private DBSourceManager() throws DBException {
079: try {
080: Configuration sourceConfig = ConfigurationFactory
081: .getInstance().getConfig(this .getClass());
082: // init the context
083: try {
084: jndiBase = sourceConfig.getString(DB_CONTEXT);
085: contextManager = new ContextManager(jndiBase);
086: } catch (Exception ex) {
087: jndiBase = DB_CONTEXT;
088: contextManager = new ContextManager(jndiBase);
089: }
090:
091: StringTokenizer dbSources = new StringTokenizer(
092: sourceConfig.getString(DB_SOURCES), ",");
093: while (dbSources.hasMoreTokens()) {
094: String dbSource = dbSources.nextToken().trim();
095: try {
096: Configuration dbSourceConfig = ConfigurationFactory
097: .getInstance().getConfig(
098: Class.forName(dbSource));
099: Set keys = dbSourceConfig.getKeys();
100: Reference ref = new Reference(
101: "javax.sql.DataSource",
102: "org.objectweb.jndi.DataSourceFactory",
103: null);
104: ref.add(new StringRefAddr("driverClassName",
105: dbSource));
106: for (Iterator iter = keys.iterator(); iter
107: .hasNext();) {
108: String key = (String) iter.next();
109: if (key.equals(DB_SOURCE)
110: || !dbSourceConfig.isString(key)) {
111: continue;
112: }
113: ref.add(new StringRefAddr(key, dbSourceConfig
114: .getString(key)));
115: }
116: contextManager.bind(dbSourceConfig
117: .getString(DB_SOURCE), ref);
118: } catch (Exception ex) {
119: log.error(
120: "Failed to instanciate the datase source for ["
121: + dbSource + "] because : "
122: + ex.getMessage(), ex);
123: }
124: }
125: } catch (Exception ex) {
126: throw new DBException(
127: "Failed to instanciate the db source manager : "
128: + ex.getMessage(), ex);
129: }
130: }
131:
132: /**
133: * This method initializes the database source manager.
134: */
135: public static synchronized void init() throws DBException {
136: if (singleton == null) {
137: singleton = new DBSourceManager();
138: }
139: }
140:
141: /**
142: * This method returns an instance of the database source manager.
143: *
144: * @return The instance of the database source manager.
145: * @exception DBException
146: */
147: public static synchronized DBSourceManager getInstance()
148: throws DBException {
149: if (singleton == null) {
150: throw new DBException(
151: "The Database Source manager has not been initialized.");
152: }
153: return singleton;
154: }
155:
156: /**
157: * This method adds a new database source. This method must not be
158: * used by any Daemon instances!!!!!
159: *
160: * @param driverPath The path to the driver library.
161: * @param driverClass The driver class to load.
162: * @param jndi The name to register this jdbc connection with the jndi.
163: * @param env The environment for the jdbc connetion.
164: * @exception DBException
165: */
166: public void addDBSource(String driverPath, String driverClass,
167: String jndi, HashMap env) throws DBException {
168: try {
169: MasterClassLoader.getInstance().addLib(driverPath);
170: Class.forName(driverClass);
171: Reference ref = new Reference("javax.sql.DataSource",
172: "org.apache.commons.dbcp.BasicDatabSourceFactory",
173: null);
174: ref.add(new StringRefAddr("driverClassName", driverClass));
175: Set keys = env.keySet();
176: for (Iterator iter = keys.iterator(); iter.hasNext();) {
177: String key = (String) iter.next();
178: if (key.equals(DB_SOURCE)) {
179: continue;
180: }
181: ref.add(new StringRefAddr(key, (String) env.get(key)));
182: }
183: String jndiRef = jndi;
184: if (jndiRef.contains(jndiBase)) {
185: jndiRef = jndiRef.substring(jndiRef.indexOf(jndiBase)
186: + jndiBase.length());
187: }
188: contextManager.bind(jndiRef, ref);
189: } catch (Exception ex) {
190: throw new DBException(
191: "Failed to add a data source because : "
192: + ex.getMessage(), ex);
193: }
194: }
195:
196: /**
197: * This method adds the database source.
198: *
199: * @param driverClass The driver class to load.
200: * @param jndi The name to register this jdbc connection with the jndi.
201: * @param env The environment for the jdbc connetion.
202: * @exception DBException
203: */
204: public void addDBSource(String driverClass, String jndi, HashMap env)
205: throws DBException {
206: try {
207: Class.forName(driverClass);
208: Reference ref = new Reference("javax.sql.DataSource",
209: "org.apache.commons.dbcp.BasicDatabSourceFactory",
210: null);
211: ref.add(new StringRefAddr("driverClassName", driverClass));
212: Set keys = env.keySet();
213: for (Iterator iter = keys.iterator(); iter.hasNext();) {
214: String key = (String) iter.next();
215: if (key.equals(DB_SOURCE)) {
216: continue;
217: }
218: ref.add(new StringRefAddr(key, (String) env.get(key)));
219: }
220: String jndiRef = jndi;
221: if (jndiRef.contains(jndiBase)) {
222: jndiRef = jndiRef.substring(jndiRef.indexOf(jndiBase)
223: + jndiBase.length());
224: }
225: contextManager.bind(jndiRef, ref);
226: } catch (Exception ex) {
227: throw new DBException(
228: "Failed to add a data source because : "
229: + ex.getMessage(), ex);
230: }
231: }
232:
233: /**
234: * This method removes the database source from JNDI. It does not unload
235: * the library that requires a restart.
236: *
237: * @param jndi The path to the jndi variable.
238: * @exception DBException
239: */
240: public void removeDBSource(String jndi) throws DBException {
241: try {
242: String jndiRef = jndi;
243: if (jndiRef.contains(jndiBase)) {
244: jndiRef = jndiRef.substring(jndiRef.indexOf(jndiBase)
245: + jndiBase.length());
246: }
247: contextManager.unbind(jndiRef);
248: } catch (Exception ex) {
249: throw new DBException("Failed to remove [" + jndi
250: + "] because : " + ex.getMessage(), ex);
251: }
252: }
253: }
|