    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.hayabusa.taglib;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020import org.opengion.hayabusa.resource.GUIInfo;
    021import org.opengion.hayabusa.resource.UserInfo;
    022import org.opengion.hayabusa.resource.FavoriteGUIData;
    023import org.opengion.fukurou.util.XHTMLTag;
    024import org.opengion.fukurou.util.ToString;                                                      // 6.1.1.0 (2015/01/17)
    025import org.opengion.fukurou.util.StringUtil ;                                           // 6.2.2.0 (2015/03/27)
    026
    027import static org.opengion.fukurou.util.StringUtil.nval ;
    028
    029import jakarta.servlet.http.HttpServletRequest ;
    030import jakarta.servlet.http.HttpServletResponse;
    031
    032import java.util.Enumeration;
    033import java.util.ArrayList;
    034import java.util.Map;
    035import java.util.concurrent.ConcurrentHashMap;                                          // 6.4.3.1 (2016/02/12) refactoring
    036
    037import java.io.IOException;
    038
    039/**
    040 * お気に入りリンクを作成するタグです(通常はresult.jspに組込み)。
    041 *
    042 * 画面検索時の引数やユーザー情報を元にして、ダイレクトに再検索できる
    043 * リンクを作成します。このリンクをお気に入り等にセーブしておき、次回検索時にも
    044 * 使用できるようにします。
    045 *
    046 * @og.formSample
    047 * ●形式：&lt;og:favoriteLink direct="true" target="_blank" method="GET" /&gt;
    048 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    049 *
    050 * ●Tag定義：
    051 *   &lt;og:favoriteLink
    052 *       target             【TAG】リンク先の文書を表示させるフレーム、またはウィンドウの名前を指定します(初期値:_blank)
    053 *       direct             【TAG】直接アクセスできる形式のリンクを作成するかどうか[true/false]を指定します(初期値:false)
    054 *       method             【TAG】リンクの作成元となるメソッド[POST/GET/ALL]を指定します(初期値:GET)
    055 *       href               【TAG】リンクを作成する時の転送先アドレスを指定します(初期値:index.jsp)
    056 *       lbl                【TAG】ラベルリソースのラベルIDを指定します
    057 *       linkCache          【TAG】リンクをキャッシュするかどうか[true/false]を指定します(初期値:false)
    058 *       lastQueryRedirect  【TAG】キャッシュされたリンク先に転送するかどうか[true/false]を指定します(初期値:false)
    059 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    060 *       useIcon            【TAG】お気に入りアイコンリンクを作成するかどうか[true/false]を指定します(初期値:false)
    061 *   &gt;   ... Body ...
    062 *   &lt;/og:favoriteLink&gt;
    063 *
    064 * ●使用例：
    065 *    直接お気に入りのリンクを作成する。
    066 *    デフォルト属性を使用(direct="true" target="_blank" method="GET")
    067 *    &lt;og:favoriteLink &gt; Favorite Link &lt;/og:favoriteLink &gt;
    068 *
    069 * @og.rev 7.3.2.3 (2021/04/09) ｼｽﾃﾑ定数のJSP_IMGを使用します。(※ SYS.JSP + SYS.IMAGE_DIR)
    070 * @og.group 画面部品
    071 *
    072 * @version  4.0
    073 * @author       Kazuhiko Hasegawa
    074 * @since    JDK5.0,
    075 */
    076public class FavoriteLinkTag extends CommonTagSupport {
    077        /** このプログラムのVERSION文字列を設定します。   {@value} */
    078        private static final String VERSION = "7.3.2.3 (2021/04/09)" ;
    079        private static final long serialVersionUID = 732320210409L ;
    080
    081        // 7.3.2.3 (2021/04/09) ｼｽﾃﾑ定数のJSP_IMGを使用します。(※ SYS.JSP + SYS.IMAGE_DIR)
    082        private static final String JSP_IMG =  HybsSystem.sys( "JSP_IMG" ) + "/" ;
    083
    084        /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。  */
    085        private static final Map<String,String> LAST_QUERY      = new ConcurrentHashMap<>();    // 6.4.1.1 (2016/01/16) lastQuery → LAST_QUERY  refactoring
    086
    087        private boolean         direct          ;                               // 3.0.0.0 初期値変更
    088        private String          target          = "_blank";             // 3.6.0.7 (2004/11/06)
    089        private String          method          = "GET";
    090        private String          href            = "index.jsp";  // 3.8.8.2 (2007/01/26)
    091        private boolean         linkCache       ;                               // 3.5.5.9 (2004/06/07)
    092        private boolean         redirect        ;                               // 3.5.5.9 (2004/06/07)
    093        private boolean         useIcon         ;                               // 4.1.1.0 (2008/02/13)
    094
    095        /**
    096         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    097         *
    098         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。ボディが存在する場合のみボディが呼ばれる対応。
    099         * @og.rev 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示します。
    100         * @og.rev 5.0.0.2 (2009/09/15) xss対応⇒チェックする
    101         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    102         *
    103         * @return      後続処理の指示
    104         */
    105        @Override
    106        public int doStartTag() {
    107                // 5.0.0.2 (2009/09/15) 強制False
    108                // useXssCheck( false );
    109
    110                // 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示
    111                if( redirect ) {
    112                        // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。key,val は、not null 制限。
    113                        final String uid = getUserInfo( "ID" );
    114
    115                        final String page = uid == null ? null : LAST_QUERY.get( uid ) ;
    116
    117                        if( page != null ) {
    118                                final HttpServletResponse response = (HttpServletResponse)pageContext.getResponse();
    119                                final String url = response.encodeRedirectURL( page );
    120                                try {
    121                                        response.sendRedirect( url );
    122                                }
    123                                catch( final IOException ex ) {
    124                                        final String errMsg = "最終画面の転送時のリダイレクトエラー" + toString();
    125                                        throw new HybsSystemException( errMsg,ex );
    126                                }
    127
    128                                return SKIP_BODY ;
    129                        }
    130                }
    131
    132                set( "body",getMsglbl() );
    133                return EVAL_BODY_BUFFERED ;     // Body を評価する。( extends BodyTagSupport 時)
    134        }
    135
    136        /**
    137         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    138         *
    139         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
    140         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。ボディが存在する場合のみボディが呼ばれる対応。
    141         *
    142         * @return      後続処理の指示(SKIP_BODY)
    143         */
    144        @Override
    145        public int doAfterBody() {
    146
    147                final String label = getBodyString();
    148
    149                if( label != null && label.length() > 0 ) {
    150                        set( "body",label );
    151                }
    152
    153                return SKIP_BODY ;
    154        }
    155
    156        /**
    157         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    158         *
    159         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    160         * @og.rev 4.1.1.0 (2008/0213) お気に入りアイコンリンクの作成
    161         *
    162         * @return      後続処理の指示
    163         */
    164        @Override
    165        public int doEndTag() {
    166                debugPrint();           // 4.0.0 (2005/02/28)
    167
    168                // method による条件判断。
    169                final String requestMethod = ((HttpServletRequest)getRequest()).getMethod();
    170                if( method != null &&
    171                        ( "ALL".equalsIgnoreCase( method ) ||
    172                          method.equalsIgnoreCase( requestMethod ) ) ) {
    173                                // 4.1.1.0 (2008/0213) お気に入りアイコンリンクの作成
    174                                if( useIcon ) {
    175                                        jspPrint( getFavoriteIcon() );
    176                                }
    177                                else {
    178                                        jspPrint( makeTag() );
    179                                }
    180                }
    181
    182                return EVAL_PAGE ;
    183        }
    184
    185        /**
    186         * タグリブオブジェクトをリリースします。
    187         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    188         *
    189         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    190         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    191         * @og.rev 3.5.5.9 (2004/06/07) linkCache , redirect 属性を追加
    192         * @og.rev 3.6.0.7 (2004/11/06) target 属性の初期値を _new から _blank に変更
    193         * @og.rev 3.8.8.2 (2007/01/26) href 属性を追加
    194         *
    195         */
    196        @Override
    197        protected void release2() {
    198                super.release2();
    199                direct          = false;
    200                target          = "_blank";             // 3.6.0.7 (2004/11/06)
    201                method          = "GET";
    202                href            = "index.jsp";  // 3.8.8.2 (2007/01/26)
    203                linkCache       = false;                // 3.5.5.9 (2004/06/07)
    204                redirect        = false;                // 3.5.5.9 (2004/06/07)
    205        }
    206
    207        /**
    208         * お気に入りリンクを作成します。
    209         *
    210         * @og.rev 3.8.8.2 (2007/01/26) href 属性を追加
    211         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    212         *
    213         * @return      お気に入りリンクタグ文字列
    214         * @og.rtnNotNull
    215         */
    216        protected String makeTag() {
    217                final HttpServletRequest request = (HttpServletRequest)getRequest();
    218
    219                // ダイレクトリンク時の設定
    220                // リンクの作成
    221                // http://C00000:C00000@hn50g5:8080/dbdef/jsp/index.jsp?GAMENID=xxx&command=NEW&key=val
    222                final StringBuilder link = new StringBuilder( BUFFER_MIDDLE )
    223                        .append( "http://" )
    224                        .append( request.getServerName() ).append( ':' )        // hn50g5:              // 6.0.2.5 (2014/10/31) char を append する。
    225                        .append( request.getServerPort() )                                      // 8823
    226                        .append( request.getContextPath() )                                     // /dbdef
    227                        .append( "/jsp/" );
    228
    229                // 4.0.0 (2005/01/31)
    230                final String direct_jsp  = getGUIInfoAttri( "ADDRESS" ) + "/" + (String)getSessionAttribute( "JSPID" );
    231
    232                final String hrefUrl = link.toString() ;
    233                if( direct ) {
    234                        set( "href" , hrefUrl + direct_jsp );
    235                }
    236                else {
    237                        set( "href" , hrefUrl + href );         // 3.8.8.2 (2007/01/26)
    238                }
    239
    240                set( "target" ,target );
    241                set( "title"  ,getGUIInfoAttri( "LABEL" ) );    // 4.0.0 (2005/01/31)
    242
    243                final String urlEnc = makeUrlEncode( request );
    244
    245                // linkCache による、最終リクエストのアドレスを格納しておきます。
    246                if( linkCache ) {
    247                        // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。key,val は、not null 制限。
    248                        final String uid = getUserInfo( "ID" );
    249                        if( uid != null ) {
    250                                final String val = hrefUrl + direct_jsp + "?" + urlEnc ;
    251                                LAST_QUERY.put( uid,val );
    252                        }
    253                }
    254
    255                return XHTMLTag.link( getAttributes(),urlEnc ) ;
    256        }
    257
    258        /**
    259         * URLエンコードを行ったリンク情報を作成します。
    260         *
    261         * @og.rev 3.1.0.0 (2003/03/20) Vector を使用している箇所で、非同期でも構わない箇所を、ArrayList に置換え。
    262         * @og.rev 3.1.2.0 (2003/04/07) 画面IDと実画面ディレクトリとの関連見直し(DIRの代りにGAMENIDを渡すように変更)
    263         * @og.rev 3.1.8.0 (2003/05/16) 内部で作成している GAMENID 属性をセットしないように変更。
    264         * @og.rev 4.0.0.0 (2007/07/11) submitTag で作成されたボタンパラメータは、次ページへ転送しません。
    265         * @og.rev 5.0.0.2 (2009/09/15) xssチェック対応
    266         *
    267         * @param       request HttpServletRequestオブジェクト
    268         *
    269         * @return      URLエンコードを行ったリンク情報
    270         * @og.rtnNotNull
    271         */
    272        private String makeUrlEncode( final HttpServletRequest request ) {
    273                final Enumeration<?> enume = request.getParameterNames();               // 4.3.3.6 (2008/11/15) Generics警告対応
    274                final ArrayList<String> v_keys = new ArrayList<>();
    275                final ArrayList<String> v_vals = new ArrayList<>();
    276                while( enume.hasMoreElements() ) {
    277                        final String key = String.valueOf( enume.nextElement() );
    278                        if( key != null && key.startsWith( HybsSystem.NO_XFER_KEY ) ) {
    279                                continue;
    280                        }
    281
    282                        // String val = getRequestValue( key );
    283                        final String val = getRequestValue( key, false ); // 5.0.0.2 (2009/09/15)
    284                        if( val != null && val.length() > 0 ) {
    285                                v_keys.add( key );
    286                                v_vals.add( val );
    287                        }
    288                }
    289
    290                final String[] keys = v_keys.toArray( new String[v_keys.size()] );
    291                final String[] vals = v_vals.toArray( new String[v_vals.size()] );
    292
    293                return XHTMLTag.urlEncode( keys,vals );
    294        }
    295
    296        /**
    297         * お気に入りアイコンを取得します。
    298         *
    299         * @og.rev 4.1.1.0 (2008/02/12) 新規追加
    300         * @og.rev 6.2.2.0 (2015/03/27) BRと\nを相互に変換する処理を追加
    301         * @og.rev 6.2.2.3 (2015/04/10) htmlフィルターに、BR→改行処理機能を追加。
    302         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"／＞" 止めを、"＞" に変更します)。
    303         * @og.rev 7.3.2.3 (2021/04/09) ｼｽﾃﾑ定数のJSP_IMGを使用します。(※ SYS.JSP + SYS.IMAGE_DIR)
    304         *
    305         * @return      お気に入りアイコンのリンクを返します。
    306         * @og.rtnNotNull
    307         */
    308        private String getFavoriteIcon() {
    309                final GUIInfo guiInfo           = ( GUIInfo )getSessionAttribute( HybsSystem.GUIINFO_KEY );
    310                final String mscVal             = getRequestValue( "MSC" );
    311                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    312
    313                if( guiInfo.isRead() && mscVal.length() != 0 ) {
    314                        final String gamenId            = guiInfo.getKey();
    315                        final UserInfo userInfo = getUser();
    316                        final Map<String,FavoriteGUIData> favoriteMap = userInfo.getFavoriteMap();
    317
    318                        // 6.3.9.0 (2015/11/06) Use one line for each declaration, it enhances code readability.(PMD)
    319                        final String fgEdit;
    320                        final String image;
    321                        final String updateLabel;
    322                        if( favoriteMap.containsKey( gamenId ) ){
    323                                fgEdit = "0";
    324                                image  = "FAV_MENU_OUT.gif";
    325                                updateLabel  = getLabel( "DELETE" );
    326                        }
    327                        else {
    328                                fgEdit = "1";
    329                                image  = "FAV_MENU_IN.gif";
    330                                updateLabel  = getLabel( "INSERT" );
    331                        }
    332
    333                        final String geContextName = HybsSystem.sys( "GE_CONTEXT_NAME" );
    334                        if( geContextName.isEmpty() ) {
    335                                final String errMsg = "システムパラメータ GE_CONTEXT_NAME が設定されていません。";
    336                                throw new HybsSystemException( errMsg );
    337                        }
    338
    339                        buf.append( "<a href=\"/").append( geContextName )
    340                                .append("/jsp/GE0014/update.jsp?fgEdit=" ).append( fgEdit )
    341                                .append( "&command=NEW&SYSTEM_ID="      ).append( userInfo.getParameter( "SYSTEM_ID" ) )
    342                                .append( "&GUIKEY="                     ).append( gamenId )
    343                                .append( "&CONTEXT_URL="        ).append( userInfo.getParameter( "CONTEXT_URL" ) )
    344                                // 7.3.2.3 (2021/04/09) ｼｽﾃﾑ定数のJSP_IMGを使用します。(※ SYS.JSP + SYS.IMAGE_DIR)
    345//                              .append( "\"><img src=\""       ).append( userInfo.getParameter( "JSP" ) )
    346//                              .append( "/image/"                      ).append( image )
    347                                .append( "\"><img src=\""       ).append( JSP_IMG ).append( image )
    348                                .append( "\" title=\""          ).append( StringUtil.htmlFilter( getLabel( "FAVORITE_MENU" ),true ) )   // 6.2.2.0 (2015/03/27)
    349                                .append( ' '                            ).append( updateLabel )
    350//                              .append( "\" /></a>"            );
    351                                .append( "\" ></a>"                     );                                              // 7.0.1.0 (2018/10/15)
    352                }
    353
    354                return buf.toString();
    355        }
    356
    357        /**
    358         * 【TAG】直接アクセスできる形式のリンクを作成するかどうか[true/false]を指定します(初期値:false)。
    359         *
    360         * @og.tag
    361         * trueは、指定の画面のフレームレベルでの指定になります。false は、トップフレームを
    362         * 含む形なので、通常の登録画面と同じ形式になります。
    363         * 初期値は、false(直接リンクしない)です。
    364         *
    365         * @param       flag 作成可否 [true:する/false:しない]
    366         */
    367        public void setDirect( final String flag ) {
    368                direct = nval( getRequestParameter( flag ),direct );
    369        }
    370
    371        /**
    372         * 【TAG】リンク先の文書を表示させるフレーム、またはウィンドウの名前を指定します(初期値:_blank)。
    373         *
    374         * @og.tag リンク先のフレーム名(ターゲット属性)を設定します。
    375         *
    376         * @param       name リンク先の文書のフレーム名(ターゲット属性)
    377         */
    378        public void setTarget( final String name ) {
    379                target = nval( getRequestParameter( name ),target );
    380        }
    381
    382        /**
    383         * 【TAG】リンクを作成する時の転送先アドレスを指定します(初期値:index.jsp)。
    384         *
    385         * @og.tag
    386         * direct="false"(初期値)に使用されるリンクの転送先アドレスを指定します。
    387         * 初期値は、index.jspです。
    388         *
    389         * @param       url 転送先アドレス
    390         */
    391        public void setHref( final String url ) {
    392                href = nval( getRequestParameter( url ),href );
    393        }
    394
    395        /**
    396         * 【TAG】リンクの作成元となるメソッド[POST/GET/ALL]を指定します(初期値:GET)。
    397         *
    398         * @og.tag
    399         * ここで指定したメソッドでリクエストされた場合のみ、リンクを作成します。
    400         * 初期値は、GET です。(つまり GET のみリンクを作成します。)
    401         * これは、POST では、引数が付かない為です。(実際は付ける事ができますが・・・)
    402         * ALL は、どちらの場合でもリンクを作成しますが、先に述べたように POST では
    403         * 引数がつきません。
    404         * 初期値は、GETです。
    405         *
    406         * @param       flag リンクの作成元となるメソッド [POST/GET/ALL]
    407         */
    408        public void setMethod( final String flag ) {
    409                method = nval( getRequestParameter( flag ),method );
    410        }
    411
    412        /**
    413         * 【TAG】リンクをキャッシュするかどうか[true/false]を指定します(初期値:false)。
    414         *
    415         * @og.tag
    416         * この、favoriteLink で指定された画面を、ユーザー毎にキャッシュします。
    417         * キャッシュされた画面は、lastQuery を指定することで、取り出し(転送)
    418         * することが出来ます。
    419         * ここでのキャッシュは、direct="true" を指定した場合のアドレスです。
    420         * direct="false" は、index.jsp からのフレーム形式の為、メール等で
    421         * 送り、後ほど再開するような使い方(または、ワークフロー的な使い方)
    422         * を想定していますが、direct="true" により単独フレームデータを、
    423         * リアルタイムで使用するケース(EXCELのWebクエリーなど)で使用します。
    424         * 初期値は、falseです。
    425         *
    426         * @og.rev 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示します。
    427         *
    428         * @param       flag リンクキャッシュ [true:する/false:しない]
    429         */
    430        public void setLinkCache( final String flag ) {
    431                linkCache = nval( getRequestParameter( flag ),linkCache );
    432        }
    433
    434        /**
    435         * 【TAG】キャッシュされたリンク先に転送するかどうか[true/false]を指定します(初期値:false)。
    436         *
    437         * @og.tag
    438         * この、favoriteLink で指定された画面を、キャッシュします。
    439         * キャッシュされた画面は、lastQuery を指定することで、取り出し(転送)
    440         * することが出来ます。
    441         * ここでのキャッシュは、direct="true" を指定した場合のアドレスです。
    442         * direct="false" は、index.jsp からのフレーム形式の為、メール等で
    443         * 送り、後ほど再開するような使い方(または、ワークフロー的な使い方)
    444         * を想定していますが、direct="true" により単独フレームデータを、
    445         * リアルタイムで使用するケース(EXCELのWebクエリーなど)で使用します。
    446         * 初期値は、falseです。
    447         *
    448         * @og.rev 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示します。
    449         *
    450         * @param       flag リンク先転送 [true:する/false:しない]
    451         */
    452        public void setLastQueryRedirect( final String flag ) {
    453                redirect = nval( getRequestParameter( flag ),redirect );
    454        }
    455
    456        /**
    457         * 【TAG】お気に入りアイコンリンクを作成するかどうか[true/false]を指定します(初期値:false)。
    458         *
    459         * @og.tag
    460         * 初期値は、falseです。
    461         *
    462         * @og.rev 4.1.1.0 (2008/02/13) 新規追加。
    463         *
    464         * @param       flag お気に入りアイコンリンク作成 [true:する/false:しない]
    465         */
    466        public void setUseIcon( final String flag ) {
    467                useIcon = nval( getRequestParameter( flag ),useIcon );
    468        }
    469
    470        /**
    471         * リンクキャッシュをクリアします。
    472         * この時、poolされているオブジェクトは、ResourceManager#clear() メソッドを
    473         * 呼び出します。
    474         *
    475         * @og.rev 3.5.5.9 (2004/06/07) 新規作成
    476         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    477         */
    478        public static void clear() {
    479                        LAST_QUERY.clear();
    480        }
    481
    482        /**
    483         * このオブジェクトの文字列表現を返します。
    484         * 基本的にデバッグ目的に使用します。
    485         *
    486         * @return このクラスの文字列表現
    487         * @og.rtnNotNull
    488         */
    489        @Override
    490        public String toString() {
    491                return ToString.title( this.getClass().getName() )
    492                                .println( "VERSION"             ,VERSION        )
    493                                .println( "direct"              ,direct         )
    494                                .println( "target"              ,target         )
    495                                .println( "method"              ,method         )
    496                                .println( "linkCache"   ,linkCache      )
    497                                .println( "redirect"    ,redirect       )
    498                                .println( "Other..."    ,getAttributes().getAttribute() )
    499                                .fixForm().toString() ;
    500        }
    501}