/*
 * CopyRight(C) 2003, NTT All rights reserved
 *
 *	XMS2データベーステーブルの作成
 *		変更履歴
 *			2004.01.08  新規作成  二條智文
 *
 *	XMS2データベーステーブルを新規作成します。
*/

import java.sql.*;
import java.io.*;

public class DBSet {

	// ユーザ名を保持する
	private String USER_NAME;
	// パスワードを保持する
	private String USER_PASSWORD;
	// DB名を保持する
	private String DB_NAME;
	// DBポートを保持する
	private String DB_PORT;
	// サーバ名を保持する
	private String DB_SERVER;
	// XMS2インストールディレクトリを保持する
	private String XMS2_DIR;
	// SMTFインストールフラグを保持する
	private String SMTF_FLAG;

	// Perceptionインストールフラグを保持する
	private String PCT_FLAG;
	// Offlineインストールフラグを保持する
	private String OFL_FLAG;

	// ユーザオプション
	private static String USER_NAME_OPTION = "-U";
	// パスワードオプション
	private static String USER_PASSWORD_OPTION = "-P";
	// DB名オプション
	private static String DB_NAME_OPTION = "-D";
	// DBポートオプション
	private static String DB_PORT_OPTION = "-p";
	// サーバ名オプション
	private static String DB_SERVER_OPTION = "-S";
	// XMS2インストールディレクトリオプション
	private static String XMS2_DIR_OPTION = "-i";
	// SMTFインストールフラグオプション
	private static String SMTF_FLAG_OPTION = "-sm";

	// Perceptionインストールフラグオプション
	private static String PCT_FLAG_OPTION = "-pc";

	// Offlineインストールフラグオプション
	private static String OFL_FLAG_OPTION = "-ol";

	// ドライバ名
	private static final String DRIVER_NAME = "com.microsoft.jdbc.sqlserver.SQLServerDriver";

	// SQL区切り文字列
	private static final String SQL_TOKEN = "GO";

	// DBコネクション
	private Connection connection;

	// SQL定義ファイル名
	private String[] DBSET_FILE = {
									"CreateDB.sql",
									"CreateUser.sql",
									"CreateTB.sql",
									"CreateIDX.sql",
									"InsertTB_GroupAndPeople.sql",
									"InsertTB_Groups.sql",
									"InsertTB_LO.sql",
									"InsertTB_LORelation.sql",
									"InsertTB_LOType.sql",
									"InsertTB_People.sql",
									"InsertTB_RoleAssignments.sql",
									"InsertTB_Roles.sql",
									"InsertTB_RolesFunction.sql",
									"InsertTB_XMOEntry.sql",
									"InsertTB_XmoRelation.sql",
									"lomu.sql"
								};

// SQLビュー定義ファイル名
	private String[] VIEWSET_FILE = {
									"Create_v_LOList.sql",
									"Create_v_UserList.sql"
	};
	
	// SmartForce SQL定義ファイル
	private String SMTF_FILE = "InsertTB_LOType_SMTF.sql";

	// Perception SQL定義ファイル
	private String PCT_FILE = "InsertTB_LOType_PCT.sql";

	// Offline SQL定義ファイル
	private String OFL_FILE = "InsertTB_LOType_OFL.sql";

	/**
	 * メイン関数
	 * コマンドラインより以下の引数を取得します。
	 * -U ユーザ
	 * -P パスワード
	 * -D DB名
	 * -p DBポート
	 * -S DBサーバ名
	 * -i XMS2インストールディレクトリ
	 */
	public static void main(String[] args) {
		String userName = null;
		String password = null;
		String dbName = null;
		String dbPort = null;
		String dbServer = null;
		String xms2Dir = null;
		String smtfFlag = null;
		String pctFlag = null;
		String oflFlag = null;

		// 引数チェック
		for( int i = 0; i < args.length; i++ ) {
			if( args[i].charAt(0) == '-' ) {
				String option = args[i];
				String value = "";
				try {
					if( args[i+1].charAt(0) != '-' ) {
						value = args[i+1];
					}
				}
				catch( ArrayIndexOutOfBoundsException ae ) {
				}
				if( option.equals( USER_NAME_OPTION ) ) {
					userName = value;
				}
				else if( option.equals( USER_PASSWORD_OPTION ) ) {
					password = value;
				}
				else if( option.equals( DB_NAME_OPTION ) ) {
					dbName = value;
				}
				else if( option.equals( DB_PORT_OPTION ) ) {
					dbPort = value;
				}
				else if( option.equals( DB_SERVER_OPTION ) ) {
					dbServer = value;
				}
				else if( option.equals( XMS2_DIR_OPTION ) ) {
					xms2Dir = value;
				}
				else if( option.equals( SMTF_FLAG_OPTION ) ) {
					smtfFlag = value;
				}
				else if( option.equals( PCT_FLAG_OPTION ) ) {
					pctFlag = value;
				}
				else if( option.equals( OFL_FLAG_OPTION ) ) {
					oflFlag = value;
				}
			}
		}

		// 1つでもnullがあったらエラー
		if( userName == null || password == null || dbName == null ||
			dbPort == null || dbServer == null || xms2Dir == null || smtfFlag == null || pctFlag== null || oflFlag== null)
		{
			// 異常終了
			System.exit(1);
		}

		// インスタンス生成
		try {
			DBSet dbSet = new DBSet(userName, password, dbName,
									dbPort, dbServer, xms2Dir, smtfFlag, pctFlag, oflFlag);
			dbSet.setDB();
		}
		catch(ClassNotFoundException ce) {
			ce.printStackTrace();
			// JDBCドライバーが存在しない
			System.exit(1);
		}
		catch(FileNotFoundException fe) {
			fe.printStackTrace();
			// ファイルが存在しない場合
			System.exit(1);
		}
		catch(IOException ie) {
			ie.printStackTrace();
			// ファイル読み込み例外
			System.exit(1);
		}
		catch(SQLException se) {
			se.printStackTrace();
			// SQL例外
			System.exit(1);
		}

		// 正常終了
		System.exit(0);
	}
	/**
	 * コンストラクタ
	 * @param userName ユーザ名
	 * @param password パスワード
	 * @param dbName DB名
	 * @param dbServer DBサーバ
	 * @param xms2_dir XMS2インストールディレクトリ
	 * @param smtfFlag SmartForceインストールフラグ
	 * @param pctFlag Perceptionインストールフラグ
	 */
	private DBSet(	String userName,
					String password,
					String dbName,
					String dbPort,
					String dbServer,
					String xms2_dir,
					String smtfFlag,
					String pctFlag,
					String oflFlag )
		throws SQLException, ClassNotFoundException
	{
		USER_NAME = userName;
		USER_PASSWORD = password;
		DB_NAME = dbName;
		DB_PORT = dbPort;
		DB_SERVER = dbServer;
		XMS2_DIR = xms2_dir + "/table/";
		SMTF_FLAG = smtfFlag;
		PCT_FLAG = pctFlag;
		OFL_FLAG = oflFlag;
		
		connection = getConnection();
		connection.setAutoCommit( false );
	}

	/**
	 * DB設定を行います。
	 * @exception SQLException SQL例外
	 * @exception IOException ファイル読み込み例外
	 * @exception FileNotFoundException ファイルが存在しない場合
	 */
	private void setDB()
		throws SQLException, IOException, FileNotFoundException
	{
		// Statement取得
		Statement statement = connection.createStatement();

		String strFilePath = "";
		String strSQL = "";

		// SQLファイル定義ファイル分処理を繰り返す
		try {
			for( int i = 0; i < DBSET_FILE.length; i++ ) {
				strFilePath = XMS2_DIR + DBSET_FILE[i];
				strSQL = loadFile( strFilePath );
				statement.execute( strSQL );
			}

			// スマートフォース
			if( !SMTF_FLAG.equals( "OFF" ) ) {
				strFilePath = XMS2_DIR + SMTF_FILE;
				strSQL = loadFile( strFilePath );
				statement.execute( strSQL );
			}

			// Perception
			if( !PCT_FLAG.equals( "OFF" ) ) {
				strFilePath = XMS2_DIR + PCT_FILE;
				strSQL = loadFile( strFilePath );
				statement.execute( strSQL );
			}
			// Offline
			if( !OFL_FLAG.equals( "OFF" ) ) {
				strFilePath = XMS2_DIR + OFL_FILE;
				strSQL = loadFile( strFilePath );
				statement.execute( strSQL );
			}

			connection.commit();

			//Viewの追加のために、テーブルをコミット後実行する
			for( int i = 0; i < VIEWSET_FILE.length; i++ ) {
				strFilePath = XMS2_DIR + VIEWSET_FILE[i];
				strSQL = loadFile( strFilePath );
				statement.execute( strSQL );
			}
			connection.commit();

		}
		catch( FileNotFoundException fe ) {
			// ロールバック
			try { connection.rollback();
			} catch( Exception e) {}
			throw fe;
		}
		catch( IOException ie ) {
			// ロールバック
			try { connection.rollback();
			} catch( Exception e) {}
			throw ie;
		}
		catch( SQLException se ) {
			// ロールバック
			try { connection.rollback();
			} catch( Exception e) {}
			throw se;
		}
		finally {
			try {	statement.close();
					connection.close();
			} catch( Exception e) {}
		}

	}

	/**
	 * ファイルロード<BR>
	 * ファイル中の"GO"は読み飛ばします
	 * @param ファイルパス
	 * @return String ファイル内容
	 * @exception IOException ファイル読み込み例外
	 * @exception FileNotFoundException ファイルが存在しない場合
	 */
	private String loadFile( String strFilePath )
		throws IOException, FileNotFoundException
	{
		BufferedReader reader = new BufferedReader(new FileReader( strFilePath ));

		StringBuffer sbFile = new StringBuffer();
		String strLine = null;
		while( (strLine = reader.readLine()) != null ) {
			if(!strLine.trim().equals( SQL_TOKEN )) {
				sbFile.append( strLine + "\n");
			}
		}

		return new String(sbFile);
	}

	private Connection getConnection()
		throws SQLException, ClassNotFoundException
	{
		// ドライバの設定
		Class.forName(DRIVER_NAME);

		// 接続文字列生成
		String strCon = "jdbc:microsoft:sqlserver://" + DB_SERVER + ":" + DB_PORT;

		// コネクションを取得します
		Connection con = DriverManager.getConnection(strCon,USER_NAME,USER_PASSWORD);

		return con;
	}
}