/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JFUXMLPropertyCache
*   ソースファイル名：JFUXMLPropertyCache.java
*   作成者          ：富士通
*   日付            ：2011年06月02日
*＜機能概要＞
*   XML定義ファイルキャッシュ部品です。
*   プロパティ値のキャッシュとリアルタイム読み込み可能です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2011/06/02   FJ）和田    新規作成
*   v15.00.00   2015/10/14   FJ）西川   【OM-2015-0002416】XML情報の欠落事象対応
*   v42.00.00   2019/05/15   FJ)大島    【ANK-3642-00-00】スマートリンクタブレット新機種追加（2019年6月〜）
*   v47.00.00   2019/09/26   FJ）大島   【ANK-3715-00-00】提供条件リリース対応
*
**********************************************************************/
package eo.web.webview.common;

import java.io.File;
import java.util.ArrayList;
import java.util.Map;

import org.w3c.dom.Attr;
import org.w3c.dom.NodeList;

import com.fujitsu.futurity.common.JCMPropertyCache;
import com.fujitsu.futurity.common.JSYLogBase;
import com.fujitsu.futurity.common.JSYwebLog;
import com.fujitsu.futurity.web.x00.JCCBusinessException;

import eo.common.constant.JFUStrConst;

/**
 * XML定義ファイルキャッシュ部品です。
 * <br>
 * @author 富士通
 */
public abstract class JFUXMLPropertyCache extends JCMPropertyCache
{
	/** XPath操作Manager */
	private JFUXPathManager manager = null;

	/** XMLファイルパス */
	private String filePath = null;

	/**
	 * プロパティファイルの読み込みを行います。<br>
	 * 読み込んだファイルの情報は、メモリー上にキャッシュします。
	 * <br>
	 * @return 値。指定値が無ければnull。
	 * @throws Exception 読込時に発生する例外
	 */
	@Override
	protected void loadProperties() throws Exception
	{
		String filePath = this.getFilePath();
		// Fileオブジェクト
		File file = new File(filePath);

		long size = file.length();
		long lastModified = file.lastModified();

		if (super.curTimestamp != lastModified || super.curFileSize != size)
		{
			// 初回のアクセス、タイムスタンプの変更、又は物理ファイルサイズの変更の場合

			if (this.manager != null)
			{
				// XML文書全体のサイズチェックを未実施に変更する。
				this.manager.setCheckXmlSize(false);
			}
		}

		if (this.manager == null || !this.manager.isCheckXmlSize())
		{
			// XML文書全体のサイズチェックが未実施の場合
			outputBusLog("INFO：※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※");

			if (this.manager == null)
			{
				outputBusLog("INFO：●ファイル読込 (初回アクセス時)");
			}
			else if (super.curFileSize != size)
			{
				outputBusLog("INFO：●ファイル読込 (ファイルサイズが不一致)");
			}
			else if (super.curTimestamp != lastModified)
			{
				outputBusLog("INFO：●ファイル読込 (タイムスタンプが不一致)");
			}
			else
			{
				outputBusLog("INFO：●ファイル読込 (メモリー上と読込ファイルのXMLサイズが不一致)");
			}
			outputBusLog("INFO：　クラス名＝【" + super.getClass() + "】");
			outputBusLog("INFO：　パス＝【" + getFilePath() + "】タイムスタンプ＝【" + lastModified + "】サイズ[B]＝【" + size + "】");

			for (int i = 0; i < 3; i++)
			{
				// 最大3回対象ファイルの読込を実施する。

				if (this.manager != null && this.manager.isCheckXmlSize() && i == 2)
				{
					// XML文書全体のサイズチェックが実施済の場合

					// 処理を抜ける。
					break;
				}
				else
				{
					// XML文書全体のサイズチェックが未実施の場合
					int readCnt = i + 1;
					outputBusLog("INFO：　【" + readCnt + "回目】 開始");

					// ファイルの再読込
					this.setManager(new JFUXPathManager(filePath, this.manager == null ? null : this.getManager().getDocument()));

					super.curFileSize = size;
					super.curTimestamp = lastModified;
				}
			}

			if (this.manager != null && !this.manager.isCheckXmlSize())
			{
				// 最大3回対象ファイルの読込でXML文書全体のサイズチェックが実施済にならない場合
				outputBusLog("ERROR：メモリー上と読込ファイルのXMLサイズが不一致の為、エラー画面へ遷移。");
				outputBusLog("INFO：※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※");

				// システムエラー画面に遷移する。
				throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
			}
			outputBusLog("INFO：※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※");
		}
	}

	/**
	 * 引数のクエリを使用し指定した要素が存在するかを確認し返却します。
	 * <br>
	 * @param query クエリ
	 * @return 評価結果
	 * @throws Exception XML解析時に発生する例外
	 */
	public boolean isElement(String query) throws Exception
	{
		return this.getManager().isElement(query.replace("/text()", ""));
	}

	/**
	 * 引数のクエリを使用し指定した要素を文字列として取得し返却します。
	 * <br>
	 * @param query クエリ
	 * @return アイテム
	 * @throws Exception XML解析時に発生する例外
	 */
	public String getItem(String query) throws Exception
	{
		return this.getManager().getItem(query);
	}

	/**
	 * 引数のクエリを使い取得したNodeListの属性値をキーに、要素をバリューとして保持したMapを返却します。
	 * <br>
	 * @param query クエリ
	 * @param attrName 属性名
	 * @return Mapオブジェクト
	 * @throws Exception XML解析時に発生する例外
	 */
	public Map<String, String> getItemsAsMap(String query, String attrName) throws Exception
	{
		return this.getManager().getItemsAsMap(query, attrName);
	}

	/**
	 * 引数のクエリを使い取得したNodeListの属性名の値を返却します。
	 * <br>
	 * @param query クエリ
	 * @param attrName 属性名
	 * @return 属性値
	 * @throws Exception XML解析時に発生する例外
	 */
	public String getAttrVal(String query, String attrName) throws Exception
	{
		return this.getManager().getAttrVal(query, attrName);
	}

// ANK-3642-00-00 ADD START
	/**
	 * 引数のクエリを使い取得し取得したノードリストを返却します。
	 * @param query クエリ
	 * @return NodeList
	 */
	public NodeList getItemAsNodeList(String query) throws Exception
	{
		return this.getManager().getItemAsNodeList(query);
	}
// ANK-3642-00-00 ADD END
	
// ANK-3715-00-00 ADD START
	/**
	 * 引数のクエリを使い取得し取得した属性値一覧を返却します。
	 * @param query クエリ
	 * @param attrName 属性名
	 * @return ArrayList<String>
	 */
	public ArrayList<String> getAttrList(String query, String attrName) throws Exception
	{
		return this.getManager().getAttrList(query, attrName);
	}
// ANK-3715-00-00 ADD END
	
	/**
	 * XPath操作manager部品を設定します。
	 * <br>
	 * @param arg0
	 */
	protected void setManager(JFUXPathManager arg0)
	{
		this.manager = arg0;
	}

	/**
	 * XPath操作manager部品を取得します。
	 * <br>
	 * @return XPath操作managerオブジェクト
	 */
	protected JFUXPathManager getManager()
	{
		return manager;
	}

	/**
	 * ファイルパスを設定します。
	 * <br>
	 * @param arg0
	 */
	protected void setFilePath(String arg0)
	{
		this.filePath = arg0;
	}

	/**
	 * ファイルパスを取得します。
	 * <br>
	 * @return ファイルパス
	 */
	protected String getFilePath()
	{
		return filePath;
	}

//	/**
//	 * メモリーサイズを出力
//	 * 
//	 * <br>
//	 * @param msg 可変メッセージ
//	 * @throws Exception
//	 */
//	private void outputMem(String msg) throws Exception
//	{
//		Runtime memory = Runtime.getRuntime();
//		outputBusLog("INFO：　メモリー状況：ファイル読込"+ msg +"：空き[KB]＝【" + (int)memory.freeMemory() / 1024 + "】使用[KB]＝【" + (int)(memory.totalMemory() - memory.freeMemory()) / 1024 + "】");
//	}

	/**
	 * ビジネスログへの出力処理
	 *
	 * @param msg ログ情報
	 */
	protected void outputBusLog(String msg) throws Exception
	{
		JSYwebLog.println(JSYLogBase.EXECUTION, getClass(), msg, "CS0003I", null, null);
	}
}
