001: /*
002: * Copyright 2004-2005 OpenSymphony
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy
006: * of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations
014: * under the License.
015: *
016: */
017:
018: /*
019: * Previously Copyright (c) 2001-2004 James House
020: */
021: package org.quartz.utils;
022:
023: import java.sql.Connection;
024: import java.sql.SQLException;
025: import java.util.Properties;
026:
027: import javax.naming.Context;
028: import javax.naming.InitialContext;
029: import javax.sql.DataSource;
030: import javax.sql.XADataSource;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034:
035: /**
036: * <p>
037: * A <code>ConnectionProvider</code> that provides connections from a <code>DataSource</code>
038: * that is managed by an application server, and made available via JNDI.
039: * </p>
040: *
041: * @see DBConnectionManager
042: * @see ConnectionProvider
043: * @see PoolingConnectionProvider
044: *
045: * @author James House
046: * @author Sharada Jambula
047: * @author Mohammad Rezaei
048: * @author Patrick Lightbody
049: * @author Srinivas Venkatarangaiah
050: */
051: public class JNDIConnectionProvider implements ConnectionProvider {
052:
053: /*
054: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
055: *
056: * Data members.
057: *
058: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
059: */
060:
061: private String url;
062:
063: private Properties props;
064:
065: private Object datasource;
066:
067: private boolean alwaysLookup = false;
068:
069: private final Log log = LogFactory.getLog(getClass());
070:
071: /*
072: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
073: *
074: * Constructors.
075: *
076: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
077: */
078:
079: /**
080: * Constructor
081: *
082: * @param jndiUrl
083: * The url for the datasource
084: */
085: public JNDIConnectionProvider(String jndiUrl, boolean alwaysLookup) {
086: this .url = jndiUrl;
087: this .alwaysLookup = alwaysLookup;
088: init();
089: }
090:
091: /**
092: * Constructor
093: *
094: * @param jndiUrl
095: * The URL for the DataSource
096: * @param jndiProps
097: * The JNDI properties to use when establishing the InitialContext
098: * for the lookup of the given URL.
099: */
100: public JNDIConnectionProvider(String jndiUrl, Properties jndiProps,
101: boolean alwaysLookup) {
102: this .url = jndiUrl;
103: this .props = jndiProps;
104: this .alwaysLookup = alwaysLookup;
105: init();
106: }
107:
108: /*
109: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110: *
111: * Interface.
112: *
113: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
114: */
115:
116: protected Log getLog() {
117: return log;
118: }
119:
120: private void init() {
121:
122: if (!isAlwaysLookup()) {
123: Context ctx = null;
124: try {
125: ctx = (props != null) ? new InitialContext(props)
126: : new InitialContext();
127:
128: datasource = (DataSource) ctx.lookup(url);
129: } catch (Exception e) {
130: getLog().error(
131: "Error looking up datasource: "
132: + e.getMessage(), e);
133: } finally {
134: if (ctx != null) {
135: try {
136: ctx.close();
137: } catch (Exception ignore) {
138: }
139: }
140: }
141: }
142: }
143:
144: public Connection getConnection() throws SQLException {
145: Context ctx = null;
146: try {
147: Object ds = this .datasource;
148:
149: if (ds == null || isAlwaysLookup()) {
150: ctx = (props != null) ? new InitialContext(props)
151: : new InitialContext();
152:
153: ds = ctx.lookup(url);
154: if (!isAlwaysLookup()) {
155: this .datasource = ds;
156: }
157: }
158:
159: if (ds == null) {
160: throw new SQLException(
161: "There is no object at the JNDI URL '" + url
162: + "'");
163: }
164:
165: if (ds instanceof XADataSource) {
166: return (((XADataSource) ds).getXAConnection()
167: .getConnection());
168: } else if (ds instanceof DataSource) {
169: return ((DataSource) ds).getConnection();
170: } else {
171: throw new SQLException("Object at JNDI URL '" + url
172: + "' is not a DataSource.");
173: }
174: } catch (Exception e) {
175: this .datasource = null;
176: throw new SQLException(
177: "Could not retrieve datasource via JNDI url '"
178: + url + "' " + e.getClass().getName()
179: + ": " + e.getMessage());
180: } finally {
181: if (ctx != null) {
182: try {
183: ctx.close();
184: } catch (Exception ignore) {
185: }
186: }
187: }
188: }
189:
190: public boolean isAlwaysLookup() {
191: return alwaysLookup;
192: }
193:
194: public void setAlwaysLookup(boolean b) {
195: alwaysLookup = b;
196: }
197:
198: /*
199: * @see org.quartz.utils.ConnectionProvider#shutdown()
200: */
201: public void shutdown() throws SQLException {
202: // do nothing
203: }
204:
205: }
|