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

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

import org.opengion.fukurou.xml.JspParserFilter;
import org.opengion.fukurou.xml.OGDocument;
import org.opengion.fukurou.xml.OGElement;
import org.opengion.fukurou.xml.OGNode;

import org.opengion.fukurou.util.FileUtil;

/**
 * コンストラクタに引数で与えられたマスタデータ情報を元に、特定のJSPタグ情報を生成する基底クラス。
 * マスタデータ情報はGF92のNMSYORIカラムの種別毎にJspConvertEntityオブジェクトに事前に準備する必要がある。
 *
 * 例)
 * JspConvertEntity e = new JspConvertEntity("RESULT");
 * e.setTableName("GF92");
 * e.setColumnName("NMSYORI");
 *
 *
 * 継承先のクラスのexecuteメソッドでは、引数のマスタデータ情報からJSPタグの文字列を生成する処理を実装します。
 *
 * @author Takeshi.Takada
 *
 */
public abstract class AbstractJspCreate implements JspParserFilter {

	/** 出力先のシステムに応じた改行コード */
	public static final String CR = System.getProperty("line.separator");

	/** タブを定数化しておきます。 */
	public static final String T1 = "\t" ;				// 5.6.4.4 (2013/05/31) タブを定数化しておきます。
	public static final String T2 = "\t\t" ;			// 5.6.4.4 (2013/05/31) タブを定数化しておきます。
	public static final String T3 = "\t\t\t" ;			// 5.6.4.4 (2013/05/31) タブを定数化しておきます。

	// 5.6.1.2 (2013/02/22) 初期値を設定。NAME は、複数のファイル名をカンマ区切り文字で与えられるように想定を変更。
	protected String KEY  = null;
	protected String NAME = "";

	/**
	 * ファイル名から、処理対象かどうかを判断します。
	 * ファイル名は、拡張子なしのファイル名(index,query,result,・・・)などになります。
	 * 先に指定しているファイル名と部分一致するかどうかで判定します。
	 *
	 * @og.rev 5.6.1.2 (2013/02/22) NAME は、複数のファイル名をカンマ区切り文字で与えられるように変更。
	 *
	 * @param	name	処理対象のファイル名
	 *
	 * @return	処理対象なら true/ そうでなければ、false
	 */
	protected boolean isExecute( final String name ) {
		return NAME.contains( FileUtil.getBaseName( name ) ) ;
	}

	/**
	 * 初期化メソッド
	 *
	 * 内部で使用する JspConvertEntity の List のマップを受け取り、初期化を行います。
	 *
	 * @param	master	JspConvertEntityのリストのマップ
	 */
	abstract protected void init( final Map<String,List<JspConvertEntity>> master );

	/**
	 * JSPに出力するタグの内容を作成します。
	 * 引数より作成前のタグの属性内容を確認するする事が出来ます。
	 *
	 * @og.rev 5.2.1.0 (2010/10/01) メソッドの引数を、OGAttributes から OGElement に変更します。
	 *
	 * @param	ele	エレメントオブジェクト
	 * @param	nameSpace	このドキュメントのnameSpace( og とか mis とか )
	 *
	 * @return	変換された文字列
	 * @throws Throwable 変換時のエラー
	 */
	abstract protected String execute( final OGElement ele , final String nameSpace )  throws Throwable ;

	/**
	 * ドキュメントオブジェクト を変換します。
	 *
	 * 引数に null が設定された場合も、正常に処理を行います。(return null とする)
	 * 後続処理を行いたくない場合にも、null を返します。
	 *
	 * @og.rev 5.2.1.0 (2010/10/01) メソッドの引数を、OGAttributes から OGElement に変更します。
	 *
	 * @param	doc	処理を行う ドキュメントオブジェクト
	 *
	 * @return	処理した結果の ドキュメントオブジェクト
	 * @see org.opengion.fukurou.xml.JspParserFilter#filter( OGDocument )
	 */
	@Override
	public OGDocument filter( final OGDocument doc ) {
		if( doc == null ) { return doc; }
		OGDocument rtndoc = doc;

		String name = doc.getFilename();
		if( isExecute( name ) && KEY != null ) {
			try {
				String nameSpace = doc.getNameSpace();
				String key = (KEY.indexOf( ':' ) == 0 ) ? nameSpace + KEY : KEY ;

				List<OGElement> list = doc.getElementList( key );
				for( OGElement ele : list ) {
					OGNode newNode = new OGNode( execute( ele,nameSpace ) );		// 5.2.1.0 (2010/10/01)
					rtndoc.changeNode( ele,newNode );
				}
			} catch ( Throwable th ) {
				th.printStackTrace();
			}
		}
		return rtndoc;
	}

	/**
	 * 引数のリストを連結文字列で連結した文字列を作成して返します。
	 *
	 * @param	list	処理を行うドキュメントリスト
	 * @param	sep		連結する区切り文字
	 *
	 * @return	連結された文字列
	 */
	protected String chainChar( final List<String> list , final String sep ){
		StringBuilder buf = new StringBuilder();

		for( String st : list ) {
			if( buf.length() > 0 ) {
				buf.append( sep ) ;
			}
			buf.append( st ) ;
		}
		return buf.toString();
	}

	/**
	 * 指定のListオブジェクトが null でなく、かつ、空でないか、判定する。
	 *
	 * @og.rev 5.2.1.0 (2010/10/01) 新規追加
	 *
	 * @param	list	、判定するListオブジェクト
	 *
	 * @return	nullでなく、かつ、空でない場合、true
	 */
	protected boolean isNotEmpty( final List<JspConvertEntity> list ) {
		return list != null && !list.isEmpty() ;
	}
}
