001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free SoftwareFoundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jdbc;
031:
032: import com.caucho.util.L10N;
033: import com.caucho.util.Log;
034:
035: import javax.naming.Context;
036: import javax.naming.InitialContext;
037: import javax.naming.NamingException;
038: import javax.sql.DataSource;
039: import java.sql.Connection;
040: import java.sql.SQLException;
041: import java.util.HashMap;
042: import java.util.logging.Level;
043: import java.util.logging.Logger;
044:
045: /**
046: * Abstract way of grabbing data from the JDBC connection.
047: */
048: public class ConnectionContext {
049: private static final L10N L = new L10N(ConnectionContext.class);
050: private static final Logger log = Log.open(ConnectionContext.class);
051:
052: private static InitialContext _initialContext;
053:
054: private static ThreadLocal<HashMap<String, ConnectionContext>> _localConn = new ThreadLocal<HashMap<String, ConnectionContext>>();
055:
056: private int _depth;
057: private Connection _conn;
058:
059: public static void begin(String jndiName) {
060: HashMap<String, ConnectionContext> map = _localConn.get();
061:
062: if (map == null) {
063: map = new HashMap<String, ConnectionContext>(8);
064:
065: _localConn.set(map);
066: }
067:
068: ConnectionContext cxt = map.get(jndiName);
069:
070: if (cxt == null) {
071: cxt = new ConnectionContext();
072:
073: map.put(jndiName, cxt);
074: }
075:
076: cxt._depth++;
077: }
078:
079: public static Connection getConnection(String jndiName)
080: throws SQLException {
081: HashMap<String, ConnectionContext> map = _localConn.get();
082:
083: if (map == null)
084: throw new IllegalStateException(L.l(
085: "'{0}' is not an available connection.", jndiName));
086:
087: ConnectionContext cxt = map.get(jndiName);
088:
089: if (cxt == null || cxt._depth == 0)
090: throw new IllegalStateException(L.l(
091: "'{0}' is not an available connection.", jndiName));
092:
093: if (cxt._conn == null) {
094: try {
095: DataSource ds = (DataSource) _initialContext
096: .lookup(jndiName);
097:
098: cxt._conn = ds.getConnection();
099: } catch (NamingException e) {
100: throw new IllegalStateException(e);
101: }
102: }
103:
104: return null;
105: }
106:
107: public static void end(String jdbcName) {
108: HashMap<String, ConnectionContext> map = _localConn.get();
109:
110: if (map == null)
111: return;
112:
113: ConnectionContext cxt = map.get(jdbcName);
114:
115: if (cxt == null)
116: return;
117:
118: if (--cxt._depth == 0) {
119: Connection conn = cxt._conn;
120:
121: try {
122: cxt._conn = null;
123: conn.close();
124: } catch (SQLException e) {
125: log.log(Level.FINE, e.toString(), e);
126: }
127: }
128: }
129:
130: private static Context getInitialContext() {
131: if (_initialContext == null) {
132: try {
133: _initialContext = new InitialContext();
134: } catch (NamingException e) {
135: }
136: }
137:
138: return _initialContext;
139: }
140: }
|