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

import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.fukurou.util.StringUtil;						// 6.2.0.0 (2015/02/27)
import static org.opengion.fukurou.util.StringUtil.nval2;
import static org.opengion.fukurou.system.HybsConst.CR ;				// 6.1.0.0 (2014/12/26)
import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;	// 6.1.0.0 (2014/12/26) refactoring

/**
 * 画面オブジェクトの元となる 画面データを作成します。
 * 画面データは、言語(lang)に依存しない情報で、最終的な 画面オブジェクト内部で
 * 使用される 固定的なデータオブジェクトになります。
 *
 * @og.rev 4.0.0.0 (2004/12/31) 新規作成
 * @og.group リソース管理
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public final class GUIData {

	// 内部データのカラム番号
	/** ｶﾗﾑ番号 {@value} */ public static final int GUIKEY		= 0 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int GUILVL		= 1 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int LABEL_CLM	= 2 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int ADDRESS		= 3 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int SEQNO		= 4 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int GROUPS		= 5 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int CLASSIFY	= 6 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int ROLES		= 7 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int RWMODE		= 8 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int TARGET		= 9 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int PARAM		= 10 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int KBLINK		= 11 ;
	/** ｶﾗﾑ番号 {@value} */ public static final int DYUPD		= 12 ;	// 5.3.3.0 (2011/03/01) 更新日時追加
	/** ｶﾗﾑ番号 {@value} */ public static final int SYSTEM_ID	= 13 ;	// 7.2.6.0 (2020/06/30) 内部的に使ってないが定義しておく
	/** ｶﾗﾑ番号 {@value} */ public static final int KBSAKU		= 14 ;	// 7.4.2.0 (2021/05/18) 内部的に使ってないが定義しておく
	/** ｶﾗﾑ番号 {@value} */ public static final int SNO			= 15 ;	// 7.2.6.1 (2020/07/17) 内部的に使ってないが定義しておく

	private final String	guiKey ;		// 画面ID
	private final int		guiLevel ;		// 画面階層
	private final String	lblClm ;		// 画面カラムID
	private final String	address ;		// アドレス
	private final String	realAddress ;	// 実行実アドレス
	private final int		seqno ;			// 表示順
	private final String	groups ;		// グループ
	private final String	classify ;		// 分類
	private final String	target ;		// ターゲット
	private final String	param ;			// 設定値(パラメータ) 6.3.8.4 (2015/10/09) イメージアイコン設定は、KBLINK にします。
	private final String	kblink ;		// リンク区分
	private final boolean	pageUse ;		// page が、アドレスに追加できるかどうか
	private final RoleMode	roleMode ;		// 4.3.0.0 (2008/07/04) ロールズとモードを管理するオブジェクト
	private final String	dyupd ;			// 5.3.3.0 (2011/03/01) 更新日時追加
	private final String	imageKey ;		// 5.5.2.5 (2012/05/21) イメージアイコンの値。null の場合は、画面ID

	private static final String CON_DIR = "/" + HybsSystem.getContextName() + "/";

	/**
	 * 配列文字列のデータを元に、GUIDataオブジェクトを構築します。
	 * このコンストラクタは、他のパッケージから呼び出せないように、
	 * パッケージプライベートにしておきます。
	 * このコンストラクタは、ＤＢリソースファイルを想定しています。
	 *
	 * @og.rev 4.3.3.7 (2008/11/22) https対応
	 * @og.rev 5.1.3.0 (2010/02/01) 画面ロールのroot の場合は、user が root 以外、アクセス禁止のはず
	 * @og.rev 5.3.3.0 (2011/03/01) 更新日時追加 DYUPD
	 * @og.rev 5.5.2.5 (2012/05/21) imageKey イメージアイコンの処理を追加
	 * @og.rev 5.6.4.3 (2013/05/24) faqt追加
	 * @og.rev 5.7.8.1 (2014/07/18) address の "/" 対応
	 * @og.rev 6.3.8.4 (2015/10/09) GE80(FAQﾃｰﾌﾞﾙ)の取得は廃止。(helpタグで行う)
	 * @og.rev 6.3.8.4 (2015/10/09) KBLINK(リンク区分)を画面のイメージファイルに割り当てます。
	 *
	 * @param	data	GUIKEY,GUILVL,LABEL_CLM,ADDRESS,SEQNO,GROUPS,CLASSIFY,ROLES,RWMODE,TARGET,KBLINK,DYUPD
	 */
	GUIData( final String[] data ) {
		guiKey		= data[GUIKEY].intern() ;					// 画面ID
		guiLevel	= Integer.parseInt( data[GUILVL] );			// 画面階層
		lblClm 		= nval2( data[LABEL_CLM],guiKey ) ;			// 画面カラムID
		address 	= data[ADDRESS].intern() ;					// アドレス
		seqno		= Integer.parseInt( data[SEQNO] );			// 表示順
		groups		= nval2( data[GROUPS] , null ) ;			// グループ
		classify	= nval2( data[CLASSIFY] , "" ) ;			// 分類
		target		= nval2( data[TARGET] , null ) ;			// ターゲット

		// realAddress と pageUse を設定します。
		// 3.5.5.0 (2004/03/12) kblink の設定方法を見直し
		// 4.3.3.7 (2008/11/22) https対応
		if( address.startsWith( "http://" ) || address.startsWith( "https://" ) || StringUtil.startsChar( address , '.' ) ) {
			pageUse = false;
			kblink = "http";
			realAddress = address;
		}
		// 5.7.8.1 (2014/07/18) address の "/" 対応
		else if( StringUtil.startsChar( address , '/' ) ) {		// 6.2.0.0 (2015/02/27) １文字 String.startsWith
			pageUse = false;
			kblink  = "/";
			realAddress = address;
		}
		// 6.3.8.4 (2015/10/09) KBLINK(リンク区分)を画面のイメージファイルに割り当てます。
		else {
			pageUse = true;
			kblink = "jsp";		// 6.3.8.4 (2015/10/09)
			realAddress = CON_DIR + "jsp/" + address + "/" ;
		}

		// 4.0.0 (2005/01/31) param を追加します。
		final String paramTmp = data[PARAM] ;	// 設定値(パラメータ)
		if( paramTmp != null && paramTmp.length() > 0 ) {
			param = paramTmp.intern() ;
		}
		else {
			param = "" ;
		}

		// 5.5.2.5 (2012/05/21) イメージアイコンの処理。既存の param 設定と分けておきます。(将来的にはDBから読み取りたい)
		// 6.3.8.4 (2015/10/09) KBLINK(リンク区分)を画面のイメージファイルに割り当てます。
		imageKey = nval2( data[KBLINK] , guiKey ) ;

		// 5.1.3.0 (2010/02/01) 画面ロールのroot の場合は、user が root 以外、アクセス禁止のはず
		// ここでは、RoleMode で、共通化を図っているため、"root" を、"r00t" に置換えます。
		String roles = data[ROLES];
		if( "root".equals( roles ) ) { roles = "r00t" ; }
		roleMode	= RoleMode.newInstance( roles,data[RWMODE] );	// ロールモード

		dyupd = nval2( data[DYUPD] , "" ) ;
	}

	/**
	 * 画面オブジェクトのキーを返します。
	 *
	 * @return 画面オブジェクトのキー
	 */
	public String getGuiKey() { return guiKey; }

	/**
	 * 画面オブジェクトの階層レベルを返します。
	 *
	 * @return 画面オブジェクトの階層レベル
	 */
	public int getGuiLevel() { return guiLevel ; }

	/**
	 * 画面オブジェクトの画面カラムIDを返します。
	 * これは、同一画面ID(GUIKEY)で、ロール違いやアドレス違いにより
	 * 画面に表示する名称を変える場合に使用します。
	 *
	 * @return 画面オブジェクトの画面カラムID
	 */
	public String getLabelClm() { return lblClm ; }

	/**
	 * 画面オブジェクトのアドレスを返します。
	 *
	 * @return 画面オブジェクトのアドレス
	 */
	public String getAddress() { return address; }

	/**
	 * トップからの実行アドレス情報を取得します。
	 * コンテキスト名とリンク区分属性を利用して、サーバートップからのアドレスを
	 * 返します。ただし、GUIリソースに、http://～ または、.～ から始まるアドレスは
	 * そのまま、なにも変換せずに返します。
	 * param 属性がある場合は、引数として後ろに追加します。
	 *
	 * http://AAAA  ⇒  http://AAAA
	 * ../../AAAA/  ⇒  ../../AAAA/
	 * AAAA         ⇒  /CONTEXT_NAME/KBLINK/AAAA/
	 *
	 * @og.rev 3.5.5.0 (2004/03/12) 新規追加
	 * @og.rev 4.0.0.0 (2005/01/31) param 属性の追加
	 *
	 * @return	実行実アドレス
	 */
	public String getRealAddress() {
		return realAddress ;
	}

	/**
	 * トップからの実行アドレス情報を取得します。
	 * コンテキスト名とリンク区分属性を利用して、サーバートップからのアドレスを
	 * 返します。ただし、GUIリソースに、http://～ または、.～ から始まるアドレスは
	 * そのまま、なにも変換せずに返します。
	 * また、アドレスの最後がスラッシュ(/)で終了している場合は、page属性を追加します。
	 *
	 * http://AAAA  ⇒  http://AAAA
	 * ../../AAAA/  ⇒  ../../AAAA/
	 * AAAA         ⇒  /CONTEXT_NAME/KBLINK/AAAA/
	 *
	 * @og.rev 4.0.0.0 (2005/01/31) 新規追加
	 *
	 * @param    page          実行ページ(index.jsp など)
	 *
	 * @return	実行実アドレス
	 */
	public String getRealAddress( final String page ) {
		// 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
		return ! pageUse || page == null ? realAddress : realAddress + page;
	}

	/**
	 * 画面オブジェクトの表示順を返します。
	 *
	 * @return	画面オブジェクトの表示順
	 */
	public int getSeqno() { return seqno; }

	/**
	 * 画面オブジェクトのグループを返します。
	 *
	 * @return	画面オブジェクトのグループ
	 */
	public String getGroups() { return groups; }

	/**
	 * 画面オブジェクトの分類を返します。
	 *
	 * @return	画面オブジェクトの分類
	 */
	public String getClassify() { return classify; }

	/**
	 * 画面オブジェクトのロールズを返します。
	 *
	 * @return	画面オブジェクトのロールズ文字列
	 */
	public String getRoles() { return roleMode.getRoles(); }

	/**
	 * 画面オブジェクトのモード文字列を返します。
	 *
	 * @return	画面オブジェクトのモード文字列
	 */
	public String getMode() { return roleMode.getMode(); }

	/**
	 * ロールモード情報を取得します。
	 *
	 * @og.rev 4.3.0.0 (2008/07/04) 新規追加
	 *
	 * @return	ロールモード情報
	 */
	public RoleMode getRoleMode() { return roleMode ; }

	/**
	 * 画面オブジェクトのターゲットを返します。
	 *
	 * @return 画面オブジェクトのターゲット
	 */
	public String getTarget() { return target; }

	/**
	 * 画面オブジェクトのパラメータを返します。
	 *
	 * @return 画面オブジェクトのパラメータ
	 */
	public String getParam() { return param; }

	/**
	 * 画面オブジェクトのリンク区分を返します。
	 *
	 * @return 画面オブジェクトのリンク区分
	 */
	public String getKblink() { return kblink; }

	/**
	 * 画面オブジェクトの更新日時を返します。
	 *
	 * @og.rev 5.3.3.0 (2011/03/01) 新規追加
	 *
	 * @return 画面オブジェクトの更新日時
	 */
	public String getDyupd() { return dyupd; }

	/**
	 * イメージアイコンのキーを返します。
	 *
	 * 画面にアイコンを追加する場合、jsp/menuImage フォルダに、画面ID と同じ名称の
	 * 画像ファイルを置く必要があります。
	 *
	 * ※ 6.3.8.4 (2015/10/09)
	 *    従来は、PARAM 属性に、IMAGE_KEY=XXXX と指定していましたが、
	 *    KBLINK(リンク区分) を使用するように変更しました。
	 *
	 * @og.rev 5.5.2.5 (2012/05/21) 新規追加
	 * @og.rev 6.3.8.4 (2015/10/09) KBLINK(リンク区分)を画面のイメージファイルに割り当てます。
	 *
	 * @return イメージアイコンのキー
	 */
	public String getImageKey() { return imageKey; }

	/**
	 * オブジェクトの識別子として，詳細なユーザー情報を返します。
	 *
	 * @og.rev 5.3.3.0 (2011/03/01) 更新日時を追加
	 * @og.rev 5.6.4.3 (2013/05/24) faq
	 * @og.rev 6.3.8.4 (2015/10/09) GE80(FAQﾃｰﾌﾞﾙ)の取得は廃止。(helpタグで行う)
	 *
	 * @return  詳細な画面情報
	 * @og.rtnNotNull
	 */
	@Override
	public String toString() {
		final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
			.append( "guiKey     :" ).append( guiKey      ).append( CR )
			.append( "guiLevel   :" ).append( guiLevel    ).append( CR )
			.append( "address    :" ).append( address     ).append( CR )
			.append( "realAddress:" ).append( realAddress ).append( CR )
			.append( "seqno      :" ).append( seqno       ).append( CR )
			.append( "classify   :" ).append( classify    ).append( CR )
			.append( "roles      :" ).append( getRoles()  ).append( CR )
			.append( "mode       :" ).append( getMode()   ).append( CR )
			.append( "target     :" ).append( target      ).append( CR )
			.append( "param      :" ).append( param       ).append( CR )
			.append( "kblink     :" ).append( kblink      ).append( CR )
			.append( "dyupd      :" ).append( dyupd       ).append( CR );
		return rtn.toString();
	}
}
