001 /* 002 * $Id: JDBCLoginService.java 3100 2008-10-14 22:33:10Z rah003 $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 package org.jdesktop.swingx.auth; 022 import java.sql.Connection; 023 import java.sql.DriverManager; 024 import java.util.Properties; 025 import java.util.logging.Level; 026 import java.util.logging.Logger; 027 028 import javax.naming.InitialContext; 029 /** 030 * A login service for connecting to SQL based databases via JDBC 031 * 032 * @author rbair 033 */ 034 public class JDBCLoginService extends LoginService { 035 private static final Logger LOG = Logger.getLogger(JDBCLoginService.class 036 .getName()); 037 038 /** 039 * The connection to the database 040 */ 041 private Connection conn; 042 /** 043 * If used, defines the JNDI context from which to get a connection to 044 * the data base 045 */ 046 private String jndiContext; 047 /** 048 * When using the DriverManager to connect to the database, this specifies 049 * any additional properties to use when connecting. 050 */ 051 private Properties properties; 052 053 /** 054 * Create a new JDBCLoginService and initializes it to connect to a 055 * database using the given params. 056 * @param driver 057 * @param url 058 */ 059 public JDBCLoginService(String driver, String url) { 060 super(url); 061 try { 062 Class.forName(driver); 063 } catch (Exception e) { 064 LOG.log(Level.WARNING, "The driver passed to the " + 065 "JDBCLoginService constructor could not be loaded. " + 066 "This may be due to the driver not being on the classpath", e); 067 } 068 this.setUrl(url); 069 } 070 071 /** 072 * Create a new JDBCLoginService and initializes it to connect to a 073 * database using the given params. 074 * @param driver 075 * @param url 076 * @param props 077 */ 078 public JDBCLoginService(String driver, String url, Properties props) { 079 super(url); 080 try { 081 Class.forName(driver); 082 } catch (Exception e) { 083 LOG.log(Level.WARNING, "The driver passed to the " + 084 "JDBCLoginService constructor could not be loaded. " + 085 "This may be due to the driver not being on the classpath", e); 086 } 087 this.setUrl(url); 088 this.setProperties(props); 089 } 090 091 /** 092 * Create a new JDBCLoginService and initializes it to connect to a 093 * database using the given params. 094 * @param jndiContext 095 */ 096 public JDBCLoginService(String jndiContext) { 097 super(jndiContext); 098 this.jndiContext = jndiContext; 099 } 100 101 /** 102 * Default JavaBean constructor 103 */ 104 public JDBCLoginService() { 105 super(); 106 } 107 108 /** 109 * @return the JDBC connection url 110 */ 111 public String getUrl() { 112 return getServer(); 113 } 114 115 /** 116 * @param url set the JDBC connection url 117 */ 118 public void setUrl(String url) { 119 String old = getUrl(); 120 setServer(url); 121 firePropertyChange("url", old, getUrl()); 122 } 123 124 /** 125 * @return JDBC connection properties 126 */ 127 public Properties getProperties() { 128 return properties; 129 } 130 131 /** 132 * @param properties miscellaneous JDBC properties to use when connecting 133 * to the database via the JDBC driver 134 */ 135 public void setProperties(Properties properties) { 136 Properties old = getProperties(); 137 this.properties = properties; 138 firePropertyChange("properties", old, getProperties()); 139 } 140 141 public Connection getConnection() { 142 return conn; 143 } 144 145 public void setConnection(Connection conn) { 146 Connection old = getConnection(); 147 this.conn = conn; 148 firePropertyChange("connection", old, getConnection()); 149 } 150 151 /** 152 * Attempts to get a JDBC Connection from a JNDI javax.sql.DataSource, using 153 * that connection for interacting with the database. 154 * @throws Exception 155 */ 156 private void connectByJNDI(String userName, char[] password) throws Exception { 157 InitialContext ctx = new InitialContext(); 158 javax.sql.DataSource ds = (javax.sql.DataSource)ctx.lookup(jndiContext); 159 conn = ds.getConnection(userName, new String(password)); 160 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 161 } 162 163 /** 164 * Attempts to get a JDBC Connection from a DriverManager. If properties 165 * is not null, it tries to connect with those properties. If that fails, 166 * it then attempts to connect with a user name and password. If that fails, 167 * it attempts to connect without any credentials at all. 168 * <p> 169 * If, on the other hand, properties is null, it first attempts to connect 170 * with a username and password. Failing that, it tries to connect without 171 * any credentials at all. 172 * @throws Exception 173 */ 174 private void connectByDriverManager(String userName, char[] password) throws Exception { 175 if (getProperties() != null) { 176 try { 177 conn = DriverManager.getConnection(getUrl(), getProperties()); 178 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 179 } catch (Exception e) { 180 try { 181 conn = DriverManager.getConnection(getUrl(), userName, new String(password)); 182 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 183 } catch (Exception ex) { 184 conn = DriverManager.getConnection(getUrl()); 185 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 186 } 187 } 188 } else { 189 try { 190 conn = DriverManager.getConnection(getUrl(), userName, new String(password)); 191 } catch (Exception e) { 192 LOG.log(Level.WARNING, "Connection with properties failed. " + 193 "Tryint to connect without.", e); 194 //try to connect without using the userName and password 195 conn = DriverManager.getConnection(getUrl()); 196 197 } 198 } 199 } 200 201 /** 202 * @param name user name 203 * @param password user password 204 * @param server Must be either a valid JDBC URL for the type of JDBC driver you are using, 205 * or must be a valid JNDIContext from which to get the database connection 206 */ 207 public boolean authenticate(String name, char[] password, String server) throws Exception { 208 //try to form a connection. If it works, conn will not be null 209 //if the jndiContext is not null, then try to get the DataSource to use 210 //from jndi 211 if (jndiContext != null) { 212 try { 213 connectByJNDI(name, password); 214 } catch (Exception e) { 215 try { 216 connectByDriverManager(name, password); 217 } catch (Exception ex) { 218 LOG.log(Level.WARNING, "Login failed", ex); 219 //login failed 220 return false; 221 } 222 } 223 } else { 224 try { 225 connectByDriverManager(name, password); 226 } catch (Exception ex) { 227 LOG.log(Level.WARNING, "", ex); 228 return false; 229 } 230 } 231 return true; 232 } 233 }