Package com.alibaba.wasp.jdbcx

Source Code of com.alibaba.wasp.jdbcx.JdbcDataSource

/**
* 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(&quot;jdbc:wasp:&tilde;/test&quot;);
* ds.setUser(&quot;sa&quot;);
* ds.setPassword(&quot;sa&quot;);
* Context ctx = new InitialContext();
* ctx.bind(&quot;jdbc/dsName&quot;, 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(&quot;jdbc/dsName&quot;);
* 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;
  }

}
TOP

Related Classes of com.alibaba.wasp.jdbcx.JdbcDataSource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.