/*
 * 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.hayabusa.resource;

import org.opengion.hayabusa.common.HybsSystem ;
import org.opengion.fukurou.system.DateSet;						// 6.4.2.0 (2016/01/29)
import org.opengion.fukurou.util.StringUtil ;
import org.opengion.fukurou.db.ApplicationInfo;
import org.opengion.fukurou.db.DBUtil;
import org.opengion.fukurou.security.HybsCryptography;
import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;	// 6.1.0.0 (2014/12/26) refactoring

/**
 * 指定のURLをランダムキー化したり、そのキーより実URLへ転送したりします。
 *
 * 通常のURLは、引数にキーとバリュー値をセットして文字列連結します。そのままでは
 * URLが長くなったり、引数の一部を書き換えたりできてしまいます。
 * このクラスでは、GE17(URL転送テーブル)に引数付きURLを登録するとともに、
 * ランダムキーを作成します。
 * また、このランダムキーを元にGE17を検索し、元のURLに転送する機能があります。
 *
 * @og.rev 4.0.0.0 (2004/12/31) 新規作成
 * @og.group リソース管理
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public final class URLXfer {

	// URL転送テーブル(GE17)にデータを書き込むためのSQLです。
	private static final String INSERT_SQL = "INSERT INTO GE17 (SYSTEM_ID,RANDOM_KEY,NAME_JA,DYVALID,REDIRECT_URL,"
											+ "FGJ,DYSET,DYUPD,USRSET,USRUPD,PGUPD) "
											+ " VALUES ( ?,?,?,?,?,'1',?,?,?,?,'URLXfer' )" ;

	// URL転送テーブル(GE17)からデータを読み込むためのSQLです。
	private static final String SELECT_SQL = "SELECT REDIRECT_URL FROM GE17"
											+ " WHERE SYSTEM_ID = ? AND RANDOM_KEY = ? AND DYVALID >= ?" ;

	private final String DBID		;		// ＵＲＬ転送テーブルアクセスの接続先
	private final String ADDRESS	;		// ＵＲＬ転送テーブルアクセスアドレス
	private final String SYSTEM_ID	;		// システムID

	/** コネクションにアプリケーション情報を追記するかどうか指定 */
	public static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;

	// 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
	private final ApplicationInfo appInfo;

	/**
	 * コンストラクター
	 *
	 * アドレスが存在しない場合は、初期化メソッドを呼び出します。
	 *
	 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
	 */
	public URLXfer() {
		DBID = HybsSystem.sys( "RESOURCE_DBID" );
		ADDRESS = StringUtil.nval(
								HybsSystem.sys( "RESOURCE_ADDRESS" ) ,
								HybsSystem.sys( "CONTEXT_URL" ) + "jsp/index.jsp"
					)  + "?XFER=";

		SYSTEM_ID = HybsSystem.sys( "SYSTEM_ID" );

		// 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
		if( USE_DB_APPLICATION_INFO ) {
			appInfo = new ApplicationInfo();
			// ユーザーID,IPアドレス,ホスト名
			appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
			// 画面ID,操作,プログラムID
			appInfo.setModuleInfo( "URLXfer",null,null );
		}
		else {
			appInfo = null;
		}
	}

	/**
	 * URL文字列のデータを元に、URLXferオブジェクトを構築します。
	 * データをGE17(URL転送テーブル)に登録するとともに、ランダムキーを作成(XFER)して、
	 * そのランダム引数を用いたアドレスを返します。
	 * アドレスは、システムパラメータ URL_XFER_ADDRESS + "?XFER=" + ランダムキーです。
	 *
	 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
	 * @og.rev 5.2.2.0 (2010/11/01) util.StringUtil から security.HybsCryptography へ移動
	 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
	 *
	 * @param	redirectURL	転送URL
	 * @param	name			表示名称
	 * @param	validDate		有効日時(yyyyMMdd)
	 * @param	userid		ユーザーID
	 *
	 * @return	RandomURL文字列
	 * @og.rtnNotNull
	 */
	public String getRandomURL( final String redirectURL,final String name,final String validDate,final String userid ) {

		final String DYSET = DateSet.getDate( "yyyyMMddHHmmss" );						// 6.4.2.0 (2016/01/29)
		final String key = redirectURL + Math.random() ;
		final String randomKey = HybsCryptography.getMD5( key );	// 5.2.2.0 (2010/11/01) クラス変更

		// 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
		final String validYMD  = validDate == null ? "99999999" : validDate ;

		final String[] args = new String[] { SYSTEM_ID,randomKey,name,validYMD,redirectURL,DYSET,DYSET,userid,userid };
		DBUtil.dbExecute( INSERT_SQL,args,appInfo,DBID );

		return ADDRESS + randomKey ;
	}

	/**
	 * ランダムキー(XFER)の文字列より、元のURLを検索します。
	 * データはランダムキーを元に、GE17(URL転送テーブル)より取り出します。
	 * 取り出す条件は、SYSTEM_ID 、RANDOM_KEY と DYVALID が 現在時刻より大きい場合です。
	 *
	 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
	 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
	 *
	 * @param	randomKey	ハッシュ化されたキー文字列
	 *
	 * @return RedirectURL文字列
	 */
	public String getRedirectURL( final String randomKey ) {
		final String nowDate = DateSet.getDate( "yyyyMMdd" );						// 6.4.2.0 (2016/01/29)

		final String[]   args = new String[] { SYSTEM_ID,randomKey,nowDate };
		final String[][] vals = DBUtil.dbExecute( SELECT_SQL,args,appInfo,DBID );

		// 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
		// 反転注意
		return vals == null || vals.length == 0 || vals[0] == null || vals[0].length == 0 ? null : vals[0][0];
	}

	/**
	 * オブジェクトの識別子として，詳細なユーザー情報を返します。
	 *
	 * @return  詳細なユーザー情報
	 * @og.rtnNotNull
	 */
	@Override
	public String toString() {
		final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
			.append( "DBID :"		).append( DBID )
			.append( " ADDRESS :"	).append( ADDRESS )
			.append( " SYSTEM_ID :"	).append( SYSTEM_ID );
		return rtn.toString();
	}
}
