View Javadoc

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 }