View Javadoc

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