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

import java.io.File;
import java.util.List;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import jakarta.servlet.http.HttpServletRequest;

import org.opengion.fukurou.system.OgBuilder ;				// 6.4.4.1 (2016/03/18)
import org.opengion.fukurou.system.DateSet;					// 6.4.2.0 (2016/01/29)
import org.opengion.fukurou.security.HybsCryptography;		// 5.8.8.0 (2015/06/05)
import org.opengion.fukurou.util.StringUtil;
import org.opengion.fukurou.util.XHTMLTag;
import org.opengion.fukurou.util.ToString;					// 6.1.1.0 (2015/01/17)
import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.hayabusa.common.HybsSystemException;
// import org.opengion.hayabusa.html.CreateToken;				// 5.8.2.1 (2014/12/13) 6.9.5.0 (2018/04/23) extToken 廃止
import org.opengion.hayabusa.resource.GUIInfo;
import org.opengion.hayabusa.resource.URLXfer;

import static org.opengion.fukurou.util.StringUtil.nval;

/**
 * HTML のaタグと同等のリンクを作成するHTML拡張タグです。
 *
 * @og.formSample
 * ●形式：&lt;og:link href="…" &gt;  ...  &lt;/og:link &gt;
 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
 *
 * ●Tag定義：
 *   &lt;og:link
 *       type               【HTML】リンク先のMIMEタイプを指定します
 *       name               【HTML】この要素をリンクの対象とするための名前を指定します(HTML5より廃止)
 *       gamenId            【TAG】画面ID属性を登録します
 *       useGamenId         【TAG】GAMENID,BACK_GAMENID 属性を付加するかどうか[true/false]を設定します(初期値:true)
 *       column             【TAG】リンクをつけたいカラムを指定します(ViewLink タグと併用)
 *       keys               【TAG】リンク先に渡すキーをCSV形式で複数指定します
 *       vals               【TAG】リンク先に渡す値をCSV形式で複数指定します
 *       onLink             【TAG】リンクを張る(true or 1)/張らない(false or 0)の設定を指定します(初期値:true)
 *       markList           【TAG】処理するマークを、"|"区切りの文字列で指定します
 *       href               【HTML】リンク先のURLを指定します
 *       target             【HTML】リンク先の表示ターゲットを指定します
 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
 *       lbl                【TAG】ラベルリソースのラベルIDを指定します
 *       xlink              【TAG】href ではなく、xlink:href を使用するかどうか[true/false]を指定します(初期値:false)
 *       fileCheck          【TAG】ファイルの存在チェックを行うかどうか[true/false]を指定します(初期値:false)
 *       filePath           【TAG】アドレスにファイルのディレクトリ直接のアドレスを指定するかどうか[true/false]設定します(初期値:false)
 *       hreflang           【HTML】リンク先の基本となる言語コードを指定します
 *       rel                【HTML】この文書から見た、href属性で指定されるリンク先との関係を指定します
 *       rev                【HTML】href属性で指定されるリンク先から見た、この文書との関係をしてします
 *       charset            【HTML】リンク先の文字コードセットを指定します
 *       shape              【HTML】リンクボタンの形状(イメージマップ rect/circle/poly/default)を指定します
 *       coords             【HTML】リンクボタンの座標を指定します
 *       id                 【HTML】要素に対して固有の名前(id)をつける場合に設定します
 *       lang               【HTML】要素の内容と他の属性値の言語(lang,xml:lang)を指定します
 *       dir                【HTML】文字表記の方向(dir)を指定します
 *       title              【HTML】要素に対する補足的情報(title)を設定します
 *       style              【HTML】この要素に対して適用させるスタイルシート(style)を設定します
 *       tabindex           【HTML】タブの移動順(tabindex)を指定します(0 ～ 32767)
 *       accesskey          【HTML】アクセスキー(alt+キーで直接指定)を割り当てます
 *       clazz              【HTML】要素に対して class 属性を設定します
 *       language           【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します
 *       useDirectJump      【TAG】ダイレクトジャンプを使用するかどうか[true/false]を指定します(初期値:false)
 *       useRequestCache    【TAG】リクエストキャッシュ情報を使用するかどうか[true/false]を指定します(初期値:true)
 *       hrefOnly           【TAG】リンク(アンカータグ)ではなく、href 属性をそのまま返すかどうか[true/false]を指定します(初期値:false)
 *       hrefTarget         【TAG】リンク(アンカータグ)ではなく、href 属性と、target属性を キーも含めて返すかどうか[true/false]を指定します(初期値:false)
 *       delKeys            【TAG】リクエストキャッシュ情報使用時に使用しない(削除する)キーをCSV形式で複数指定します
 *       onClick            【HTML】JavaScriptのイベント onClick を設定します(例:onClick="renew('query.jsp','QUERY');")
 *       onBlur             【HTML】JavaScriptのイベント onBlur を設定します(例:onBlur="this.value=value.toUpperCase();")
 *       onFocus            【HTML】JavaScriptのイベント onFocus を設定します
 *       ondblClick         【HTML】JavaScriptのイベント ondblClick を設定します
 *       onMouseDown        【HTML】JavaScriptのイベント onMouseDown を設定します
 *       onMouseUp          【HTML】JavaScriptのイベント onMouseUp を設定します
 *       onMouseMove        【HTML】JavaScriptのイベント onMouseMove を設定します
 *       onMouseOut         【HTML】JavaScriptのイベント onMouseOut を設定します
 *       onMouseOver        【HTML】JavaScriptのイベント onMouseOver を設定します
 *       roles              【TAG】ロールをセットします
 *       useURLCheck        【TAG】リンクアドレスにURLチェック用の確認キーを付加するかどうか[true/false]を指定します(初期値:false)
 *       urlCheckUser       【TAG】URLチェック用の確認キーに対して、リンクを開くことのできるユーザーIDを指定します(初期値:ログインユーザー)
 *       urlCheckTime       【TAG】URLチェック用の確認キーに対して、リンクの有効期限を指定します(初期値:1440分=1日)
 *       urlCheckCrypt      【TAG】URLチェックの暗号化キーを指定します。受け側に依存します。未指定の場合はデフォルトの値が利用されます。
 *       useHrefEncode      【TAG】href 部分に対して、(;%)の２文字だけ URLEncodeを行うかどうかを指定します(初期値:USE_HREF_URLENCODE[=false])
 *       strictCheck        【TAG】(通常は使いません)カラムＩＤの存在チェックを行うかどうか[true/false]を指定します(初期値:true)
 *       forceEnc           【TAG】(通常は使いません) valsの値が[で開始している場合でもURLEncodeを通すかを設定します(初期値:false) 5.10.15.3 (2019/09/27)
 *       useBackLink        【TAG】(通常は使いません) true：相手先に戻るﾘﾝｸを必ず表示。false:必ず表示しない。未指定(null):従来通り(初期値:null) 7.3.1.0 (2021/02/02)
 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
 *   &gt;   ... Body ...
 *   &lt;/og:link&gt;
 *
 * 【廃止】6.9.5.0 (2018/04/23) 物理削除
 *   //  extToken           【廃止】利用するCreateTokenプラグイン名を設定します。6.9.5.0 (2018/04/23)
 *
 *    6.7.6.0 (2017/03/17) [strictCheck属性]は、カラムＩＤの存在チェックを行うかどうかを指定します(初期値:true)
 *      true    カラムＩＤがDBTableModel に存在しない場合は、エラーになる。
 *      false   カラムＩＤがDBTableModel に存在しない場合は、無視する。
 *
 * ●使用例
 *    ・普通のリンク
 *        &lt;og:link gamenId="32ExcelIn" href="direct.jsp" keys="location,filename,modifyType" value="{&#064;GUI.ADDRESS},{&#064;GUI.ADDRESS}.xls,A"  target="RESULT" &gt;
 *            &lt;img src="{&#064;SYS.JSP}/image/insert.gif" alt="Excel Insert" /&gt;&lt;og:message lbl="MSG0057" /&gt;
 *        &lt;/og:link&gt;
 *
 *    ・検索結果テーブル内でのリンク
 *        &lt;og:viewLink command="{&#064;command}"&gt;
 *            &lt;og:link column="KMZ" gamenId="RK0251" href="index.jsp" target="CONTENTS"
 *                keys="KMZ,ORDER_BY,command" vals="[KMZ],'LKIS',NEW" /&gt;
 *        &lt;/og:viewLink&gt;
 *
 *    ・ダイレクトジャンプ(指定の画面へ直接飛ばす)URL
 *      gamenId を指定しなければこの画面へのURLを作成します。
 *      このURLは、その画面の index.jsp に直接ジャンプするためのURLです。
 *      この場合、useRequestCache="true" が初期値なので、必要なければ、false に設定願います。
 *        &lt;og:link useDirectJump="true" delKeys="pageSize"
 *                     keys="location,filename,modifyType" value="{&#064;GUI.ADDRESS},{&#064;GUI.ADDRESS}.xls,A" /&gt;
 * @og.group 画面表示
 *
 * @version  4.0
 * @author	 Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class LinkTag extends HTMLTagSupport {
	/** このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "7.3.1.0 (2021/02/02)" ;
	private static final long serialVersionUID = 731020210202L ;

	private static final long INIT_TIME = 24*60*60*1000L ;									// 6.2.5.0 (2015/06/05) 1日=24(時)*60(分)*60(秒)*1000(ミリ秒)

	private String		column		;
	private String		onLink		= "true";	// true または 1
	private boolean		fileCheck	;
	private boolean		filePath	;
	// 6.4.2.1 (2016/02/05) HybsSystem.url2dir に引数追加。fileURL変数を廃止します。
	// 7.2.7.0 (2020/08/07) 他の属性の関係で、baseURLをfileURL に変更
//	private String		baseURL		= HybsSystem.sys( "FILE_URL" );
	private String		fileURL		= HybsSystem.sys( "FILE_URL" );
	private String		gamenId		;
	private boolean		useGamenId	= true;
	// 3.5.2.0 (2003/10/20)
	private String		markList		= "true|TRUE|1";	// true または 1
	private boolean		xlink			;					// 3.5.5.0 (2004/03/12)
	private boolean		useDirectJump	;					// 3.7.1.0 (2005/04/26)
	private boolean		useRequestCache = true;				// 3.7.1.0 (2005/04/26)
	private int			validDuration 	= -1;
	private boolean		hrefOnly		;					// 4.0.0 (2005/11/30)
	private boolean		hrefTarget		;					// 5.5.5.6 (2012/08/31)
	private boolean		useHrefEncode	= HybsSystem.sysBool( "USE_HREF_URLENCODE" );		// 6.0.2.0 (2014/09/19)
	private boolean		strictCheck		= true;				// 6.7.6.0 (2017/03/17) カラムＩＤの存在チェックを行うかどうかを指定します。

	private String[]	keys			;					// 3.5.6.2 (2004/07/05)
	private String[]	vals			;					// 3.5.6.2 (2004/07/05)
	private String[]	delKeys			;					// 3.7.1.0 (2005/04/26)
//	private boolean		useURLCheck		;	 				// 4.3.7.0 (2009/06/01)
	private boolean		useURLCheck		= HybsSystem.sysBool( "LINK_URL_CHECK" );			// 5.10.11.0 (2019/05/03) システムリソースに変更
	private String		urlCheckUser	;					// 4.3.7.0 (2009/06/01)
	private long		urlCheckTime	= INIT_TIME;		// 6.2.5.0 (2015/06/05)
//	private String		urlCheckCrypt	;					// 5.8.8.0 (2015/06/05)
	private String		urlCheckCrypt	= HybsSystem.sys( "URL_CHECK_CRYPT" );				// 5.8.8.0 (2015/06/05)　5.9.32.1 (2018/05/09) urlCheckCrypt初期値をシステムリソースから取得に変更
//	private String		extToken		;					// 5.8.2.1 (2014/12/13) 6.9.5.0 (2018/04/23) extToken 廃止

//	private transient List<CreateToken>	ctArray	;			// 6.3.9.0 (2015/11/06) transient 追加 6.9.5.0 (2018/04/23) 廃止
	private boolean		useForceEnc		;					// 5.10.15.3 (2019/09/27) 強制URLエンコード用
	private String		useBackLink		;					// 7.3.1.0 (2021/02/02)

	private static final String SERVER_ACCESS_URL = HybsSystem.sys( "SERVER_ACCESS_URL" );	// 5.10.16.3 (2019/10/25) https://www.xxx:8080 まで

	/**
	 * デフォルトコンストラクター
	 *
	 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
	 */
	public LinkTag() { super(); }		// これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。

	/**
	 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
	 *
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。ボディが存在する場合のみボディが呼ばれる対応。
	 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
	 * @og.rev 5.7.1.2 (2013/12/20) msg ⇒ msglbl 変更
	 *
	 * @return	後続処理の指示( EVAL_BODY_BUFFERED )
	 */
	@Override
	public int doStartTag() {
		// 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
		if( useTag() ) {
			String msglbl = getMsglbl();	// 5.7.1.2 (2013/12/20) msg ⇒ msglbl 変更
			if( msglbl == null && column != null ) { msglbl = "[" + column + "]"; }
			set( "body",msglbl );
			return EVAL_BODY_BUFFERED ;	// Body を評価する。( extends BodyTagSupport 時)
		}
		return SKIP_BODY ;				// Body を評価しない
	}

	/**
	 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
	 *
	 * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。ボディが存在する場合のみボディが呼ばれる対応。
	 *
	 * @return	後続処理の指示(SKIP_BODY)
	 */
	@Override
	public int doAfterBody() {
		final String label = getBodyString();

		if( label != null && label.length() > 0 ) {
			set( "body",label );
		}

		return SKIP_BODY ;
	}

	/**
	 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
	 *
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
	 * @og.rev 3.1.2.0 (2003/04/07) リンク指定時に、画面IDを渡して、実アドレスを求める事ができる様にする。
	 * @og.rev 3.1.7.0 (2003/05/02) 戻るボタン用のBACK_GAMENID を、引数に追加します。
	 * @og.rev 3.1.8.0 (2003/05/16) GAMENID属性のＵＲＬへの自動セットを行うかどうかを決める属性( useGamenId )を追加。
	 * @og.rev 3.1.8.0 (2003/05/16) 画面ＩＤが指定されたときのリンク情報作成方法を通常のリンク時にも適用する。
	 * @og.rev 3.1.8.0 (2003/05/16) 画面のロールに応じて、リンクを張る/張らないを自動判断する。
	 * @og.rev 3.5.2.0 (2003/10/20) markList属性を追加
	 * @og.rev 3.5.5.0 (2004/03/12) xlink属性をAttributeオブジェクトに追加
	 * @og.rev 3.5.6.2 (2004/07/05) makeTag() の処理範囲変更、viewlink へのパラメータ変更。
	 * @og.rev 3.7.1.0 (2005/04/26) ダイレクトジャンプリンク機能を追加
	 * @og.rev 4.0.0.0 (2005/11/30) roles 属性の追加
	 * @og.rev 4.0.0.0 (2005/08/31) 同一カラムの複数登録を許可します。
	 * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
	 * @og.rev 4.3.7.1 (2009/06/08) URLチェック機能対応
	 * @og.rev 4.3.7.4 (2009/07/01) 循環参照を解消
	 * @og.rev 4.3.8.0 (2009/08/01) ユーザーIDの外部設定に対応
	 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
	 * @og.rev 6.0.2.0 (2014/09/19) useHrefEncode 属性対応
	 * @og.rev 5.8.2.1 (2014/12/14) トークンプラグイン対応
	 * @og.rev 5.8.8.0 (2015/06/05) urlCheckCrypt対応
	 * @og.rev 6.2.5.0 (2015/06/05) System.currentTimeMillis() + urlCheckTime を、最初に計算しておく。
	 * @og.rev 6.4.2.1 (2016/02/05) HybsSystem.url2dir に引数追加。fileURL変数を廃止します。
	 * @og.rev 6.7.3.0 (2017/01/27) ViewLinkTag経由の判定を入れる。
	 * @og.rev 6.7.6.0 (2017/03/17) strictCheck 追加。
	 * @og.rev 6.9.5.0 (2018/04/23) extToken 廃止
	 * @og.rev 7.1.0.1 (2020/02/07) hrefOnly属性追加
	 * @og.rev 7.2.7.0 (2020/08/07) 他の属性の関係で、baseURLをfileURL に変更
	 *
	 * @return	後続処理の指示
	 */
	@Override
	public int doEndTag() {
		debugPrint();		// 4.0.0 (2005/02/28)
		// 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
		if( !useTag() ) { return EVAL_PAGE ; }

		// 3.1.8.0 (2003/05/16) GAMENID属性のＵＲＬへの自動セットを行うかどうかを決める属性( useGamenId )を追加。
		// 4.0.0 (2005/11/30) 指定のロールが、アクセス許可の場合は、出力します。
		final String roles = get( "roles" );
		// 4.3.0.0 (2008/07/04) ロールモードマルチ対応
		if( ! getUser().isAccess( roles ) ) {
			return EVAL_PAGE ;
		}

		//  4.3.7.1 (2009/06/08)
		if( useURLCheck ) {
			// 4.3.8.0 (2009/08/01)
			urlCheckUser = nval( urlCheckUser, getUser().getUserID() );
		}

		// 6.2.5.0 (2015/06/05) System.currentTimeMillis() + urlCheckTime を、最初に計算しておく。
		final long plusCheckTime = System.currentTimeMillis() + urlCheckTime ;

		final ViewLinkTag viewlink = (ViewLinkTag)findAncestorWithClass( this,ViewLinkTag.class );
		if( viewlink != null ) {
			if( isGamenCheck() ) {	set( "onLink", onLink );  }
			else {					set( "onLink", "false" ); }
			 // 4.3.7.1 (2009/06/08)
			if( useURLCheck ) {
				set( "useURLCheck"	, "true" );
				set( "urlCheckUser"	, urlCheckUser );
				set( "urlCheckTime"	, String.valueOf( plusCheckTime ) );								// 6.2.5.0 (2015/06/05)
				set( "urlCheckCrypt", urlCheckCrypt );	// 5.8.8.0 (2015/06/05)
			}
			set( "markList"   , markList );
			set( "linkFormat" , makeTag() );			// 3.5.6.2 (2004/07/05)
			if( hrefOnly ) {
				set( "hrefOnly" , "true" );				// 7.1.0.1 (2020/02/07) hrefOnly属性追加
			}

			// 4.0.0 (2005/08/31) 同一カラムの複数登録を許可します。
			set( "column"      , column );
//			set( "extToken"    , extToken );							// 5.8.2.1 (2014/12/13) 6.9.5.0 (2018/04/23) extToken 廃止
			set( "strictCheck" , String.valueOf( strictCheck ) );		// 6.7.6.0 (2017/03/17)

	 		// 6.0.2.0 (2014/09/19) useHrefEncode 属性対応
			if( !useGamenId && useHrefEncode ) {
				set( "useHrefEncode","true" );
			}
			viewlink.addAttribute( getAttributes() );
		}
		// 3.7.1.0 (2005/04/26) ダイレクトジャンプリンク機能を追加
		// 画面の利用権限有無などは調査不要
		else if( useDirectJump ) {
			jspPrint( makeDirectLink() );
		}
		else {
			if( isFileCheck() && isGamenCheck() && markList.indexOf( onLink ) >= 0 ) {
				// 3.5.6.2 (2004/07/05) makeTag() より移動
				if( filePath ) {
					final String furl  = get( "href" );

					// 6.4.2.1 (2016/02/05) HybsSystem.url2dir に引数追加。fileURL変数を廃止します。
					// 7.2.7.0 (2020/08/07) 他の属性の関係で、fileURL に変更
//					final String filename =  HybsSystem.url2dir( baseURL,furl );
					final String filename =  HybsSystem.url2dir( fileURL,furl );

					set( "href",filename );
				}

				// 4.3.7.1 (2009/06/08)
				// 6.7.3.0 (2017/01/27) ViewLinkTag経由の判定を入れる。
				String tag = makeTag( false );		// ViewLinkTag経由しない。
				if( useURLCheck ) {
					// 5.8.8.0 (2015/06/05) urlCheckCrypt対応
					HybsCryptography criptCls = null;
					if( urlCheckCrypt != null && urlCheckCrypt.length() > 0 ){
						criptCls = new HybsCryptography( urlCheckCrypt );
					}

					if( hrefOnly ) {
						// 4.3.7.4 (2009/07/01) 循環参照を解消
						tag = XHTMLTag.addURLCheckKey( tag, HybsSystem.URL_CHECK_KEY, getUser().getUserID(), plusCheckTime, criptCls );		// 5.8.8.0
					}
					else {
						// 4.3.7.4 (2009/07/01) 循環参照を解消
						tag = XHTMLTag.embedURLCheckKey( tag, HybsSystem.URL_CHECK_KEY, getUser().getUserID(), plusCheckTime, criptCls );	// 5.8.8.0
					}
				}
//				// 5.8.2.1 (2014/12/14) URLトークンプラグイン
//				// 6.9.5.0 (2018/04/23) extToken 廃止
//				if( ctArray != null && !ctArray.isEmpty() ){		// 6.1.1.0 (2015/01/17) refactoring
//					for( final CreateToken ct : ctArray){
//						if( hrefOnly ){
//							tag = ct.generateURL( tag, plusCheckTime, null );	// 5.8.8.0
//						}
//						else{
//							tag = ct.embedToken( tag, plusCheckTime, null );	// 5.8.8.0
//						}
//					}
//				}
				jspPrint( tag );
			}
		}

		return EVAL_PAGE ;
	}

	/**
	 * タグリブオブジェクトをリリースします。
	 * キャッシュされて再利用されるので、フィールドの初期設定を行います。
	 *
	 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
	 * @og.rev 3.1.2.0 (2003/04/07) リンク指定時に、画面IDを渡して、実アドレスを求める事ができる様にする。
	 * @og.rev 3.1.8.0 (2003/05/16) GAMENID属性のＵＲＬへの自動セットを行うかどうかを決める属性( useGamenId )を追加。
	 * @og.rev 3.5.2.0 (2003/10/20) markList属性を追加
	 * @og.rev 3.5.5.0 (2004/03/12) xlink属性を追加
	 * @og.rev 3.5.6.2 (2004/07/05) keys , vals属性を追加
	 * @og.rev 3.7.1.0 (2005/04/26) useDirectJump , useRequestCache , delKeys 属性を追加
	 * @og.rev 4.0.0.0 (2005/09/30) validDuration 属性を追加
	 * @og.rev 4.3.7.0 (2009/06/01) useURLCheck属性を追加
	 * @og.rev 5.5.5.6 (2012/08/31) hrefTarget属性を追加
	 * @og.rev 6.0.2.0 (2014/09/19) useHrefEncode属性を追加
	 * @og.rev 5.8.2.1 (2014/12/14) トークンプラグイン対応(extToken,ctArray属性を追加)
	 * @og.rev 5.8.8.0 (2015/06/05) urlCheckCrypt追加
	 * @og.rev 6.2.5.0 (2015/06/05) urlCheckTimeの初期値を、INIT_TIMEに変更
	 * @og.rev 6.4.2.1 (2016/02/05) HybsSystem.url2dir に引数追加。fileURL変数を廃止します。
	 * @og.rev 6.7.6.0 (2017/03/17) strictCheck 追加。
	 * @og.rev 6.9.5.0 (2018/04/23) extToken 廃止
	 * @og.rev 5.9.32.1 (2018/05/09) urlCheckCrypt初期値をシステムリソースから取得に変更
	 * @og.rev 5.10.11.0 (2019/05/03) useURLCheck属性をシステムリソースから取得に変更
	 * @og.rev 5.10.15.3 (2019/09/27) forceEnc追加
	 * @og.rev 7.2.7.0 (2020/08/07) 他の属性の関係で、baseURLをfileURL に変更
	 * @og.rev 7.3.1.0 (2021/02/02) useBackLink 追加。
	 */
	@Override
	protected void release2() {
		super.release2();
		column			= null;
		onLink			= "true";	// true または 1
		markList		= "true|TRUE|1";	// 3.5.2.0 (2003/10/20)
		fileCheck		= false;
		filePath		= false;
//		baseURL			= HybsSystem.sys( "FILE_URL" );
		fileURL			= HybsSystem.sys( "FILE_URL" );		// 7.2.7.0 (2020/08/07)
		gamenId			= null;
		useGamenId		= true;
		xlink			= false;	// 3.5.5.0 (2004/03/12)
		keys			= null;		// 3.5.6.2 (2004/07/05)
		vals			= null;		// 3.5.6.2 (2004/07/05)
		useDirectJump	= false;	// 3.7.1.0 (2005/04/26)
		useRequestCache = true;		// 3.7.1.0 (2005/04/26)
		delKeys			= null;		// 3.7.1.0 (2005/04/26)
		validDuration	= -1;
		hrefOnly		= false;	// 4.0.0 (2005/11/30)
		hrefTarget		= false;	// 5.5.5.6 (2012/08/31)
//		useURLCheck		= false;	// 4.3.7.0 (2009/06/01)
		useURLCheck		= HybsSystem.sysBool( "LINK_URL_CHECK" );			// 5.10.11.0 (2019/05/03)
		urlCheckUser	= null;		// 4.3.7.0 (2009/06/01)
		urlCheckTime	= INIT_TIME;		// 6.2.5.0 (2015/06/05)
//		urlCheckCrypt	= null;				// 5.8.8.0 (2015/06/05)
		urlCheckCrypt	= HybsSystem.sys( "URL_CHECK_CRYPT" );				// 5.9.32.1 (2018/05/11)
		useHrefEncode	= HybsSystem.sysBool( "USE_HREF_URLENCODE" );		// 6.0.2.0 (2014/09/19)
		strictCheck		= true;		// 6.7.6.0 (2017/03/17)
//		extToken		= null;												// 5.8.2.1 (2014/12/14) 6.9.5.0 (2018/04/23) extToken 廃止
//		ctArray			= null;												// 5.8.2.1 (2014/12/14) 6.9.5.0 (2018/04/23) extToken 廃止
		useForceEnc		= false;	// 5.10.15.3 (2019/09/27)
		useBackLink		= null;		// 7.3.1.0 (2021/02/02)
	}

	/**
	 * リンクを作成します。
	 *
	 * これは、HTMLTagSupportのmakeTag()のオーバーライド用のメソッドです。
	 * ViewLinkTag経由の場合は、引数 true で、独自のメソッドを呼び出します。
	 * これは、戻り行番号( BACK_ROW={I} )が、処理されないため、IE上でエラーが発生するのを
	 * 避けるためです。
	 *
	 * @og.rev 6.7.3.0 (2017/01/27) Override用のメソッドを用意しておきます。
	 *
	 * @return	リンクタグ文字列
	 * @og.rtnNotNull
	 */
	@Override
	protected String makeTag() {
		return makeTag( true );		// 互換性。ViewLinkTag経由の場合
	}

	/**
	 * リンクを作成します。
	 *
	 * @og.rev 3.5.5.0 (2004/03/12) xlink 属性に応じたリンク文字を作成します。
	 * @og.rev 3.5.6.2 (2004/07/05) XHTMLTag の変換値のみを返す様に変更。
	 * @og.rev 3.7.0.3 (2005/03/01) リンク作成時に行番号を引数に追加する。
	 * @og.rev 4.0.0.0 (2005/11/30) href 属性のみを返します。
	 * @og.rev 4.0.1.0 (2007/12/17) BACK_ADDRESSの追加
	 * @og.rev 4.3.3.5 (2008/11/08) サーバーアドレスを取得する際に、リクエストから取得するように変更します。
	 * @og.rev 4.3.7.0 (2009/06/01) URLチェック機能対応
	 * @og.rev 4.3.7.1 (2009/06/08) ↑の実装を#doEndTagに移動
	 * @og.rev 5.5.5.6 (2012/08/31) 「href="*******" target="******"」 という キー付きの文字列を作成
	 * @og.rev 6.0.2.0 (2014/09/19) useHrefEncode 属性対応
	 * @og.rev 6.2.0.1 (2015/03/06) hrefアドレスのASCII以外の文字の、URLエンコードを行う。
	 * @og.rev 6.4.4.1 (2016/03/18) StringBuilderの代わりに、OgBuilderを使用する。
	 * @og.rev 6.7.3.0 (2017/01/27) ViewLinkTag経由の判定を入れる。
	 * @og.rev 5.10.15.3 (2019/09/27) forceEnc追加
	 * @og.rev 7.3.1.0 (2021/02/02) useBackLink で戻るﾘﾝｸの制御を行う。
	 *
	 * @param	useViewLink ViewLinkTag経由の判定 [true:ViewLinkTag経由/false:その他]
	 * @return	リンクタグ文字列
	 * @og.rtnNotNull
	 */
	private String makeTag( final boolean useViewLink ) {

		makeGamenLink();		// 3.5.6.2 (2004/07/05)
		if( get( "body" ) == null ) { set( "body" , get( "href" ) ); }

		// xlink と通常の link では、URL接続文字が異なる。
		final String sep = xlink ? "&amp;" : "&" ;

		final OgBuilder urlEncBuf = new OgBuilder()
//				.append( XHTMLTag.urlEncode( keys,vals,sep ) );
				.append( XHTMLTag.urlEncode( keys,vals,sep,useForceEnc ) );		// 5.10.15.3 (2019/09/27)
		// 3.5.6.2 (2004/07/05) addBackGamenId() メソッドの内容を移動
		if( useGamenId ) {
			urlEncBuf.appendIf( useViewLink , sep , "BACK_ROW={I}" )					// ViewLinkTag経由の場合のみ、出力します。
					 .append( sep , "BACK_GAMENID=" , getGUIInfoAttri( "KEY" ) )
					 .appendIf( gamenId != null && !gamenId.isEmpty()					// if
							, sep , "GAMENID=" , gamenId )
					 .append( sep , "BACK_ADDRESS=" )
					 .append( getContextURL() , getGUIInfoAttri( "ADDRESS" ) , "/index.jsp" );
		}
		// 6.0.2.0 (2014/09/19) useHrefEncode 属性対応
		else if( useHrefEncode ) {
			String furl = get( "href" );
			if( furl != null ) {
				furl = StringUtil.urlEncode2( furl );							// ASCII以外の文字の、URLエンコードを行う。
				set( "href",furl );
			}
		}

		urlEncBuf.appendNN( sep,"useBackLink=" , useBackLink );					// 7.3.1.0 (2021/02/02) useBackLink で戻るﾘﾝｸの制御を行う。

		final String urlEnc = urlEncBuf.toString();

		// 4.0.0 (2005/11/30) href 属性のみを返します。
		if( hrefOnly ) {
			return XHTMLTag.addUrlEncode( get( "href" ),urlEnc,sep );
		}

		// 5.5.5.6 (2012/08/31) 「href="*******" target="******"」 という キー付きの文字列を作成
		if( hrefTarget ) {
			final StringBuilder hrefTemp = new StringBuilder( BUFFER_MIDDLE );

			// 6.0.2.5 (2014/10/31) char を append する。
			hrefTemp.append( "href=\"" ).append( XHTMLTag.addUrlEncode( get( "href" ),urlEnc,sep ) ).append( '"' );

			final String target = get( "target" ) ;
			if( target != null && !target.isEmpty() ) {
				hrefTemp.append( " target=\"" ).append( target ).append( '"' );		// 6.0.2.5 (2014/10/31) char を append する。
			}

			return hrefTemp.toString() ;
		}

		if( xlink ) {
			return XHTMLTag.xlink( getAttributes(),urlEnc ) ;
		}
		else {
			return XHTMLTag.link( getAttributes(),urlEnc ) ;
		}
	}

	/**
	 * ダイレクトジャンプリンクを作成します。
	 *
	 * gamenId を指定しなければ、この画面が指定されたと考えます。
	 * target を指定しなければ、"_blank" を指定します。
	 * msg がなければ(または、BODY部が空の場合)、画面名にこのリンクを作成します。
	 *
	 * @og.rev 3.7.1.0 (2005/04/26) 新規追加
	 * @og.rev 4.0.0.0 (2005/09/30) リンク文字列をハッシュ化します。
	 * @og.rev 4.3.3.5 (2008/11/08) サーバーアドレスを取得する際に、リクエストから取得するように変更します。
	 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
	 *
	 * @return	ダイレクトジャンプリンク文字列
	 */
	private String makeDirectLink() {

	 	// gamenId を指定しなければ、この画面が指定されたと考えます。
		if( gamenId == null ) {
			gamenId = getGUIInfoAttri( "KEY" );
		}

	 	// キャッシュ情報と keys,vals情報を設定します。
		if( useRequestCache ) { makeRequestCache2Vals( gamenId ); }
		final String urlEnc = XHTMLTag.urlEncode( keys,vals )
							+ "&GAMENID=" + gamenId ;

		String href = get( "href" );
		if( href == null || href.isEmpty() ) {
			// 4.3.3.5 (2008/11/08) サーバーアドレスを取得する際に、リクエストから取得するように変更します。
			href = getContextURL() + "index.jsp" ;
		}

		final String redirectURL = href + "?" + urlEnc ;
		final String name = getGUIInfoAttri( "LNAME" );

		String validDate = null;	// 設定されない場合は、無制限
		if( validDuration != 0 ) {
			if( validDuration < 0 ) {	// マイナスの場合は、初期値が使われます。
				validDuration = sysInt( "LINK_VALID_DURATION_DAYS" );
			}
			                                             //  ミリ秒    秒    時間
			final long nowTime = System.currentTimeMillis() + 1000L * 3600L * 24L * validDuration ;
			validDate = DateSet.getDate( nowTime,"yyyyMMdd" );				// 6.4.2.0 (2016/01/29)
		}
		final String userid   = getUser().getUserID();

		final URLXfer xfer = new URLXfer();
		// redirectURL,name,validDate,userid
		return xfer.getRandomURL( redirectURL,name,validDate,userid );
	}

	/**
	 * リクエストキャッシュ情報を加味した keys,vals を再作成します。
	 * このメソッドは、ダイレクトジャンプ時のみ有効です。
	 *
	 * リクエスト情報のMapを取り出します。そのとき、keys,vals を優先して
	 * 設定します。
	 *
	 * @og.rev 3.7.1.0 (2005/04/26) 新規追加
	 *
	 * @param	gamenId	画面ID (リクエストキャッシュの取り出しキー)
	 */
//	@SuppressWarnings(value={"unchecked"})
	private void makeRequestCache2Vals( final String gamenId ) {
		final Map<String,String[]> reqMap = new HashMap<>();

		final String reqKey = HybsSystem.REQ_CACHE_KEY + gamenId ;
		@SuppressWarnings(value={"unchecked"})		// 8.2.1.0 (2022/07/15) ﾒｿｯﾄﾞ全体から局所化
		final Map<String,String[]> attMap = (Map<String,String[]>)getSessionAttribute( reqKey );
		if( attMap != null ) { reqMap.putAll( attMap ); }

		if( keys != null ) {
			for( int i=0; i<keys.length; i++ ) {
				// keys,vals をキャッシュに上書き( キャッシュは、文字列配列)
				final String[] temp = new String[] { vals[i] } ;
				reqMap.put( keys[i],temp );
			}
		}

		// ダイレクトジャンプするための画面IDは、別途設定するため、削除しておきます。
		reqMap.remove( "GAMENID" );

		// 使用しないキーを、削除しておきます。
		if( delKeys != null ) {
			for( int i=0; i<delKeys.length; i++ ) {
				reqMap.remove( delKeys[i] );
			}
		}

		// マップキーを取得。キャッシュ値は、String[] なので、複数キー登録する。
		// 6.3.9.0 (2015/11/06) 配列にせずに、拡張for文で処理する。

		final List<String> v_keys = new ArrayList<>();
		final List<String> v_vals = new ArrayList<>();
		for( final Map.Entry<String,String[]> entry : reqMap.entrySet() ) {
			final String   kk = entry.getKey();
			final String[] vv = entry.getValue();
			if( vv != null ) {
				for( final String val : vv ) {
					v_keys.add( kk );
					v_vals.add( val );
				}
			}
		}

		keys = v_keys.toArray( new String[v_keys.size()] );
		vals = v_vals.toArray( new String[v_vals.size()] );
	}

	/**
	 * ファイルの存在チェックを行います。
	 *
	 * 実ファイルは、URL(httpの引数)より、変換して求めます。
	 *
	 * @og.rev 3.1.8.0 (2003/05/16) 画面のロールに応じて、リンクを張る/張らないを自動判断する。
	 *
	 * @return	ファイルが存在する(true)/存在しない(false)
	 */
	private boolean isFileCheck() {
		boolean rtn = true;

		if( fileCheck ) {
			File file = null;

			final String url  = get( "href" );
			if( url != null ) {
				final String fin = HybsSystem.url2dir( url );
				file = new File( fin );
			}
			rtn = file != null && file.exists() ;
		}

		return rtn ;
	}

	/**
	 * リンク先の画面のロールに応じて、リンクを張る/張らないを自動判断を行います。
	 *
	 * リンク先の画面ＩＤは、gamenId 属性で指定してください。それ以外のリンクは、
	 * 自動判断できません。
	 * link タグ単独の場合に、画面にアクセスできない場合は、メッセージも表示されません。
	 * viewLink タグを利用される場合は、リンクのON/OFF で制御します。
	 *
	 * @og.rev 3.1.8.0 (2003/05/16) 画面のロールに応じて、リンクを張る/張らないを自動判断する。
	 * @og.rev 4.0.0.0 (2005/01/31) GUIオブジェクトがマップに無ければ、アクセスできない。
	 *
	 * @return	画面アクセス許可する(true)/許可しない(false)
	 */
	private boolean isGamenCheck() {
		boolean rtn = true;

		if( gamenId != null ) {
			final GUIInfo guiInfo = getGUIInfo( gamenId );		// 4.0.0 (2005/01/31)

			// 4.0.0 (2005/01/31) ユーザー毎にアクセスできるGUIが設定されている為
			// 存在しなければ、アクセス不可ということ。
			if( guiInfo == null ) { rtn = false; }
		}

		return rtn ;
	}

	/**
	 * 画面ＩＤとhref から、指定のＵＲＬを作成します。
	 *
	 * @og.rev 3.1.2.0 (2003/04/07) リンク指定時に、画面IDを渡して、実アドレスを求める事ができる様にする。
	 * @og.rev 3.1.8.0 (2003/05/16) リンク作成時に、kyes/values が null の時の処理の修正。
	 * @og.rev 3.1.8.0 (2003/05/16) GAMENID属性のＵＲＬへの自動セットを行うかどうかを決める属性( useGamenId )を追加。
	 * @og.rev 3.1.8.0 (2003/05/16) 画面ＩＤが指定されたときのリンク情報作成方法を通常のリンク時にも適用する。
	 * @og.rev 3.5.5.0 (2004/03/12) URLを求めるのに、GUIInfo#getRealAddress() を使用する。
	 * @og.rev 4.0.0.0 (2005/01/31) GUIInfoの実アドレスのパラメータを考慮する。
	 *
	 */
	private void makeGamenLink() {
		if( gamenId == null || gamenId.isEmpty() ) { return ; }	// 4.0.0 (2005/11/30)

		final GUIInfo guiInfo = getGUIInfo( gamenId );		// 4.0.0 (2005/01/31)
		if( guiInfo == null ) { return ; }	// 見つからない場合は、アクセス不可

		final String address = guiInfo.getRealAddress( get( "href" ) );
		final String url = getRequestParameter( address );
		set( "href",url );

		final String label = guiInfo.getLabel();
		if( get( "title" ) == null ) {
			set( "title","To:" + label );
		}
		if( get( "body" ) == null ) {
			set( "body",label );
		}
	}

	/**
	 * リクエストからサーバーアドレス(例：http://hn5120:8824/ver4/jsp/)を取得します。
	 *
	 * システムリソースに、SERVER_ACCESS_URL キーで設定されているアドレスが優先されます。
	 * 例）https://www.xxx:8080 まで
	 *
	 * @og.rev 4.3.3.5 (2008/11/08) 新規追加。
	 * @og.rev 5.4.3.8 (2011/01/24) プロトコルhttps対応
	 * @og.rev 5.10.16.3 (2019/10/25) accessURL対応
	 *
 	 * @return	サーバーアドレス文字列
	 * @og.rtnNotNull
	 */
	private String getContextURL() {
		final HttpServletRequest request = (HttpServletRequest) getRequest();
//		final StringBuilder link = new StringBuilder( BUFFER_MIDDLE )
//			.append( request.getScheme()     ).append( "://" )		// 5.4.3.8
//			.append( request.getServerName() ).append( ':' )		// 6.0.2.5 (2014/10/31) char を append する。
//			.append( request.getServerPort() )
//			.append( request.getContextPath() )
//			.append( "/jsp/" );
//		return link.toString();

		final StringBuilder link = new StringBuilder( BUFFER_MIDDLE );
		if( StringUtil.isEmpty( SERVER_ACCESS_URL ) ) {
			//link.append( "http://" );
			link.append( request.getScheme() ).append( "://" )		// 5.4.3.8
				.append( request.getServerName() ).append( ':' )
				.append( request.getServerPort() );
		}
		else {
			link.append( SERVER_ACCESS_URL );						// 5.10.16.3 (2019/10/25) accessURL対応
		}

		return link.append( request.getContextPath() ).append( "/jsp/" ).toString();
	}

	/**
	 * 【HTML】リンク先のMIMEタイプを指定します。
	 *
	 * @og.tag リンク先のMIMEタイプを指定します。
	 *
	 * @param	type MIMEタイプ
	 */
	public void setType( final String type ) {
		set( "type",getRequestParameter( type ) );
	}

	/**
	 * 【HTML】この要素をリンクの対象とするための名前を指定します。
	 *
	 * @og.tag この要素をリンクの対象とするための名前を指定します。
	 *
	 * ※ HTML5では、a要素のname属性は廃止されています。
	 * HTML4.01におけるname属性は、ウェブページ内の特定個所に名前を付けて、
	 * ページ内リンクを作成する際などに使用していました。 HTML5で同様の
	 * 機能を作成する場合にはid属性を使用します。 id属性は、ひとつの
	 * 文書の中では重複して同じ名前を付けることはできないので、
	 * ウェブページ内の場所を一意に特定できます。
	 *
	 * @param	name 名前
	 * @see		<a href="http://www.htmq.com/html5/a.shtml">a</a>
	 */
	public void setName( final String name ) {
		set( "name",getRequestParameter( name ) );
	}

	/**
	 * 【TAG】リンクをつけたいカラムを指定します(ViewLink タグと併用)。
	 *
	 * @og.tag
	 * このカラム名のTableModelに対して、 ViewLink タグが存在する場合は,
	 * リンクを張ります。
	 *
	 * @param	clm カラム
	 */
	public void setColumn( final String clm ) {
		this.column = getRequestParameter( clm );
	}

	/**
	 * 【HTML】リンク先のURLを指定します。
	 *
	 * @og.tag リンク先のURLを指定します。
	 *
	 * @param	href リンク先のURL
	 */
	public void setHref( final String href ) {
		set( "href",getRequestParameter( href ) );
	}

	/**
	 * 【HTML】リンク先の基本となる言語コードを指定します。
	 *
	 * @og.tag リンク先の基本となる言語コードを指定します。
	 *
	 * @param	hreflang 言語コード
	 */
	public void setHreflang( final String hreflang ) {
		set( "hreflang",getRequestParameter( hreflang ) );
	}

	/**
	 * 【HTML】この文書から見た、href属性で指定されるリンク先との関係を指定します。
	 *
	 * @og.tag この文書から見た、href属性で指定されるリンク先との関係を指定します。
	 *
	 * @param	rel リンク先との関係
	 */
	public void setRel( final String rel ) {
		set( "rel",getRequestParameter( rel ) );
	}

	/**
	 * 【HTML】href属性で指定されるリンク先から見た、この文書との関係をしてします。
	 *
	 * @og.tag href属性で指定されるリンク先から見た、この文書との関係をしてします。
	 *
	 * @param	rev リンク先から見たこの文書との関係
	 */
	public void setRev( final String rev ) {
		set( "rev",getRequestParameter( rev ) );
	}

	/**
	 * 【HTML】リンク先の文字コードセットを指定します。
	 *
	 * @og.tag リンク先の文字コードセットを指定します。
	 *
	 * @param	charset 文字コードセット
	 */
	public void setCharset( final String charset ) {
		set( "charset",getRequestParameter( charset ) );
	}

	/**
	 * 【HTML】リンク先の表示ターゲットを指定します。
	 *
	 * @og.tag リンク先の文書を表示させるフレーム、またはウィンドウの名前を指定します。
	 *
	 * @param	target ターゲット
	 */
	public void setTarget( final String target ) {
		set( "target",getRequestParameter( target ) );
	}

	/**
	 * 【HTML】リンクボタンの形状[rect/circle/poly/default]を指定します。
	 *
	 * @og.tag HTMLのイメージマップとして指定できる設定値[rect/circle/poly/default]を指定します。
	 *
	 * @param	shape 形状 [rect/circle/poly/default]
	 */
	public void setShape( final String shape ) {
		set( "shape",getRequestParameter( shape ) );
	}

	/**
	 * 【HTML】リンクボタンの座標を指定します。
	 *
	 * @og.tag
	 * coords セット
	 *
	 * @param	coords リンクボタンの座標
	 */
	public void setCoords( final String coords ) {
		set( "coords",getRequestParameter( coords ) );
	}

	/**
	 * 【TAG】リンク先に渡すキーをCSV形式で複数指定します。
	 *
	 * @og.tag リンク先に渡すキーを指定します。
	 * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
	 * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
	 *
	 * @og.rev 3.5.6.2 (2004/07/05) CommonTagSupport#getCSVParameter を使用
	 *
	 * @param	key キー(CSV形式)
	 */
	public void setKeys( final String key ) {
		keys = getCSVParameter( key );
	}

	/**
	 * 【TAG】リンク先に渡す値をCSV形式で複数指定します。
	 *
	 * @og.tag リンク先に渡す値を指定します。
	 * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
	 * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
	 * keys,vals を使用すると、URLエンコードされます。
	 *
	 * @og.rev 3.5.6.2 (2004/07/05) CommonTagSupport#getCSVParameter を使用
	 *
	 * @param	val 値(CSV形式)
	 */
	public void setVals( final String val ) {
		vals = getCSVParameter( val );
	}

	/**
	 * 【TAG】リンクを張る(true or 1)/張らない(false or 0)の設定を指定します(初期値:true)。
	 *
	 * @og.tag
	 * リンクを張る場合は、"true"(または "1") リンクを張らない
	 * 場合は, "true以外"(または "0")をセットします。
	 * 初期値は、 "true"(リンクを張る)です。
	 * さらに、[カラム名] で、動的にカラムの値で、リンクを張る、張らないを
	 * 選ぶ事が可能になります。値は、"true"(または "1") で、マークします。
	 * 追記 3.5.2.0 (2003/10/20)：markList属性に、処理対象文字列郡を指定できます。
	 * これにより、リンクを処理するかどうかの判断が、true,1 以外にも使用できるようになりました。
	 *
	 * @og.rev 3.5.2.0 (2003/10/20) markList属性を追加
	 *
	 * @param	flag リンクの設定 [true,1:リンクを張る/true,1以外:リンクを張らない]
	 */
	public void setOnLink( final String flag ) {
		onLink = nval( getRequestParameter( flag ),onLink );
	}

	/**
	 * 【TAG】ファイルの存在チェックを行うかどうか[true/false]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * "true"の場合は、ファイルの存在チェックを行い、ファイルがあれば
	 * リンクを張ります。ファイルが存在しない場合は, 何も表示されません。
	 * 初期値は、 "false"(ファイルチェックを行わない)です。
	 * 注意：現状、viewLink タグからの使用は出来ませんので、ご了承願います。
	 *
	 * @param	flag 存在チェック [true:行う/false:行わない])
	 */
	public void setFileCheck( final String flag ) {
		fileCheck = nval( getRequestParameter( flag ),fileCheck );
	}

	/**
	 * 【TAG】アドレスにファイルのディレクトリ直接のアドレスを指定するかどうか[true/false]設定します(初期値:false)。
	 *
	 * @og.tag
	 * "true"の場合は、ファイルの物理ディレクトリをリンクします。
	 * 初期値は、 "false"(ファイルの直接アドレスを行わない)です。
	 *
	 * @param	flag ファイルのディレクトリ直接のアドレスの指定 [true:直接アドレス/その他:通常のURL]
	 */
	public void setFilePath( final String flag ) {
		filePath = nval( getRequestParameter( flag ),filePath );
	}

	/**
	 * 【TAG】画面ID を指定します。
	 *
	 * @og.tag
	 * gamenId 属性は、画面IDをキーに、実アドレスを求めるのに使用します。
	 * 画面IDが指定された場合は、実アドレスに変換する。指定されない場合は、
	 * href 属性をそのままリンク情報を作成します。
	 * 画面IDを指定する場合の href は、JSPファイル名(例えば、index.jsp 等)です。
	 * ※ 画面ID属性は、[カラム名]等の動的指定はできません。
	 *
	 * @og.rev 3.1.2.0 (2003/04/07) リンク指定時に、画面IDを渡して、実アドレスを求める事ができる様にする。
	 *
	 * @param   id 画面ID属性
	 */
	public void setGamenId( final String id ) {
		gamenId = nval( getRequestParameter( id ),gamenId );
	}

	/**
	 * 【TAG】GAMENID,BACK_GAMENID 属性を付加するかどうか[true/false]を設定します(初期値:true)。
	 *
	 * @og.tag
	 * "true"の場合は、GAMENID,BACK_GAMENID 属性を href に追加します。(?KEY1=VAL1&amp;KEY2=VAL2･･･)
	 * "false"の場合は、付加しません。
	 * JavaScript や、通常のファイル( .html や .pdf 等)に、GAMENID,BACK_GAMENID 属性を付けないように
	 * する事が出来ます。
	 * 初期値は、 "true"(GAMENID,BACK_GAMENID 属性を href に追加する)です。
	 *
	 * @og.rev 3.1.8.0 (2003/05/16) GAMENID属性のＵＲＬへの自動セットを行うかどうかを決める属性( useGamenId )を追加。
	 *
	 * @param	flag BACK_GAMENID属性の追加可否 [true:追加する/その他:追加しない]
	 */
	public void setUseGamenId( final String flag ) {
		useGamenId = nval( getRequestParameter( flag ),useGamenId );
	}

	/**
	 * 【TAG】処理するマークを含むような文字列を、"|"区切りの文字列で指定します(初期値:"true|TRUE|1")。
	 *
	 * @og.tag
	 * markListで与えられた文字列に、onLink文字列(大文字/小文字の区別あり)が
	 * 含まれていれば、処理します。
	 * 例えば、"A","B","C" という文字列が、onLink で指定された
	 * 場合に処理するようにしたい場合は、"A|B|C" をセットします。
	 * markList には、[カラム名]指定が可能です。
	 * 初期値は、 "true|TRUE|1"です。
	 *
	 * @og.rev 3.5.2.0 (2003/10/20) 新規追加
	 *
	 * @param	list 処理するマーク (indexOf による含む/含まない判定)
	 */
	public void setMarkList( final String list ) {
		markList = nval( getRequestParameter( list ),markList );
	}

	/**
	 * 【TAG】href ではなく、xlink:href を使用するかどうか[true/false]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * xlink:href 属性は、XMLでのリンクを指定します。その場合、href 属性で指定した
	 * 内容は、xlink:href に置き換えられます。
	 * また、URL文字列の接続文字列(&amp;)を、(&amp;amp;)で接続します。これは、xlink として、
	 * XMLファイルに埋め込む場合に、置き換えが必要な為です。
	 * 初期値は、 "false"(通常の href) です。
	 *
	 * @og.rev 3.5.5.0 (2004/03/12) 新規追加
	 *
	 * @param	lnk XMLリンクを使用可否 [true:する/false:しない]
	 */
	public void setXlink( final String lnk ) {
		xlink = nval( getRequestParameter( lnk ),xlink );
	}

	/**
	 * 【TAG】ダイレクトジャンプを使用するかどうか[true/false]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * ダイレクトジャンプ(指定の画面へ直接飛ばす)は、簡易ワークフロー的に、画面への
	 * リンクを作成する場合に使用します。一般には、メール本文に記述して、指定の画面まで
	 * 直接飛ばす場合に使用します。
	 * このリンクは、その画面の index.jsp に直接ジャンプします。
	 *
	 * gamenId を指定しなければ、この画面が指定されたと考えます。
	 * target を指定しなければ、"_blank" を指定します。
	 * msg がなければ(または、BODY部が空の場合)、画面名にこのリンクを作成します。
	 * 初期値は、 "false"(使用しない) です。
	 *
	 * @og.rev 3.7.1.0 (2005/04/26) 新規追加
	 *
	 * @param	directJump ダイレクトジャンプを使用可否 [true:する/false:しない]
	 */
	public void setUseDirectJump( final String directJump ) {
		useDirectJump = nval( getRequestParameter( directJump ),useDirectJump );
	}

	/**
	 * 【TAG】リクエストキャッシュ情報を使用するかどうか[true/false]を指定します(初期値:true)。
	 *
	 * @og.tag
	 * リクエストキャッシュ情報は、戻るリンクで画面を差表示(command=RENEW)する場合に
	 * 最後に検索に利用された情報をキャッシュしておき、再利用する場合に利用する値です。
	 * ダイレクトジャンプ機能(useDirectJum=true)の場合のみ有効です。
	 * 戻るリンクによる再表示は、各画面自身が持っている情報を利用しますが、
	 * ダイレクトジャンプ等で、すでにキャッシュが存在していない(セッションが異なっている)
	 * 場合に、リンク情報に直接紐付けて、再検索させる必要がある場合に利用します。
	 * このキャッシュは、keys,vals による値の再設定で、書き換えることが可能です。
	 *
	 * 初期値は、 "true"(使用する) です。
	 *
	 * @og.rev 3.7.1.0 (2005/04/26) 新規追加
	 *
	 * @param	useCache リクエストキャッシュ使用可否 [true:する/false:しない]
	 */
	public void setUseRequestCache( final String useCache ) {
		useRequestCache = nval( getRequestParameter( useCache ),useRequestCache );
	}

	/**
	 * 【TAG】リクエストキャッシュ情報使用時に使用しない(削除する)キーをCSV形式で複数指定します。
	 *
	 * @og.tag
	 * リクエストキャッシュ情報には、一般に検索時に使用されたすべての引数が
	 * 使用されます。この引数を、転送先画面では、使用しないケースがあり、その場合に、
	 * 指定のキー情報を、削除します。
	 * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
	 * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
	 *
	 * @og.rev 3.7.1.0 (2005/04/26) 新規追加
	 *
	 * @param	key	使用しない(削除する)キー(CSV形式)
	 */
	public void setDelKeys( final String key ) {
		delKeys = getCSVParameter( key );
	}

	/**
	 * 【TAG】ダイレクトジャンプリンク時のハッシュ化されたURLの有効期間を日数を指定します
	 *		(初期値:LINK_VALID_DURATION_DAYS[={@og.value SystemData#LINK_VALID_DURATION_DAYS}])。
	 *
	 * @og.tag
	 * ダイレクトジャンプリンクの引数を作成する場合、有効期限を指定できます。
	 * ここでは、設定時刻からの有効期間を日数指定します。
	 * 実際には、GE17のvalidDateカラムに設定される、日付と現在日を比較して、
	 * 有効かどうかを判断します。
	 * ゼロが指定された場合は、制限なしに設定されます。マイナスの場合は、初期値が使われます。
	 * (初期値:ユーザー定数のLINK_VALID_DURATION_DAYS[={@og.value SystemData#LINK_VALID_DURATION_DAYS}])。
	 *
	 * @og.rev 4.0.0.0 (2005/09/30) 新規追加
	 *
	 * @param	validDura	URLの有効期間日数
	 * @see		org.opengion.hayabusa.common.SystemData#LINK_VALID_DURATION_DAYS
	 */
	public void setValidDuration( final String validDura ) {
		validDuration = nval( getRequestParameter( validDura ),validDuration );
	}

	/**
	 * 【TAG】リンク(アンカータグ)ではなく、href 属性をそのまま返すかどうか[true/false]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * 通常のリンクは、アンカータグ(aタグ)の状態で出力されます。その場合、HTML上では
	 * リンクとして表示されます。このフラグをtrue にセットすると、リンク文字列
	 * そのものが出力されます。これは、リンク文字列を作成してDBに登録する場合などに
	 * 使用します。
	 *
	 * 7.1.0.1 (2020/02/07)
	 *  hrefOnly 属性を true に設定した場合は、URL全体をurlEncodeします。
	 *
	 * 初期値は、false:リンク です。
	 *
	 * @og.rev 4.0.0.0 (2005/11/30) 新規追加
	 *
	 * @param	flag href属性 [true:href属性/false:リンク]
	 */
	public void setHrefOnly( final String flag ) {
		hrefOnly = nval( getRequestParameter( flag ),hrefOnly );
	}

	/**
	 * 【TAG】リンク(アンカータグ)ではなく、href 属性と、target属性を キーも含めて返すかどうか[true/false]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * 内容的には、hrefOnly と類似の機能で、アンカータグ(aタグ)の出力ではなく、href 属性と、
	 * target属性を キーも含めて作成します。
	 * 「href="*******" target="******"」 という形式になります。
	 * これは、クリッカブルマップ等の href 属性と target属性の両方を使用するようなケースで使います。
	 * また、onLink、markList を使ったリンク作成可否の処理をおこなった場合、通常であれば、
	 * 指定のカラムの値が取得できますが、その場合は、先頭文字列が、href かどうかを判定することで、
	 * リンク作成可否の判断が可能です。
	 * 逆に言えば、この属性を true にセットした場合は、先頭文字列が、href で始まることが保障されます。
	 * hrefOnly = true と同時に設定した場合は、hrefOnly が優先されます。
	 *
	 * 初期値は、false:リンク です。
	 *
	 * @og.rev 5.5.5.6 (2012/08/31) 新規追加
	 *
	 * @param	flag 出力形式 [true:href,target形式/false:リンク]
	 */
	public void setHrefTarget( final String flag ) {
		hrefTarget = nval( getRequestParameter( flag ),hrefTarget );
	}

	/**
	 * 【TAG】リンクアドレスにURLチェック用の確認キーを付加するかどうか[true/false]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * この属性は、URLCheckFilter(org.opengion.hayabusa.filter.URLCheckFilter)と合わせて使用します。
	 * trueが指定された場合、リンクURLのパラメーターに、URL確認用のパラメーターが出力されます。
	 * このパラメーターを、URLCheckFilterが復号化し、正式なアクセスであるかどうかの判定を行います。
	 *
	 * 初期値は、 システムリソースのLINK_URL_CHECK です。
	 *
	 * @og.rev 4.3.7.0 (2009/06/01) 新規追加
	 *
	 * @param	flag 暗号化するかかどうか [true:暗号化する/false:しない]
	 * @see org.opengion.hayabusa.filter.URLCheckFilter
	 */
	public void setUseURLCheck( final String flag ) {
		useURLCheck = nval( getRequestParameter( flag ),useURLCheck );
	}

	/**
	 * 【TAG】URLチェック用の確認キーに対して、リンクを開くことのできるユーザーIDを指定します(初期値:ログインユーザー)。
	 *
	 * @og.tag
	 * URLチェック用の確認キーに対して、リンクを開くことのできるユーザーIDを
	 * CSV形式で指定します。
	 * "*"が指定された場合、ユーザーチェックは行われません。
	 *
	 * 初期値は、 ログインユーザーです。
	 *
	 * @og.rev 4.3.8.0 (2009/08/01) 新規追加
	 *
	 * @param	user リンクにアクセス可能なユーザー一覧
	 */
	public void setUrlCheckUser( final String user ) {
		urlCheckUser = nval( getRequestParameter( user ),urlCheckUser );
	}

	/**
	 * 【TAG】URLチェック用の確認キーに対して、リンクの有効期限を指定します(初期値:60分)。
	 *
	 * @og.tag
	 * URLチェック用の確認キーに対して、リンクが生成されてからの有効期限を分単位で設定します。
	 * 属性値の先頭に'D'をつけることで、日付指定を行うことができます。
	 * (D20090612 ⇒ 20090612まで(当日を含む)は有効)
	 *
	 * 初期値は、現在時間を基準として+ "1440"(1日) です。
	 *
	 * @og.rev 4.3.8.0 (2009/08/01) 新規追加
	 * @og.rev 6.2.5.0 (2015/06/05) urlCheckTimeの初期値を、INIT_TIMEに変更
	 *
	 * @param	time リンクの有効期限(分)
	 */
	public void setUrlCheckTime( final String time ) {
		final String tm = getRequestParameter( time );

		if( StringUtil.startsChar( tm , 'D' ) ) {			// 6.2.0.0 (2015/02/27) １文字 String.startsWith
			if( tm.length() < 9 ) {
				final String errMsg = "urlCheckTime属性の日付はYYYYMMDD形式で指定して下さい。"
							+ " 値=" + tm ;			// 5.1.8.0 (2010/07/01) errMsg 修正
				throw new HybsSystemException( errMsg );
			}
			final Calendar cal = new GregorianCalendar(
					Integer.parseInt( tm.substring( 1, 5 ) )
					,Integer.parseInt( tm.substring( 5, 7 ) ) - 1
					,Integer.parseInt( tm.substring( 7, 9 ) ) );		// 6.0.2.4 (2014/10/17) メソッド間違い
			urlCheckTime = INIT_TIME + cal.getTimeInMillis() - System.currentTimeMillis() ;		// 6.2.5.0 (2015/06/05)
		}
		// 6.2.5.0 (2015/06/05) tm が null でない時のみセット。null の場合は、初期値のままになる。
		else if( tm != null ) {
			// 6.3.9.0 (2015/11/06) 整数乗算の結果を long にキャストしている(findbugs)
			urlCheckTime = 60L * 1000L * Integer.parseInt( tm ) ;
		}
	}

	/**
	 * 【TAG】URLチェック用の暗号化キーを指定します(初期値:デフォルト)。
	 *
	 * @og.tag
	 * URLチェックに利用される暗号化のキーをしています。
	 * 受け側の設定(URL_CHECK_CRYPT)に合わせてください。
	 *
	 * 未指定の場合は標準が利用されます。
	 * (システムリソースURL_CHECK_CRYPTが設定されている場合はそちらを利用)
	 *
	 * @og.rev 5.8.8.0 (2015/06/05) 新規追加
	 *
	 * @param	crypt 暗号化キー
	 */
	public void setUrlCheckCrypt( final String crypt ) {
		urlCheckCrypt = nval( getRequestParameter( crypt ),urlCheckCrypt );
	}

	/**
	 * 【TAG】ファイルのhref 部分の一部をURLEncodeするかどうか[true/false]を指定します
	 *		(初期値:USE_HREF_URLENCODE[={@og.value SystemData#USE_HREF_URLENCODE}])。
	 *
	 * @og.tag
	 * ファイル等のリンクで、keys,vals は、URLEncode していましたが、URL に相当する箇所は
	 * http:// など URLEncode してはいけない箇所がある為、何もしていませんでした。
	 * ファイルのダウンロード等で、ファイル名に、";" や "%" が存在すると、認識できないため
	 * ファイルが見つからないエラーが発生していました。
	 * なお、ファイルに限定する意味で、useGamenId="false" の場合のみ、有効にします。
	 *	(初期値:USE_HREF_URLENCODE[={@og.value SystemData#USE_HREF_URLENCODE}])。
	 *
	 * ※ 6.2.0.1 (2015/03/06) ASCII以外の文字＋";" と "%"の、URLエンコードを行う様に仕様変更。
	 *
	 * @og.rev 6.0.2.0 (2014/09/19) 新規追加
	 *
	 * @param	useEnc hrefの一部をURLEncode可否 [true:する/false:しない]
	 */
	public void setUseHrefEncode( final String useEnc ) {
		useHrefEncode = nval( getRequestParameter( useEnc ),useHrefEncode );
	}

	/**
	 * 【TAG】(通常は使いません)カラムＩＤの存在チェックを行うかどうか[true/false]を指定します(初期値:true)。
	 *
	 * @og.tag
	 * true の場合、カラムＩＤがDBTableModel に存在しない場合は、エラーになります。
	 * false の場合、カラムＩＤがDBTableModel に存在しない場合は、無視します。
	 * これは、検索条件によって、設定されるカラムが異なる場合でも、後続処理を
	 * 正常に動作させたい場合に、使用します。
	 * 初期値は true (チェックを行う) です。
	 * この属性は、column属性とともに、ViewLink タグを使用する場合にのみ有効です。
	 *
	 * @og.rev 6.7.6.0 (2017/03/17) strictCheck 追加。
	 *
	 * @param  check 存在チェック [true:行う/false:行わない]
	 */
	public void setStrictCheck( final String check ) {
		strictCheck = nval( getRequestParameter( check ),strictCheck );
	}

	/**
	 * 【TAG】valsの値が[で開始している場合でもURLEncodeを通すかを設定します(初期値:false)。
	 *
	 * @og.tag
	 * テーブルモデルの値の変換のため、通常は先頭が[の場合はエンコードがかかりません。
	 * 強制的にかける場合にtrueにします。
	 *
	 * @og.rev 5.10.15.3 (2019/09/27) forceEnc追加
	 *
	 * @param flg URLEncodeを通す場合は、trueをｾｯﾄ
	 */
	public void setForceEnc( final String flg ) {
		useForceEnc = nval( getRequestParameter( flg ), useForceEnc );
	}

	/**
	 * 【TAG】(通常は使いません) 戻るリンクを表示(true)、必ず表示しない(false)、従来通り(null)を指定します。
	 *
	 * @og.tag
	 * 通常の戻るリンクは、自分自身へのリンク時には出さずに、別画面IDの場合のみ(条件が成立すれば)表示します。
	 * この属性を使用すると、自分自身へのリンク時でも、戻るﾘﾝｸを表示できます。
	 * 別画面へのリンクで、条件が成立していない場合に表示(true)を設定すると、戻ることができないため、
	 * 自分自身へのリンクを表示しますので、ご注意ください。
	 *
	 * true：相手先に(条件が成立すれば)戻るﾘﾝｸを表示。条件が成立しない場合は、自身へのリンクが表示。
	 * false:必ず表示しない
	 * 未指定(null):従来通り…自分自身では戻るリンクを表示せず、別画面の場合のみ表示します。
	 * 初期値は null (従来通り)です。
	 *
	 * @og.rev 7.3.1.0 (2021/02/02) useBackLink 追加。
	 *
	 * @param flg URLEncodeを通す場合は、trueをｾｯﾄ
	 */
	public void setUseBackLink( final String flg ) {
		useBackLink = nval( getRequestParameter( flg ), useBackLink );
	}

//	/**
//	 * 【TAG】外部（プラグイン）のトークンを利用する場合にプラグインを指定します。
//	 *
//	 * @og.tag
//	 * プラグインの名前を指定する事で、該当のCreateTokenを利用して
//	 * URLに対してトークンを付与します。
//	 * （CreatetToken_xxxのxxxを指定します）
//	 *
//	 * CSV形式を分解して、プラグインを配列として持ちます。
//	 * 適応は前から順番に行います。
//	 *
//	 * @og.rev 5.8.2.1 (2014/12/13) 新規追加
//	 * @og.rev 6.4.3.3 (2016/03/04) HybsSystem.newInstance(String,String) への置き換え。
//	 * @og.rev 6.9.5.0 (2018/04/23) extToken 廃止
//	 *
//	 * @param	name 利用するCreateTokenプラグイン
//	 */
//	public void setExtToken( final String name ) {
//		extToken = nval( getRequestParameter( name ),extToken );
//		ctArray  = new ArrayList<>();
//
//		if( extToken != null && extToken.length() > 0 ) {
//			final String[] tokens = StringUtil.csv2Array( extToken );
//			for( final String tk : tokens ) {
//				final CreateToken ct = HybsSystem.newInstance( "CreateToken_" , tk );
//				ctArray.add( ct );
//			}
//		}
//	}

	/**
	 * このオブジェクトの文字列表現を返します。
	 * 基本的にデバッグ目的に使用します。
	 *
	 * @return このクラスの文字列表現
	 * @og.rtnNotNull
	 */
	@Override
	public String toString() {
		return ToString.title( this.getClass().getName() )
				.println( "VERSION"			,VERSION		)
				.println( "column"			,column			)
				.println( "onLink"			,onLink			)
				.println( "fileCheck"		,fileCheck		)
				.println( "filePath"		,filePath		)
			// 7.2.7.0 (2020/08/07) 他の属性の関係で、baseURLをfileURL に変更
//				.println( "baseURL"			,baseURL		)
				.println( "fileURL"			,fileURL		)	// 7.2.7.0 (2020/08/07)
				.println( "gamenId"			,gamenId		)
				.println( "useGamenId"		,useGamenId		)
				.println( "markList"		,markList		)
				.println( "xlink"			,xlink			)
				.println( "useDirectJump"	,useDirectJump	)
				.println( "useRequestCache"	,useRequestCache)
				.println( "hrefOnly"		,hrefOnly		)
				.println( "hrefTarget"		,hrefTarget		)		// 5.5.5.6 (2012/08/31)
				.println( "strictCheck"		,strictCheck	)		// 6.7.6.0 (2017/03/17)
				.println( "validDuration"	,validDuration	)
				.println( "keys"			,keys			)
				.println( "vals"			,vals			)
				.println( "delKeys"			,delKeys		)
				.println( "useURLCheck"		,useURLCheck	)
				.println( "urlCheckUser"	,urlCheckUser	)
				.println( "urlCheckTime"	,urlCheckTime	)
				.println( "Other..."		,getAttributes().getAttribute() )
				.fixForm().toString() ;
	}
}
