1 /* Copyright (c) 2001-2016, The HSQL Development Group 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of the HSQL Development Group nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 22 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 32 package org.hsqldb.jdbc; 33 34 import java.io.Serializable; 35 import java.sql.Connection; 36 import java.sql.SQLException; 37 38 //#ifdef JAVA6 39 import java.sql.Wrapper; 40 41 //#endif JAVA6 42 import java.util.Properties; 43 44 import javax.naming.NamingException; 45 import javax.naming.Reference; 46 import javax.naming.Referenceable; 47 import javax.naming.StringRefAddr; 48 import javax.sql.DataSource; 49 50 /** 51 * <p>A factory for connections to the physical data source that this 52 * <code>DataSource</code> object represents. An alternative to the 53 * <code>DriverManager</code> facility, a <code>DataSource</code> object 54 * is the preferred means of getting a connection. An object that implements 55 * the <code>DataSource</code> interface will typically be 56 * registered with a naming service based on the 57 * Java<sup><font size=-2>TM</font></sup> Naming and Directory (JNDI) API. 58 * <P> 59 * The <code>DataSource</code> interface is implemented by a driver vendor. 60 * There are three types of implementations: 61 * <OL> 62 * <LI>Basic implementation -- produces a standard <code>Connection</code> 63 * object 64 * <LI>Connection pooling implementation -- produces a <code>Connection</code> 65 * object that will automatically participate in connection pooling. This 66 * implementation works with a middle-tier connection pooling manager. 67 * <LI>Distributed transaction implementation -- produces a 68 * <code>Connection</code> object that may be used for distributed 69 * transactions and almost always participates in connection pooling. 70 * This implementation works with a middle-tier 71 * transaction manager and almost always with a connection 72 * pooling manager. 73 * </OL> 74 * <P> 75 * A <code>DataSource</code> object has properties that can be modified 76 * when necessary. For example, if the data source is moved to a different 77 * server, the property for the server can be changed. The benefit is that 78 * because the data source's properties can be changed, any code accessing 79 * that data source does not need to be changed. 80 * <P> 81 * A driver that is accessed via a <code>DataSource</code> object does not 82 * register itself with the <code>DriverManager</code>. Rather, a 83 * <code>DataSource</code> object is retrieved though a lookup operation 84 * and then used to create a <code>Connection</code> object. With a basic 85 * implementation, the connection obtained through a <code>DataSource</code> 86 * object is identical to a connection obtained through the 87 * <code>DriverManager</code> facility. 88 * 89 * <!-- start Release-specific documentation --> 90 * <div class="ReleaseSpecificDocumentation"> 91 * <h3>HSQLDB-Specific Information:</h3> <p> 92 * 93 * This implementation of data source is a basic implementation and does not 94 * perform connection pooling.<p> 95 * 96 * The getter and setter methods of the parent class, {@link JDBCCommonDataSource}, 97 * can be used.<p> 98 * </div> 99 * <!-- end Release-specific documentation --> 100 * @since JDK 1.4 101 * @author Campbell Burnet (boucherb@users dot sourceforge.net) 102 * @author Fred Toussi (fredt@users dot sourceforge.net) 103 * @version 2.3.2 104 * @since 1.7.2 105 */ 106 107 //#ifdef JAVA6 108 @SuppressWarnings("serial") 109 110 //#endif JAVA6 111 public class JDBCDataSource extends JDBCCommonDataSource implements DataSource, 112 Serializable, Referenceable 113 114 //#ifdef JAVA6 115 , Wrapper 116 117 //#endif JAVA6 118 { 119 120 /** 121 * Retrieves a new connection using the properties that have already been 122 * set. 123 * 124 * @return a connection to the data source 125 * @exception SQLException if a database access error occurs 126 */ getConnection()127 public Connection getConnection() throws SQLException { 128 129 if (url == null) { 130 throw JDBCUtil.nullArgument("url"); 131 } 132 133 if (connectionProps == null) { 134 if (user == null) { 135 throw JDBCUtil.invalidArgument("user"); 136 } 137 138 if (password == null) { 139 throw JDBCUtil.invalidArgument("password"); 140 } 141 142 return getConnection(user, password); 143 } 144 145 return getConnection(url, connectionProps); 146 } 147 148 /** 149 * Retrieves a new connection using the given username and password, 150 * and the database url that has been set. No other properties are 151 * used for the connection 152 * 153 * @param username the database user on whose behalf the connection is 154 * being made 155 * @param password the user's password 156 * @return a connection to the data source 157 * @exception SQLException if a database access error occurs 158 */ getConnection(String username, String password)159 public Connection getConnection(String username, 160 String password) throws SQLException { 161 162 if (username == null) { 163 throw JDBCUtil.invalidArgument("user"); 164 } 165 166 if (password == null) { 167 throw JDBCUtil.invalidArgument("password"); 168 } 169 170 Properties props = new Properties(); 171 172 props.setProperty("user", username); 173 props.setProperty("password", password); 174 props.setProperty("loginTimeout", Integer.toString(loginTimeout)); 175 176 return getConnection(url, props); 177 } 178 getConnection(String url, Properties props)179 private Connection getConnection(String url, 180 Properties props) throws SQLException { 181 182 if (!url.startsWith("jdbc:hsqldb:")) { 183 url = "jdbc:hsqldb:" + url; 184 } 185 186 return JDBCDriver.getConnection(url, props); 187 } 188 189 //------------------------- JDBC 4.0 ----------------------------------- 190 // ------------------- java.sql.Wrapper implementation --------------------- 191 192 /** 193 * Returns an object that implements the given interface to allow access to 194 * non-standard methods, or standard methods not exposed by the proxy. 195 * 196 * If the receiver implements the interface then the result is the receiver 197 * or a proxy for the receiver. If the receiver is a wrapper 198 * and the wrapped object implements the interface then the result is the 199 * wrapped object or a proxy for the wrapped object. Otherwise return the 200 * the result of calling <code>unwrap</code> recursively on the wrapped object 201 * or a proxy for that result. If the receiver is not a 202 * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown. 203 * 204 * @param iface A Class defining an interface that the result must implement. 205 * @return an object that implements the interface. May be a proxy for the actual implementing object. 206 * @throws java.sql.SQLException If no object found that implements the interface 207 * @since JDK 1.6, HSQLDB 2.0 208 */ 209 //#ifdef JAVA6 210 @SuppressWarnings("unchecked") unwrap(java.lang.Class<T> iface)211 public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException { 212 213 if (isWrapperFor(iface)) { 214 return (T) this; 215 } 216 217 throw JDBCUtil.invalidArgument("iface: " + iface); 218 } 219 220 //#endif JAVA6 221 222 /** 223 * Returns true if this either implements the interface argument or is directly or indirectly a wrapper 224 * for an object that does. Returns false otherwise. If this implements the interface then return true, 225 * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped 226 * object. If this does not implement the interface and is not a wrapper, return false. 227 * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that 228 * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method 229 * returns true then calling <code>unwrap</code> with the same argument should succeed. 230 * 231 * @param iface a Class defining an interface. 232 * @return true if this implements the interface or directly or indirectly wraps an object that does. 233 * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper 234 * for an object with the given interface. 235 * @since JDK 1.6, HSQLDB 2.0 236 */ 237 //#ifdef JAVA6 isWrapperFor( java.lang.Class<?> iface)238 public boolean isWrapperFor( 239 java.lang.Class<?> iface) throws java.sql.SQLException { 240 return (iface != null && iface.isAssignableFrom(this.getClass())); 241 } 242 243 //#endif JAVA6 244 245 /** 246 * Retrieves the Reference of this object. 247 * 248 * @return The non-null Reference of this object. 249 * @exception NamingException If a naming exception was encountered 250 * while retrieving the reference. 251 */ getReference()252 public Reference getReference() throws NamingException { 253 254 String cname = "org.hsqldb.jdbc.JDBCDataSourceFactory"; 255 Reference ref = new Reference(getClass().getName(), cname, null); 256 257 ref.add(new StringRefAddr("database", getDatabase())); 258 ref.add(new StringRefAddr("user", getUser())); 259 ref.add(new StringRefAddr("password", password)); 260 ref.add(new StringRefAddr("loginTimeout", 261 Integer.toString(loginTimeout))); 262 263 return ref; 264 } 265 266 // ------------------------ custom public methods ------------------------ JDBCDataSource()267 public JDBCDataSource() { 268 } 269 } 270