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

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.opengion.fukurou.db.Transaction;
import org.opengion.fukurou.db.TransactionReal;
import org.opengion.fukurou.transfer.TransferConfig;
import org.opengion.fukurou.transfer.TransferExec;
import org.opengion.fukurou.db.ApplicationInfo;
import org.opengion.fukurou.util.StringUtil;
import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.hayabusa.common.HybsSystemException;

/**
 * RemoteControllableインタフェイスを実装した
 * サーブレット経由で遠隔伝送実行処理を行うためのクラスです。
 *
 * このクラスは、伝送実行処理のラッパークラスです。
 * 引数のKBEXECのパラメーターに基づき、伝送実行オブジェクトを生成し、伝送処理を実行します。
 * <del>6.3.9.0 (2015/11/06)詳細については、{@link org.opengion.fukurou.transfer.TransferExec_HTTP}を参照して下さい。</del>
 * 詳細については、{@link org.opengion.fukurou.transfer.AbstractTransferExecHTTP}を参照して下さい。
 *
 * @og.rev 5.4.2.0 (2011/12/01) 新規作成
 *
 * @version  4.1
 * @author   Hiroki Nakamura
 * @since    JDK6.0,
 *
 */
public class TransferExecWrapper implements RemoteControllable {

	// 伝送実行クラスのベースクラス名
	private static final String EXEC_CLASS_BASE = "org.opengion.fukurou.transfer.TransferExec_" ;

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

	private static final ApplicationInfo APP_INFO;		// 6.4.1.1 (2016/01/16) appInfo → APP_INFO refactoring

	static {
		if( USE_DB_APPLICATION_INFO ) {
			APP_INFO = new ApplicationInfo();
			// ユーザーID,IPアドレス,ホスト名
			APP_INFO.setClientInfo( "TransferExecWrapper",HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
			// 画面ID,操作,プログラムID
			APP_INFO.setModuleInfo( "TransferExecWrapper","TransferExecWrapper","TransferExecWrapper" );
		}
		else {
			APP_INFO = null;
		}
	}

	/**
	 * デフォルトコンストラクター
	 *
	 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
	 */
	public TransferExecWrapper() {
		super();		// これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
	}

	/**
	 * RemoteControllableインタフェイスの実装メソッドです。
	 *
	 * @og.rev 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
	 * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
	 *
	 * @param	valMap	 サーブレットが受け取ったキーと値のマップ
	 *
	 * @return	XML形式の実行結果
	 * @og.rtnNotNull
	 */
	public String remoteControl( final Map<String,String> valMap ) {
		// パラメーターより伝送設定オブジェクトを生成します。
		final TransferConfig conf = new TransferConfig(
								valMap.get( "KBREAD" )
								, valMap.get( "READOBJ" )
								, valMap.get( "READPRM" )
								, valMap.get( "KBEXEC" )
								, valMap.get( "EXECDBID" )
								, valMap.get( "EXECOBJ" )
								, valMap.get( "EXECPRM" )
								, valMap.get( "ERROR_SENDTO" )
								, valMap.get( "HFROM" )
								, null, -1 );

		// パラメーターより伝送実行オブジェクトに渡す値一覧(配列)を生成します。
		final String[] vals = getVals( valMap );

//		Transaction tran = null;
//		try {
//			tran = new TransactionReal( APP_INFO );
		try( final Transaction tran = new TransactionReal( APP_INFO ) ) {
			// 実行方法のオブジェクトを生成します。
			final TransferExec exec = (TransferExec)StringUtil.newInstance( EXEC_CLASS_BASE + valMap.get( "KBEXEC" ) );
			// 処理を実行します。
			exec.execute( vals, conf, tran );
			tran.commit();				// 6.3.6.1 (2015/08/28)
		}
		catch ( Throwable ex ) {
			// 6.3.6.1 (2015/08/28) tran.commit() されない場合は、rollback() される。
			final String errMsg = "伝送処理実行(HTTP経由)でエラーが発生しました。";
			throw new HybsSystemException( errMsg, ex );	// 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
		}
//		finally {
//			if( tran != null ) { tran.close(); }
//		}

		return "";
	}

	/**
	 * パラメーターより伝送実行オブジェクトに渡す値一覧(配列)を生成します。
	 * 対象パラメーターは①n(データ件数) と ②v1～vn(データ) です。
	 *
	 * @param valMap パラメーターMap
	 *
	 * @return 値一覧(配列)
	 * @og.rtnNotNull
	 */
	private String[] getVals( final Map<String,String> valMap ) {
		int rows = 0;
		final String rno = valMap.get( "n" );
		if( rno != null && rno.length() > 0 ) {
			rows = Integer.parseInt( rno );		// 6.0.2.4 (2014/10/17) メソッド間違い
		}
		final List<String> list = new ArrayList<>();
		for( int i=0; i<rows; i++ ) {
			final String val = valMap.get( "v" + i );
			list.add( val );
		}
		return list.toArray( new String[list.size()] );
	}
}
