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: */
053:
054: /**
055: * Copyright (C) 2000 CoolServlets.com. All rights reserved.
056: *
057: * ===================================================================
058: * The Apache Software License, Version 1.1
059: *
060: * Redistribution and use in source and binary forms, with or without
061: * modification, are permitted provided that the following conditions
062: * are met:
063: *
064: * 1. Redistributions of source code must retain the above copyright
065: * notice, this list of conditions and the following disclaimer.
066: *
067: * 2. Redistributions in binary form must reproduce the above copyright
068: * notice, this list of conditions and the following disclaimer in
069: * the documentation and/or other materials provided with the
070: * distribution.
071: *
072: * 3. The end-user documentation included with the redistribution,
073: * if any, must include the following acknowledgment:
074: * "This product includes software developed by
075: * CoolServlets.com (http://www.coolservlets.com)."
076: * Alternately, this acknowledgment may appear in the software itself,
077: * if and wherever such third-party acknowledgments normally appear.
078: *
079: * 4. The names "Jive" and "CoolServlets.com" must not be used to
080: * endorse or promote products derived from this software without
081: * prior written permission. For written permission, please
082: * contact webmaster@coolservlets.com.
083: *
084: * 5. Products derived from this software may not be called "Jive",
085: * nor may "Jive" appear in their name, without prior written
086: * permission of CoolServlets.com.
087: *
088: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
089: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
090: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
091: * DISCLAIMED. IN NO EVENT SHALL COOLSERVLETS.COM OR
092: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
093: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
094: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
095: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
096: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
097: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
098: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
099: * SUCH DAMAGE.
100: * ====================================================================
101: *
102: * This software consists of voluntary contributions made by many
103: * individuals on behalf of CoolServlets.com. For more information
104: * on CoolServlets.com, please see <http://www.coolservlets.com>.
105: */package com.Yasna.forum.database;
106:
107: import java.sql.Connection;
108: import java.sql.SQLException;
109: import javax.sql.DataSource;
110: import java.util.Properties;
111: import java.util.Enumeration;
112: import javax.naming.Context;
113: import javax.naming.InitialContext;
114: import javax.naming.NamingException;
115: import com.Yasna.forum.PropertyManager;
116:
117: /**
118: * An implementation of DbConnectionProvider that utilizes a JDBC 2.0 DataSource
119: * made available via JNDI. This is useful for application servers where a pooled
120: * data connection is already provided so Yazd can share the pool with the
121: * other applications.<p>
122: *
123: * The JNDI location of the DataSource is retrieved from the
124: * {@link com.Yasna.forum.PropertyManager} as the
125: * <code>JNDIDataSource.name</code> property. This can be overiden by setting
126: * the provider's <code>name</code> property if required.
127: *
128: * @author <a href="mailto:joe@truemesh.com">Joe Walnes</a>
129: *
130: * @see com.Yasna.forum.database.DbConnectionProvider
131: */
132: public class DataSourceConnectionProvider extends DbConnectionProvider {
133:
134: private static final String NAME = "JNDI DataSource Connection Provider";
135: private static final String DESCRIPTION = "Connection Provider for Yazd to lookup pooled "
136: + "DataSource from JNDI location. Requires 'name' "
137: + "property with JNDI location. This can be set in "
138: + "the properties file as 'JNDIDataSource.name'";
139: private static final String AUTHOR = "Joe Walnes - joe@truemesh.com";
140: private static final int MAJOR_VERSION = 1;
141: private static final int MINOR_VERSION = 0;
142: private static final boolean POOLED = true;
143:
144: private Properties properties;
145: private DataSource dataSource;
146:
147: private static final boolean DEBUG = false;
148:
149: /**
150: * Keys of JNDI properties to query PropertyManager for.
151: */
152: private static final String[] jndiPropertyKeys = { Context.APPLET,
153: Context.AUTHORITATIVE, Context.BATCHSIZE, Context.DNS_URL,
154: Context.INITIAL_CONTEXT_FACTORY, Context.LANGUAGE,
155: Context.OBJECT_FACTORIES, Context.PROVIDER_URL,
156: Context.REFERRAL, Context.SECURITY_AUTHENTICATION,
157: Context.SECURITY_CREDENTIALS, Context.SECURITY_PRINCIPAL,
158: Context.SECURITY_PROTOCOL, Context.STATE_FACTORIES,
159: Context.URL_PKG_PREFIXES };
160:
161: /**
162: * Initialize.
163: */
164: public DataSourceConnectionProvider() {
165: debug("constructor()");
166: properties = new Properties();
167: setProperty("name", PropertyManager
168: .getProperty("JNDIDataSource.name"));
169: }
170:
171: /**
172: * Lookup DataSource from JNDI context.
173: */
174: protected void start() {
175: debug("start()");
176: String name = getProperty("name");
177: if (name == null || name.length() == 0) {
178: error(
179: "No name specified for DataSource JNDI lookup - 'name' "
180: + "Property should be set.", null);
181: return;
182: }
183: try {
184: Properties contextProperties = new Properties();
185: for (int i = 0; i < jndiPropertyKeys.length; i++) {
186: String k = jndiPropertyKeys[i];
187: String v = PropertyManager.getProperty(k);
188: if (v != null) {
189: contextProperties.setProperty(k, v);
190: }
191: }
192: Context context = new InitialContext(contextProperties);
193: dataSource = (DataSource) context.lookup(name);
194: } catch (Exception e) {
195: error("Could not lookup DataSource at '" + name + "'", e);
196: }
197: }
198:
199: /**
200: * Destroy then start.
201: */
202: protected void restart() {
203: debug("restart()");
204: destroy();
205: start();
206: }
207:
208: /**
209: * Save properties.
210: */
211: protected void destroy() {
212: debug("destroy()");
213: String name = getProperty("name");
214: if (name != null && name.length() > 0) {
215: PropertyManager.setProperty("JNDIDataSource.name", name);
216: }
217: }
218:
219: /**
220: * Get new Connection from DataSource.
221: */
222: public Connection getConnection() {
223: debug("getConnection()");
224: if (dataSource == null) {
225: error("DataSource has not yet been looked up", null);
226: return null;
227: }
228: try {
229: return dataSource.getConnection();
230: } catch (SQLException e) {
231: error("Could not retrieve Connection from DataSource", e);
232: return null;
233: }
234: }
235:
236: public String getProperty(String name) {
237: debug("getProperty('" + name + "+')");
238: return properties.getProperty(name);
239: }
240:
241: public void setProperty(String name, String value) {
242: debug("setProperty('" + name + "+','" + value + "')");
243: properties.setProperty(name, value);
244: }
245:
246: public Enumeration propertyNames() {
247: debug("propertyNames()");
248: return properties.propertyNames();
249: }
250:
251: public String getPropertyDescription(String name) {
252: debug("getPropertyDescription('" + name + "')");
253: if (name.equals("name")) {
254: return "JNDI name to lookup. eg: java:comp/env/jdbc/MyDataSource";
255: } else {
256: return null;
257: }
258: }
259:
260: /**
261: * Log an error.
262: *
263: * @param msg Description of error
264: * @param e Exception to printStackTrace (may be null)
265: */
266: private final void error(String msg, Exception e) {
267: System.err.println("Error: " + msg);
268: if (e != null) {
269: e.printStackTrace();
270: }
271: }
272:
273: /**
274: * Display messages for debugging
275: */
276: private final void debug(String msg) {
277: if (DEBUG) {
278: System.err.println("DEBUG: " + msg);
279: }
280: }
281: }
|