/*
 * Copyright (c) 2009 The openGion Project.
 *
 * 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 org.opengion.fukurou.process;

import org.opengion.fukurou.util.ApplicationInfo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.DatabaseMetaData;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * ConnData は、Connection を管理する、独立したDB接続実装クラスです。
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public final class ConnData {
	/** 実行しているサーバーの名称 */
	private static final String HOST_NAME ;
	/** 実行しているサーバーのIPアドレス */
	private static final String HOST_ADRS ;

	static {
		String dmnHost ;
		String dnmAdrs ;
		try {
			InetAddress address = InetAddress.getLocalHost();
			dmnHost = address.getHostName() ;
			dnmAdrs = address.getHostAddress() ;
		}
		catch( UnknownHostException e ) {
			dmnHost = "Unknown";
			dnmAdrs = "Unknown";
		}
		HOST_NAME = dmnHost;
		HOST_ADRS = dnmAdrs;
	}

	private final boolean useAppInfo ;
	private final Connection connection ;
	private final int uniq;
	private final long createTime;
	private final String info ;

	/**
	 * 引数を指定してのコンストラクター
	 *
	 * @og.rev 5.1.1.0 (2009/12/01) MySQL対応 明示的に、TRANSACTION_READ_COMMITTED を指定する。
	 *
	 * @param	url		String	接続先URL
	 * @param	user	String	接続ユーザー
	 * @param	passwd	String	パスワード
	 * @param	uniq	int		内部的なユニークコード
	 */
	public ConnData( final String url,final String user, final String passwd,final int uniq ) {
		createTime = System.currentTimeMillis();
		this.uniq = uniq ;

		try {
			connection = DriverManager.getConnection( url, user, passwd );
			connection.setAutoCommit( false );
			connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);  // 5.1.1.0 (2009/12/01)

			DatabaseMetaData meta = connection.getMetaData();
			String productName  = meta.getDatabaseProductName();
			useAppInfo = "ORACLE".equalsIgnoreCase( productName ) ;
		}
		catch (SQLException ex) {
			String errMsg = "Connection の作成に失敗しました。[" + url + "],[" + user + "]";
			throw new RuntimeException( errMsg,ex );
		}

		info = url + "," + user + " (" + createTime + ")" ;
	}

	/**
	 * 管理しているコネクションを返します。
	 *
	 * @return	Connection
	 */
	public Connection getConnection() { return connection; }

	/**
	 * 管理している接続先のユニークキーを返します。
	 *
	 * @return	int
	 */
	public int getUniq() { return uniq; }

	/**
	 * 管理している接続先の作成時刻を返します。
	 *
	 * @return	long
	 */
	public long getCreateTime() { return createTime; }

	/**
	 * データベース接続に内部情報を設定します。
	 * 処理は、ApplicationInfo オブジェクトの適用です。
	 *
	 * @param   user String DB接続履歴取得用の実行ユーザー
	 * @param   pgid String DB接続履歴取得用の実行プログラムID
	 */
	public void makeApplicationInfo( final String user,final String pgid ) {
		if( useAppInfo ) {
			ApplicationInfo appInfo = new ApplicationInfo();
			// JavaVM 起動時のユーザーID,IPアドレス,ホスト名をセットします。
			appInfo.setClientInfo( user,HOST_ADRS,HOST_NAME );

			// 画面ID,操作,プログラムID
			appInfo.setModuleInfo( pgid,null,"ConnData" );

			appInfo.callAppInfo( connection );
		}
	}

	/**
	 * このオブジェクトの内部文字列表現を返します。
	 *
	 * 接続URL + "," + 接続ユーザー + " (" + 作成日付 + ")" です。
	 *
	 * @return 内部文字列表現
	 */
	public String toString() {
		return info ;
	}
}
