Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.wasp.jdbcx; import com.alibaba.wasp.jdbc.Driver; import com.alibaba.wasp.jdbc.JdbcConnection; import com.alibaba.wasp.jdbc.JdbcException; import com.alibaba.wasp.util.StringUtils; import com.alibaba.wasp.util.Utils; import org.apache.commons.lang.NotImplementedException; import org.apache.hadoop.conf.Configuration; import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import javax.sql.PooledConnection; import javax.sql.XAConnection; import javax.sql.XADataSource; import java.io.IOException; import java.io.ObjectInputStream; import java.io.PrintWriter; import java.io.Serializable; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Enumeration; import java.util.Properties; import java.util.logging.Logger; /*## Java 1.7 ## import java.util.logging.Logger; //*/ /** * A data source for H2 database connections. It is a factory for XAConnection * and Connection objects. This class is usually registered in a JNDI naming * service. To create a data source object and register it with a JNDI service, * use the following code: * * <pre> * import com.alibaba.wasp.jdbcx.JdbcDataSource; * import javax.naming.Context; * import javax.naming.InitialContext; * JdbcDataSource ds = new JdbcDataSource(); * ds.setURL("jdbc:wasp:˜/test"); * ds.setUser("sa"); * ds.setPassword("sa"); * Context ctx = new InitialContext(); * ctx.bind("jdbc/dsName", ds); * </pre> * * To use a data source that is already registered, use the following code: * * <pre> * import java.sql.Connection; * import javax.sql.DataSource; * import javax.naming.Context; * import javax.naming.InitialContext; * Context ctx = new InitialContext(); * DataSource ds = (DataSource) ctx.lookup("jdbc/dsName"); * Connection conn = ds.getConnection(); * </pre> * * In this example the user name and password are serialized as well; this may * be a security problem in some cases. */ public class JdbcDataSource implements XADataSource, DataSource, ConnectionPoolDataSource, Serializable, Referenceable { private static final long serialVersionUID = 1288136338451857771L; private transient JdbcDataSourceFactory factory; private transient PrintWriter logWriter; private int loginTimeout; private String userName = ""; private char[] passwordChars = {}; private String url = ""; private String description; private Configuration conf; static { com.alibaba.wasp.jdbc.Driver.load(); } /** * The public constructor. */ public JdbcDataSource(Configuration conf) { this.conf = conf; initFactory(); } /** * Called when de-serializing the object. * * @param in * the input stream */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { initFactory(); in.defaultReadObject(); } private void initFactory() { factory = new JdbcDataSourceFactory(conf); } /** * Get the login timeout in seconds, 0 meaning no timeout. * * @return the timeout in seconds */ public int getLoginTimeout() { return loginTimeout; } /** * Set the login timeout in seconds, 0 meaning no timeout. The default value * is 0. This value is ignored by this database. * * @param timeout * the timeout in seconds */ public void setLoginTimeout(int timeout) { this.loginTimeout = timeout; } /** * Get the current log writer for this object. * * @return the log writer */ public PrintWriter getLogWriter() { return logWriter; } /** * Set the current log writer for this object. This value is ignored by this * database. * * @param out * the log writer */ public void setLogWriter(PrintWriter out) { logWriter = out; } /** * Open a new connection using the current URL, user name and password. * * @return the connection */ public Connection getConnection() throws SQLException { return getJdbcConnection(userName, StringUtils.cloneCharArray(passwordChars)); } /** * Open a new connection using the current URL and the specified user name and * password. * * @param user * the user name * @param password * the password * @return the connection */ public Connection getConnection(String user, String password) throws SQLException { return getJdbcConnection(user, convertToCharArray(password)); } private JdbcConnection getJdbcConnection(String user, char[] password) throws SQLException { Properties info = Utils.convertConfigurationToProperties(conf); info.setProperty("user", user); info.put("password", password); Connection conn = getConnectionInternal(getURL(url, true), info); if (conn == null) { throw new SQLException("No suitable driver found for " + url, "08001", 8001); } else if (!(conn instanceof JdbcConnection)) { throw new SQLException("Connecting with old version is not supported: " + url, "08001", 8001); } return (JdbcConnection) conn; } private static Connection getConnectionInternal(String url, Properties properties) throws SQLException { //com.alibaba.wasp.jdbc.Driver.load(); Enumeration<java.sql.Driver> drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { java.sql.Driver driver = (java.sql.Driver) drivers.nextElement(); if (!(driver instanceof Driver)) { DriverManager.deregisterDriver(driver); } } return DriverManager.getConnection(url, properties); } /** * Get the database URL for the given database name using the current * configuration options. * * @param name * the database name * @param admin * true if the current user is an admin * @return the database URL */ protected static String getURL(String name, boolean admin) { String url; if (name.startsWith("jdbc:")) { return name; } url = name; return "jdbc:wasp:" + url; } /** * Get the current URL. * * @return the URL */ public String getURL() { return url; } /** * Set the current URL. * * @param url * the new URL */ public void setURL(String url) { this.url = url; } /** * Set the current password. * * @param password * the new password. */ public void setPassword(String password) { this.passwordChars = convertToCharArray(password); } /** * Set the current password in the form of a char array. * * @param password * the new password in the form of a char array. */ public void setPasswordChars(char[] password) { this.passwordChars = password; } private static char[] convertToCharArray(String s) { return s == null ? null : s.toCharArray(); } private static String convertToString(char[] a) { return a == null ? null : new String(a); } /** * Get the current password. * * @return the password */ public String getPassword() { return convertToString(passwordChars); } /** * Get the current user name. * * @return the user name */ public String getUser() { return userName; } /** * Set the current user name. * * @param user * the new user name */ public void setUser(String user) { this.userName = user; } /** * Get the current description. * * @return the description */ public String getDescription() { return description; } /** * Set the description. * * @param description * the new description */ public void setDescription(String description) { this.description = description; } /** * Get a new reference for this object, using the current settings. * * @return the new reference */ public Reference getReference() { String factoryClassName = JdbcDataSourceFactory.class.getName(); Reference ref = new Reference(getClass().getName(), factoryClassName, null); ref.add(new StringRefAddr("url", url)); ref.add(new StringRefAddr("user", userName)); ref.add(new StringRefAddr("password", convertToString(passwordChars))); ref.add(new StringRefAddr("loginTimeout", String.valueOf(loginTimeout))); ref.add(new StringRefAddr("description", description)); return ref; } /** * Open a new XA connection using the current URL, user name and password. * * @return the connection */ public XAConnection getXAConnection() throws SQLException { return new JdbcXAConnection(getJdbcConnection(userName, StringUtils.cloneCharArray(passwordChars))); } /** * Open a new XA connection using the current URL and the specified user name * and password. * * @param user * the user name * @param password * the password * @return the connection */ public XAConnection getXAConnection(String user, String password) throws SQLException { return new JdbcXAConnection(getJdbcConnection(user, convertToCharArray(password))); } /** * Open a new pooled connection using the current URL, user name and password. * * @return the connection */ public PooledConnection getPooledConnection() throws SQLException { return getXAConnection(); } /** * Open a new pooled connection using the current URL and the specified user * name and password. * * @param user * the user name * @param password * the password * @return the connection */ public PooledConnection getPooledConnection(String user, String password) throws SQLException { return getXAConnection(user, password); } /** * [Not supported] Return an object of this class if possible. * * @param iface * the class */ // ## Java 1.6 ## public <T> T unwrap(Class<T> iface) throws SQLException { throw JdbcException.getUnsupportedException("isWrapperFor unsupported"); } // */ /** * [Not supported] Checks if unwrap can return an object of this class. * * @param iface * the class */ // ## Java 1.6 ## public boolean isWrapperFor(Class<?> iface) throws SQLException { throw JdbcException.getUnsupportedException("isWrapperFor unsupported"); } // */ /** * [Not supported] */ public Logger getParentLogger() { throw new NotImplementedException(); } /** * INTERNAL */ public String toString() { return "JdbcDataSource : url=" + url + " user=" + userName; } }