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

/**
 * コンストラクタに引数で与えられたマスタデータ情報を元に、特定の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");

	protected String KEY  ;
	protected String NAME ;

	/**
	 * 処理対象のキーを返します。
	 *
	 * null の場合は、なにも処理しないことになります。
	 *
	 * @return	処理対象を識別するキー情報
	 */
//	protected String getKey() { return KEY; }

	/**
	 * ファイル名から、処理対象かどうかを判断します。
	 *
	 * @param	name	処理対象のファイル名
	 *
	 * @return	処理対象なら true/ そうでなければ、false
	 */
	protected boolean isExecute( final String name ) {
		return ( name != null && name.indexOf( NAME ) >= 0 );
	}

	/**
	 * 初期化メソッド
	 *
	 * 内部で使用する 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	処理対象を識別するキー情報
	 */
//	abstract protected String getKey();

	/**
	 * ファイル名から、処理対象かどうかを判断します。
	 *
	 * @param	name	処理対象のファイル名
	 *
	 * @return	処理対象なら true/ そうでなければ、false
	 */
//	abstract protected boolean isExecute( final String name );

	/**
	 * ドキュメントオブジェクト を変換します。
	 *
	 * 引数に 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 );
				List<OGElement> list = doc.getElementList( key );
				for( OGElement ele : list ) {
//					OGAttributes attri = ele.getAttributes();
//					OGNode newNode = new OGNode( execute( attri ) );
					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() ) ;
	}
}
