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


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

import org.opengion.fukurou.util.StringUtil;
import org.opengion.hayabusa.common.HybsSystemException;
import org.opengion.hayabusa.db.DBTableModelUtil;
import org.opengion.hayabusa.html.AbstractJsonReader;


/**
 * JSONからテーブルモデルへの変換を行う標準クラスです。
 * エンジンのVIEWタイプJSONから出力したデータ形式を入力とします。
 * 
 * http://qiita.com/kenichi_nakamura/items/be73e37ec870e5845ed9
 * https://www.mkyong.com/java/how-to-convert-java-map-to-from-json-jackson/
 *
 * @og.group 画面表示
 * @og.rev 5.9.21.0 (2017/06/02)
 *
 * @version  5.0
 * @author	 Takahashi Masakazu
 * @since    JDK7.0,
 */
public class JsonReader_Default extends AbstractJsonReader {
	//* このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "5.9.21.0 (2017/06/02)" ;
	
	private String datakey = "DATA"; // データ部分を示すキー名

	/**
	 * デフォルトコンストラクター
	 *
	 */
	public JsonReader_Default() {
	}

	/**
	 * JSONデータをDBTableModelに変換します。
	 * 
	 * このdefaultクラスではエンジンのViewForm_JSON形式に対応します。
	 * エンジンでの出力は以下のような形となっていますが、汎用性を上げるためにHEAD,INFOは利用せずにDATAだけを見るようにします。
	 * 
	 * { "DATA":[{"カラム名":"値(1行目)",...},{"カラム名":"値(2行目)",...}]
	 *	 ,"HEAD":{"カラム名":"ラベル",...}
	 *	 ,"INFO":{{"COUNT":"件数","COLUMN":"出力カラム名（カンマ区切り）"} }
	 *	}
	 *
	 *
	 * @param   json JSON
	 */
	@Override
	public void readDBTable( final String json ) {
		String[] names = null;
		String[] readData = null;
		int numberOfRows = 0;

		table = DBTableModelUtil.newDBTable();
		
		int skip = getSkipRowCount();
		
		Map<String,Object> jsonmap = parse( json );
		
		// datakeyで名称を変更できるようにしておく。
		// DATAは配列なのでListで返ってくる
		// これが行となる。
		ArrayList<Map<String,Object>> dataList = (ArrayList<Map<String,Object>>)jsonmap.get( datakey );
		
		for(Map<String,Object> mp : dataList){
            // 最初にカラム名をセットする
			if( names == null){
				names = mp.keySet().toArray( new String[mp.size()] );
				setTableDBColumn( names ) ;
            }
			
			if( skip > 0 ) { skip--; continue; }
			
			// 行データを追加
			if( numberOfRows < getMaxRowCount() ) {
				readData = readData( mp, names );
				setTableColumnValues( readData );
				numberOfRows ++ ;
			}
			else {
				table.setOverflow( true );
			}
        }
		
		if( names == null ) {
			String errMsg = "有効なデータが見つかりませんでした。";
			throw new HybsSystemException( errMsg );
		}
	}
	
	
	/**
	 * テーブルに登録する配列のJSONキー値を設定します。
	 * 
	 * { "DATA":[{"カラム名":"値(1行目)", ...},{"カラム名":"値(2行目)",...}] }
	 * 通常、上記のDATAをキー値としてテーブルに変換します。（エンジン標準出力）
	 * エンジン以外が同じ用な形式の場合に、クラスを新規作成しなくても取り込めるようにするためキー値を外から設定可能にしておきます。
	 *
	 * @param strings dataKey設定
	 */
	public void setOptions ( String... strings ){
		datakey = StringUtil.nval(strings[0],datakey);
	}
}
