/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JSCCommonUtil
*   ソースファイル名：JSCCommonUtil.java
*   作成者          ：富士通
*   日付            ：2011年06月03日
*＜機能概要＞
*   サービス制御管理システムの共通処理クラスです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2011/06/03   FJ          新規作成
*
**********************************************************************/
package eo.common.util;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.base.CAANMsg;

/**
 * サービス制御管理システム共通処理
 * @author 富士通
 *
 */
public class JSCCommonUtil extends JPCUtilCommon
{
	
	/**
	 * オブジェクトに値が設定されているか判定します。
	 * <br>
	 * @param test 判定するオブジェクト
	 * @return オブジェクトに値が設定されていない場合はtrue
	 */
	public static boolean isNull(Object test)
	{
		return JPCCommonUtil.isNull(test);
	}
	

	/**
	 * 有効なパラメータか判定します。
	 * 文字列に値が設定されていない場合はエラーとします。
	 * <br>
	 * @param test 判定するオブジェクト
	 * @return パラメータが不正な場合はfalse
	 */
	public static boolean isValidParameter(Object test) 
	{
		return JPCCommonUtil.isValidParameter(test);
	}

	
	/**
	 * 有効なパラメータか判定します。
	 * 文字列に値が設定されていない場合、及び指定された桁数と
	 * 一致しない場合はエラーとします。
	 * <br>
	 * @param test 判定する文字列
	 * @param level 文字列として有効な桁数
	 * @return パラメータが不正な場合はfalse
	 */
	public static boolean isValidParameter(String test, int level) 
	{
		return JPCCommonUtil.isValidParameter(test, level);
	}
	
	
	/**
	 * 件数取得用のSQLを生成します。
	 * @param innerSql 元のSQL
	 * @return 件数取得用SQL
	 */
	public static String makeSqlForCount(String innerSql)
	{
		return makeSqlForCount(innerSql, "CNT");
	}

	/**
	 * 件数取得用のSQLを生成します。
	 * @param innerSql 元のSQL
	 * @param countAlias カウンタのエイリアス
	 * @return 件数取得用SQL
	 */
	public static String makeSqlForCount(String innerSql, String countAlias)
	{
		StringBuffer sql = new StringBuffer();
		
		sql.append(String.format("SELECT COUNT(*) %s FROM (", countAlias))
			.append(innerSql)
			.append(")");
		
		return sql.toString();
	}
	
	
	/**
	 * 範囲検索用のSQLを生成します。
	 * @param innersql 元のSQL
	 * @param columnPrefix 取得対象カラムのプリフィックス
	 * @param rowNumAlias
	 * @return 生成SQL
	 */
	public static String makeSqlForRealm(String innersql, String columnPrefix, String rowNumAlias)
	{
		StringBuffer sql = new StringBuffer();
		String prefix = columnPrefix.toUpperCase();
		
		String[] sqlFragments = innersql.split(" ");
		List<String> selections = new ArrayList<String>();
		for (String sqlFragment : sqlFragments)
		{
			if (!sqlFragment.toUpperCase().startsWith(prefix + "_"))
			{
				continue;
			}
			
			selections.add(chompForSqlSelection(sqlFragment));
		}
		
		String tableName = "TAB_ORGSQL";
		StringBuffer selection = new StringBuffer();
		boolean first = true;
		for (String col : selections)
		{
			if (!first)
			{
				selection.append(",");
			}

			String realColumnName = col.substring(prefix.length() + 1, col.length());
			selection.append(String.format("%s.%s %s", tableName, col, realColumnName));
			first = false;
		}
		
		sql.append("SELECT ")
		.append(selection.toString())
		.append(" FROM (")
			.append(innersql)
			.append(") ")
			.append(tableName)
		.append(" WHERE")
		.append(String.format(" %s.%s BETWEEN ? AND ?", tableName, rowNumAlias));
		
		return sql.toString();
	}
	
	/**
	 * 英数字、＿の以外の文字を削除します。
	 * @param str 文字列
	 * @return strから英数字と＿のみを選択したもの
	 */
	private static String chompForSqlSelection(String str)
	{
		StringBuffer sb = new StringBuffer();
		
		for (Character c : str.toCharArray())
		{
			if (Character.isLetter(c)
				||Character.isDigit(c)
				|| c == '_')
			{
				sb.append(c);
			}
		}
		
		return sb.toString();
	}

	/**
	 * inMgsのkeyに何か値があればsqlにwhereを追加します。
	 * @param key キー
	 * @param where where句
	 * @param inMsg インプットデータ
	 * @param sql SQL
	 */
	public static void appendSqlIfAnyInput(String key, String where, CAANMsg inMsg, StringBuffer sql)
	{
		if (inMsg.isNull(key))
		{
			return ;
		}
		
		sql.append(" AND " + where + " ");
	}

	
	/**
	 * inMsgのkeyに何らかの値があればstatementのindex番目に当該値を設定します。
	 * 値の設定に成功すると、次のインデックス値を返します。
	 * @param key キー
	 * @param index インデックス
	 * @param inMsg インプットデータ
	 * @param statement ステートメント
	 * @return 次のインデックス
	 * @throws SQLException 例外発生時
	 */
	public static int appendParamIfAnyInput(String key, int index, CAANMsg inMsg, PreparedStatement statement) throws SQLException
	{
		if (inMsg.isNull(key))
		{
			return index;
		}
		
		String param = inMsg.getString(key);
		CAANJDBCUtil.setParam(statement, index, param);
		return index + 1;
	}
	

	
	/**
	 * 指定された文字列の配列をseparatorで結合します。
	 * @param separator 結合文字列
	 * @param strs 結合する文字列
	 * @return 結合された文字列
	 */
	public static String join(String separator, String...strs)
	{
		StringBuffer sb = new StringBuffer();
		
		boolean isFirst = true;
		for (String str : strs)
		{
			if (!isFirst)
			{
				sb.append(separator);
			}
			
			sb.append(str);
			isFirst = false;
		}
		
		return sb.toString();
	}
	
	/**
	 * <p>
	 * null文字なら""を返却する
	 * </p>
	 * @param inStr 処理対象のCBSMsg
	 * @return String 
	 */
	public static String nullToString(Object inStr)
	{
		return (null == inStr ? "" : (String)inStr);
		
	}

}
