/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * Licensed 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 woolpack.sql.adapter;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.sql.DataSource;

/**
 * {@link DriverManager}を利用する{@link DataSource}です。
 * <br/>適用しているデザインパターン：Adapter。
 * @author nakamura
 *
 */
public class DriverManagerDataSource implements DataSource {
	private String className;
	private String url;
	private String user;
	private String password;
	private boolean anonymousConnectFlag;
	
	/**
	 * 
	 * @param className ドライバのクラス名。
	 * @param url 接続先のURL文字列。
	 * @param user データベースのユーザ。
	 * @param password ユーザのパスワード。
	 * @param anonymousConnectFlag {@link #getConnection()}実行時に{@link DriverManager#getConnection(String)}を使用するならtrue、{@link DriverManager#getConnection(String, String, String)}を使用するならfalse。
	 */
	public DriverManagerDataSource(
			final String className,
			final String url,
			final String user,
			final String password,
			final boolean anonymousConnectFlag) {
		this.className = className;
		this.url = url;
		this.user = user;
		this.password = password;
		this.anonymousConnectFlag = anonymousConnectFlag;
	}

	/**
	 * {@link #getConnection()}実行時に{@link DriverManager#getConnection(String, String, String)}を使用します。
	 * @param className ドライバのクラス名。
	 * @param url 接続先のURL文字列。
	 * @param user データベースのユーザ。
	 * @param password ユーザのパスワード。
	 */
	public DriverManagerDataSource(
			final String className,
			final String url,
			final String user,
			final String password) {
		this(className, url, user, password, false);
	}
	
	/**
	 * {@link #getConnection()}実行時に{@link DriverManager#getConnection(String)}を使用します。
	 * @param className ドライバのクラス名。
	 * @param url 接続先のURL文字列。
	 */
	public DriverManagerDataSource(
			final String className,
			final String url) {
		this(className, url, null, null, true);
	}
	
	private void loadClass() throws SQLException {
		try {
			Class.forName(className);
		} catch (final ClassNotFoundException e0) {
			final SQLException e1 = new SQLException(e0.getMessage());
			e1.initCause(e0);
			throw e1;
		}
	}

	public Connection getConnection() throws SQLException {
		loadClass();
		if (anonymousConnectFlag) {
			return DriverManager.getConnection(url);
		} else {
			return DriverManager.getConnection(url, user, password);
		}
	}

	public Connection getConnection(final String username, final String password) throws SQLException {
		loadClass();
		return DriverManager.getConnection(url, username, password);
	}

	public PrintWriter getLogWriter() throws SQLException {
		return DriverManager.getLogWriter();
	}

	public int getLoginTimeout() throws SQLException {
		return DriverManager.getLoginTimeout();
	}

	public void setLogWriter(final PrintWriter out) throws SQLException {
		DriverManager.setLogWriter(out);
	}

	public void setLoginTimeout(final int seconds) throws SQLException {
		DriverManager.setLoginTimeout(seconds);
	}

	public boolean isAnonymousConnectFlag() {
		return anonymousConnectFlag;
	}
	public void setAnonymousConnectFlag(boolean anonymousConnectFlag) {
		this.anonymousConnectFlag = anonymousConnectFlag;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(final String className) {
		this.className = className;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(final String password) {
		this.password = password;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(final String url) {
		this.url = url;
	}
	public String getUser() {
		return user;
	}
	public void setUser(final String user) {
		this.user = user;
	}
}
