1 /**
2 * Logback: the reliable, generic, fast and flexible logging framework.
3 * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
4 *
5 * This program and the accompanying materials are dual-licensed under
6 * either the terms of the Eclipse Public License v1.0 as published by
7 * the Eclipse Foundation
8 *
9 * or (per the licensee's choosing)
10 *
11 * under the terms of the GNU Lesser General Public License version 2.1
12 * as published by the Free Software Foundation.
13 */
14 package ch.qos.logback.core.db;
15
16 import java.sql.Connection;
17 import java.sql.SQLException;
18
19 import javax.naming.Context;
20 import javax.naming.InitialContext;
21 import javax.naming.NamingException;
22
23 // PortableRemoteObject was introduced in JDK 1.3. We won't use it.
24 // import javax.rmi.PortableRemoteObject;
25 import javax.sql.DataSource;
26
27 /**
28 * The <id>JNDIConnectionSource</id> is an implementation of
29 * {@link ConnectionSource} that obtains a {@link javax.sql.DataSource} from a
30 * JNDI provider and uses it to obtain a {@link java.sql.Connection}. It is
31 * primarily designed to be used inside of J2EE application servers or
32 * application server clients, assuming the application server supports remote
33 * access of {@link javax.sql.DataSource}s. In this way one can take advantage
34 * of connection pooling and whatever other goodies the application server
35 * provides.
36 * <p>
37 * For more information about this component, please refer to the online manual at
38 * http://logback.qos.ch/manual/appenders.html#DBAppender
39 *
40 * @author <a href="mailto:rdecampo@twcny.rr.com">Ray DeCampo</a>
41 */
42 public class JNDIConnectionSource extends ConnectionSourceBase {
43 private String jndiLocation = null;
44 private DataSource dataSource = null;
45
46 /**
47 * @see org.apache.log4j.spi.OptionHandler#activateOptions()
48 */
49 public void start() {
50 if (jndiLocation == null) {
51 addError("No JNDI location specified for JNDIConnectionSource.");
52 }
53
54 discoverConnnectionProperties();
55
56 }
57
58 /**
59 * @see org.apache.log4j.db.ConnectionSource#getConnection()
60 */
61 public Connection getConnection() throws SQLException {
62 Connection conn = null;
63 try {
64
65 if (dataSource == null) {
66 dataSource = lookupDataSource();
67 }
68 if (getUser() == null) {
69 conn = dataSource.getConnection();
70 } else {
71 conn = dataSource.getConnection(getUser(), getPassword());
72 }
73 } catch (final NamingException ne) {
74 addError("Error while getting data source", ne);
75 throw new SQLException("NamingException while looking up DataSource: "
76 + ne.getMessage());
77 } catch (final ClassCastException cce) {
78 addError("ClassCastException while looking up DataSource.", cce);
79 throw new SQLException("ClassCastException while looking up DataSource: "
80 + cce.getMessage());
81 }
82
83 return conn;
84 }
85
86 /**
87 * Returns the jndiLocation.
88 *
89 * @return String
90 */
91 public String getJndiLocation() {
92 return jndiLocation;
93 }
94
95 /**
96 * Sets the jndiLocation.
97 *
98 * @param jndiLocation
99 * The jndiLocation to set
100 */
101 public void setJndiLocation(String jndiLocation) {
102 this.jndiLocation = jndiLocation;
103 }
104
105 private DataSource lookupDataSource() throws NamingException, SQLException {
106 DataSource ds;
107 Context ctx = new InitialContext();
108 Object obj = ctx.lookup(jndiLocation);
109
110 // PortableRemoteObject was introduced in JDK 1.3. We won't use it.
111 // ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class);
112 ds = (DataSource) obj;
113
114 if (ds == null) {
115 throw new SQLException("Failed to obtain data source from JNDI location "
116 + jndiLocation);
117 } else {
118 return ds;
119 }
120 }
121 }