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.fukurou.util;
017
018import org.opengion.fukurou.security.HybsCryptography;
019
020/**
021 * XHTMLTag.java は、共通的に使用されるHTMLタグの生成メソッドを集約したクラスです。
022 *
023 * 全変数/メソッドは、public static final 宣言されています。
024 *
025 * @version  4.0
026 * @author   Kazuhiko Hasegawa
027 * @since    JDK5.0,
028 */
029public final class XHTMLTag {
030
031        /** システム依存の改行記号をセットします。 */
032        public static final String CR = System.getProperty("line.separator");
033
034        /** バッファの初期容量を通常より若干多い目に設定します。(50)  */
035        public static final int BUFFER_SMALL = 50;
036
037        /** バッファの初期容量を通常より多い目に設定します。(200)  */
038        public static final int BUFFER_MIDDLE = 200;
039
040        /** バッファの初期容量を通常より大幅に多い目に設定します。(500)  */
041        public static final int BUFFER_LARGE  = 500;
042
043        /** URLチェックキー発行用 4.3.7.1 (2009/06/08) */
044        private static final HybsCryptography HYBS_CRYPTOGRAPHY = new HybsCryptography(); // 4.3.7.0 (2009/06/01)
045
046        /**
047         * BUTTON タグの属性リストです。
048         *
049         * @og.rev 5.7.1.0 (2013/12/06) HTML5関連の属性を追加
050         */
051        private static final String[]
052                BUTTON_KEY =  { "type","name","value","onClick"
053                                                ,"id","class","lang","dir","title","style","xml:lang"
054                                                ,"disabled","tabindex","accesskey"
055                                                ,"onBlur","onFocus","ondblClick","onMouseDown","onMouseUp"
056                                                ,"onMouseMove","onMouseOut","onMouseOver"
057                                                // 5.7.1.0 (2013/12/06) HTML5関連の属性
058                                                ,"autofocus"
059                                        };
060
061        /**
062         * INPUT タグの属性リストです。
063         *
064         * @og.rev 5.7.1.0 (2013/12/06) HTML5関連の属性を追加
065         */
066        private static final String[]
067                INPUT_KEY = { "type","size","maxlength","checked","src"
068                                                ,"alt","accept","usemap","ismap"
069                                                ,"id","class","lang","dir","title","style","xml:lang"
070                                                ,"readonly","disabled","tabindex","accesskey","onClick","onChange"
071                                                ,"onBlur","onFocus","ondblClick","onMouseDown","onMouseUp"
072                                                ,"onMouseMove","onMouseOut","onMouseOver"
073                                                ,"onSelect","onKeydown","onKeypress","onKeyup"
074                                                // 5.7.1.0 (2013/12/06) HTML5関連の属性
075                                                ,"autocomplete","autofocus","pattern","placeholder","list","min","max","step","required"
076                                        };
077
078        /**
079         * TEXTAREA タグの属性リストです。
080         *
081         * @og.rev 5.7.1.0 (2013/12/06) HTML5関連の属性を追加
082         */
083        private static final String[]
084                TEXTAREA_KEY = { "name","rows","cols"
085                                                ,"id","class","lang","dir","title","style","xml:lang"
086                                                ,"readonly","disabled","tabindex","accesskey","onClick"
087                                                ,"onBlur","onFocus","ondblClick","onMouseDown","onMouseUp"
088                                                ,"onMouseMove","onMouseOut","onMouseOver"
089                                                ,"onSelect","onKeydown","onKeypress","onKeyup"
090                                                // 5.7.1.0 (2013/12/06) HTML5関連の属性
091                                                ,"autofocus","placeholder"
092                                        };
093
094        /**
095         * LINK タグの属性リストです。
096         *
097         */
098        private static final String[]
099                LINK_KEY = { "type","name","hreflang","rel","rev","charset"
100                                                ,"target","shape","coords","onClick"
101                                                ,"id","class","lang","dir","title","style","xml:lang"
102                                                ,"tabindex","accesskey"
103                                                ,"onBlur","onFocus","ondblClick","onMouseDown","onMouseUp"
104                                                ,"onMouseMove","onMouseOut","onMouseOver"
105                                        };
106
107        /**
108         * SELECT タグの属性リストです。
109         *
110         * @og.rev 5.7.1.0 (2013/12/06) HTML5関連の属性を追加
111         */
112        private static final String[]
113                SELECT_KEY = { "size","multiple",
114                                                "id","class","lang","dir","title","style","xml:lang"
115                                                ,"disabled","tabindex","onClick","onChange"
116                                                ,"onBlur","onFocus","ondblClick","onMouseDown","onMouseUp"
117                                                ,"onMouseMove","onMouseOut","onMouseOver"
118                                                ,"onSelect","onKeydown","onKeypress","onKeyup"
119                                                // 5.7.1.0 (2013/12/06) HTML5関連の属性
120                                                ,"autofocus"
121                                        };
122
123        /**
124         * OPTION タグの属性リストです。
125         *
126         */
127        private static final String[]
128                OPTION_KEY = { "value","label","selected"
129                                                ,"id","class","lang","dir","title","style","xml:lang"
130                                                ,"disabled"
131                                        };
132
133        /**
134         * FRAME タグの属性リストです。
135         *
136         */
137        private static final String[]
138                FRAME_KEY = { "name","longdesc","marginwidth","marginheight","noresize"
139                                                ,"scrolling","frameborder"
140                                                ,"id","class","title","style"
141                                        };
142
143        /**
144         * IMAGE タグの属性リストです。
145         *
146         */
147        private static final String[]
148                IMAGE_KEY = { "src","alt","longdesc","width","height","usemap","ismap","name","onClick"
149                                                ,"align","border","hspace","vspace"              // この行は非推奨属性です。
150                                                ,"id","class","title","style","lang","dir","xml:lang"
151                                                ,"onBlur","onFocus","ondblClick","onMouseDown","onMouseUp"
152                                                ,"onMouseMove","onMouseOut","onMouseOver"
153                                        };
154
155        /**
156         * FORM タグの属性リストです。
157         *
158         */
159        private static final String[]
160                FORM_KEY = { "action","method","enctype","accept-charset","accept","name","target"
161                                                ,"id","class","title","style","lang","dir","xml:lang"
162                                        };
163
164        /**
165         * SPAN タグの属性リストです。
166         *
167         */
168        private static final String[]
169                SPAN_KEY = { "id","class","title","style","lang","dir","xml:lang" };
170
171        /**
172         * PRE タグの属性リストです。
173         *
174         */
175        private static final String[]
176                PRE_KEY = { "id","class","title","style","lang","dir","xml:lang" };
177
178        /**
179         *  デフォルトコンストラクターをprivateにして、
180         *  オブジェクトの生成をさせないようにする。
181         *
182         */
183        private XHTMLTag() { }
184
185        /**
186         * ボタンを作成します。
187         *
188         * <button type="形式" name="名前" value="送信文字" オプション・・・ >ラベル</button>
189         *
190         * <table border="1" frame="box" rules="all" >
191         *   <caption>Attributes に設定できる属性</caption>
192         *   <tr><td>name="名前"</td><td>オプション</td><td>LabelResource.properties のキー</td></tr>
193         *   <tr><td>type="形式"</td><td>必須</td><td>submit/reset/button</td></tr>
194         *   <tr><td>value="値"</td><td>オプション</td><td>name属性と共に送信される値</td></tr>
195         *   <tr><td>disabled="disabled"</td><td>オプション</td><td>ボタンを利用できない状態にする場合に指定</td></tr>
196         *   <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0〜32767の範囲で数字で指定(小さい順に移動)</td></tr>
197         *   <tr><td>accesskey="ショートカットキー"</td><td>オプション</td><td>文字セット中の1文字:WindowsであればAltキーと同時使用</td></tr>
198         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
199         *   <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>画像や文字などボタン上に表示させたいタグの文字列</td></tr>
200         * </table>
201         *
202         * 設定できる属性
203         * 形式は,
204         *  submit  送信(サブミット)
205         *  reset   リセット
206         *  button  汎用ボタン
207         * を指定します。
208         *
209         * ラベルに,HTMLテキスト(強調文字など)をはめ込むことが出来ます。
210         * また,イメージ &lt;img ・・・・&gt; を指定することも,可能です。
211         * disabled="disabled" のとき,このボタンのデータはサーバーに送信されません。
212         * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの
213         * 汎用属性を自由に登録する事が出来ます。
214         *
215         * @param   attri 属性群
216         *
217         * @return  ボタンタグ文字列
218         */
219        public static String button( final Attributes attri ) {
220                String   checkedType = "|submit|reset|button|";
221
222                String type  = attri.get( "type" );
223                if( checkedType.indexOf( "|" + type + "|" ) < 0 ) {
224                        String errMsg = "button タイプ設定エラー [" + type + "]";
225                        throw new RuntimeException( errMsg );
226                }
227
228                String values = attri.getAttribute( BUTTON_KEY );
229                String body   = attri.get( "body" );
230                if( body == null ) { body = "" ; }
231
232                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
233                rtn.append("<button ");
234                rtn.append( values );
235                rtn.append( ">" );
236                rtn.append( body );
237                rtn.append("</button>");
238
239                return rtn.toString();
240        }
241
242        /**
243         * 入力フォームを作成します。
244         *
245         * @param   attri 属性群
246         *
247         * @return  入力フォームタグ文字列
248         * @see     #input( Attributes attri,String name,String value,String optAtt )
249         */
250        public static String input( final Attributes attri ) {
251                String name     = attri.get( "name" );
252                String value    = attri.get( "value" );
253                String optAttri = attri.get( "optionAttributes" );
254
255                return input( attri,name,value,optAttri );
256        }
257
258        /**
259         * 入力フォームを作成します。
260         *
261         * &lt;input type="text" name="名前" value="送信文字" ....&gt;
262         *
263         * <table border="1" frame="box" rules="all" >
264         *   <caption>Attributes に設定できる属性</caption>
265         *   <tr><td>name="名前"</td><td>オプション</td><td>LabelResource.properties のキー</td></tr>
266         *   <tr><td>type="形式"</td><td>必須</td><td>text/password/checkbox/radio/submit/reset/button/image/file/hidden</td></tr>
267         *   <tr><td>value="値"</td><td>オプション</td><td>name属性と共に送信される値</td></tr>
268         *   <tr><td>size="30"</td><td>オプション</td><td>inputタグの大きさ</td></tr>
269         *   <tr><td>maxlength="50"</td><td>オプション</td><td>type属性が「text」,「password」 のときの最大文字数</td></tr>
270         *   <tr><td>checked="checked"</td><td>オプション</td><td>type属性が「checkbox」,「radio」 の場合に選択されている状態にする。</td></tr>
271         *   <tr><td>disabled="disabled"</td><td>オプション</td><td>選択や変更の操作をできない状態にする場合に指定</td></tr>
272         *   <tr><td>accept="MIMEタイプ"</td><td>オプション</td><td>type属性が「file」の場合に処理可能なMIMEタイプを指定</td></tr>
273         *   <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0〜32767の範囲で数字で指定(小さい順に移動)</td></tr>
274         *   <tr><td>accesskey="ショートカットキー"</td><td>オプション</td><td>文字セット中の1文字:WindowsであればAltキーと同時使用</td></tr>
275         *   <tr><td>src="URL"</td><td>オプション</td><td>type属性が「image」の場合送信ボタンの画像URLを指定</td></tr>
276         *   <tr><td>alt="代替文字列"</td><td>オプション</td><td>type属性が「image」の場合、画像が表示できないときの代替文字列を指定</td></tr>
277         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
278         *   <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>画像や文字などボタン上に表示させたいタグの文字列</td></tr>
279         *   <tr><td>サポート外</td><td>未実装</td><td>readonly属性、usemap属性、ismap属性、align属性</td></tr>
280         * </table>
281         *
282         * 設定できる属性
283         * 形式は,
284         *  text       1行のテキストフィールド
285         *  password   パスワード用テキストフィールド
286         *  checkbox   チェックボックス(複数選択可)
287         *  radio      ラジオボタン(複数選択不可)
288         *  submit     送信(サブミット)
289         *  reset      リセット
290         *  button     汎用ボタン
291         *  image      イメージによる画像ボタン
292         *  file       送信ファイルの選択
293         *  hidden     表示せずにサーバーに送信する。
294         * を指定します。
295         *
296         * ラジオボタン/チェックボックスであらかじめ,チェックをして
297         * おきたい場合は,checked 属性に "checked" を登録します。
298         * ファイルダイアログの場合は,attributesの accept 属性に "MIMEタイプ"
299         * を登録します。
300         * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの
301         * 文字を自由に登録する事が出来ます。
302         * CSSでクラスを対応 class="XXXX"
303         * タブで移動順を指定する tabindex="タブ順"
304         * ショートカットキーを割り当てる accesskey="ショートカットキー"
305         *
306         * @param   attri  属性群
307         * @param   name   名前
308         * @param   value  値
309         * @param   optAttri オプション文字列(タグ属性定義されていない属性の登録用文字列)
310         *
311         * @return  入力フォームタグ文字列
312         */
313        public static String input( final Attributes attri,final String name,final String value,final String optAttri ) {
314                String values = attri.getAttribute( INPUT_KEY );
315
316                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
317                rtn.append("<input ");
318                if( name  != null ) { rtn.append("name=\"").append( name ).append( "\" " ); }
319                if( value != null ) { rtn.append("value=\"").append( value ).append( "\" " ); }
320                rtn.append( values );
321                if( optAttri != null ) {
322                        rtn.append( " " );
323                        rtn.append( optAttri );
324                }
325                rtn.append( " />" );
326
327                return rtn.toString();
328        }
329
330        /**
331         * 入力フォームの属性情報のみの文字列を作成します。
332         * これは、name 属性や value 属性など、一般に都度変更されるフィールド
333         * 以外の固定的な属性情報を、先に作成しておく場合に、使用します。
334         *
335         * @param   attri       属性リスト
336         *
337         * @return  入力フォームタグの属性情報文字列
338         */
339        public static String inputAttri( final Attributes attri ) {
340                return attri.getAttribute( INPUT_KEY );
341        }
342
343        /**
344         * テキストエリアの属性情報のみの文字列を作成します。
345         * これは、name 属性や value 属性など、一般に都度変更されるフィールド
346         * 以外の固定的な属性情報を、先に作成しておく場合に、使用します。
347         *
348         * @param   attri       属性リスト
349         *
350         * @return  テキストエリアの属性情報文字列
351         */
352        public static String textareaAttri( final Attributes attri ) {
353                return attri.getAttribute( TEXTAREA_KEY );
354        }
355
356        /**
357         * プルダウン等のメニューの属性情報のみの文字列を作成します。
358         * これは、name 属性や value 属性など、一般に都度変更されるフィールド
359         * 以外の固定的な属性情報を、先に作成しておく場合に、使用します。
360         *
361         * @param   attri       属性リスト
362         *
363         * @return  プルダウン等のメニューの属性情報文字列
364         */
365        public static String selectAttri( final Attributes attri ) {
366                return attri.getAttribute( SELECT_KEY );
367        }
368
369        /**
370         * HIDDEN フォームを作成します。
371         *
372         * id属性に、name と同じ値が設定されます。
373         *
374         * @og.rev 5.5.4.0 (2012/07/02) ID属性追加
375         *
376         * @param   name  フォームの名前
377         * @param   value 値
378         *
379         * @return  HIDDENフォームタグ文字列
380         */
381        public static String hidden( final String name,final String value ) {
382//              StringBuilder rtn = new StringBuilder( BUFFER_SMALL );
383
384//              rtn.append("<input type=\"hidden\" ");
385//              rtn.append("name=\"" ).append( name );
386//              rtn.append("\" value=\"").append( value );
387//              rtn.append( "\" />" );
388
389//              return rtn.toString();
390                return hidden(name,value,name);
391        }
392
393        /**
394         * HIDDEN フォームを作成します。
395         *
396         * @og.rev 5.5.4.0 (2012/07/02) ID属性追加
397         *
398         * @param   name  フォームの名前
399         * @param   value 値
400         * @param   id    フォームのID
401         *
402         * @return  HIDDENフォームタグ文字列
403         */
404        public static String hidden( final String name, final String value, final String id ) {
405                StringBuilder rtn = new StringBuilder( BUFFER_SMALL );
406
407                rtn.append( "<input type=\"hidden\" " );
408                rtn.append( "name=\"" ).append( name );
409                rtn.append( "\" value=\"" ).append( value );
410                rtn.append( "\" id=\"" ).append( id );
411                rtn.append( "\" />" );
412
413                return rtn.toString();
414        }
415
416        /**
417         * テキストエリアを作成します。
418         *
419         * &lt;textarea name="名前" rows="4" cols="40"  ....&gt;送信文字列 &lt;/textarea&gt;
420         *
421         * <table border="1" frame="box" rules="all" >
422         *   <caption>Attributes に設定できる属性</caption>
423         *   <tr><td>name="名前"</td><td>オプション</td><td>LabelResource.properties のキー</td></tr>
424         *   <tr><td>rows="行数"</td><td>オプション</td><td>入力フィールドの表示行数</td></tr>
425         *   <tr><td>cols="幅"</td><td>オプション</td><td>入力フィールドの表示幅(文字数)</td></tr>
426         *   <tr><td>disabled="disabled"</td><td>オプション</td><td>選択や変更の操作をできない状態にする場合に指定</td></tr>
427         *   <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0〜32767の範囲で数字で指定(小さい順に移動)</td></tr>
428         *   <tr><td>accesskey="ショートカットキー"</td><td>オプション</td><td>文字セット中の1文字:WindowsであればAltキーと同時使用</td></tr>
429         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
430         *   <tr><td>value="値"</td><td>オリジナル</td><td>name属性と共に送信される値</td></tr>
431         *   <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>画像や文字などボタン上に表示させたいタグの文字列</td></tr>
432         *   <tr><td>サポート外</td><td>未実装</td><td>readonly属性</td></tr>
433         * </table>
434         *
435         * 設定できる属性
436         *
437         * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの
438         * 文字を自由に登録する事が出来ます。
439         * CSSでクラスを対応 class="XXXX"
440         * タブで移動順を指定する tabindex="タブ順"
441         * ショートカットキーを割り当てる accesskey="ショートカットキー"
442         *
443         * @param   attri 属性群
444         *
445         * @return  入力フォームタグ文字列
446         */
447        public static String textarea( final Attributes attri ) {
448                String values = attri.getAttribute( TEXTAREA_KEY );
449                String body   = attri.get( "body" );
450                if( body == null ) { body = "" ; }
451
452                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
453                rtn.append("<textarea ");
454                rtn.append( values );
455                rtn.append( ">" );
456                rtn.append( body );
457                rtn.append( "</textarea>" );
458
459                return rtn.toString();
460        }
461
462        /**
463         * ページリンクを作成します。
464         *
465         * &lt;A href="URL" target="ターゲット名"&gt;ラベル&lt;/A&gt;
466         *
467         * <table border="1" frame="box" rules="all" >
468         *   <caption>Attributes に設定できる属性</caption>
469         *   <tr><td>href="URL"</td><td>必須</td><td>リンク先のURLを指定します。</td></tr>
470         *   <tr><td>charset="文字セット"</td><td>オプション</td><td>リンク先の文字コードセットを指定します。</td></tr>
471         *   <tr><td>hreflang="言語セット"</td><td>オプション</td><td>リンク先の基本となる言語コードを指定します。</td></tr>
472         *   <tr><td>type="MIMEタイプ"</td><td>オプション</td><td>リンク先のMIMEタイプを指定します。</td></tr>
473         *   <tr><td>name="名前"</td><td>オプション</td><td>この要素をリンクの到達点とするための名前を指定します。</td></tr>
474         *   <tr><td>rel="リンクタイプ"</td><td>オプション</td><td>この文書からみた href 属性で指定されるリンク先との関係</td></tr>
475         *   <tr><td>rev="リンクタイプ"</td><td>オプション</td><td>href 属性で指定されるリンク先からみた、この文書との関係</td></tr>
476         *   <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0〜32767の範囲で数字で指定(小さい順に移動)</td></tr>
477         *   <tr><td>accesskey="ショートカットキー"</td><td>オプション</td><td>文字セット中の1文字:WindowsであればAltキーと同時使用</td></tr>
478         *   <tr><td>target="フレーム名"</td><td>オプション</td><td>リンク先のフレーム名</td></tr>
479         *   <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>画像や文字などをリンクにできます。</td></tr>
480         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
481         *   <tr><td>サポート外</td><td>未実装</td><td>shape属性、coords属性</td></tr>
482         * </table>
483         *
484         * 設定できる属性
485         *
486         * ラベルなしの場合, href属性の "URL" そのものを付けます。
487         *
488         * target属性のフレーム名は
489         *
490         *  _top        フレームを解除して,リンク先をフレーム全体に表示する。
491         *  _parent リンク先を親フレームに表示する。
492         *  _self   リンク先を自分自身に表示する。
493         *  _blank  新しいウインドウを開いて,表示する。
494         *  その他  フレーム作成時の名前で指定可能。
495         *
496         * を指定します。
497         * なしの場合 _self (自分自身)を指定します。
498         *
499         * リンクメール機能
500         * URLを,mailto:メールアドレス で設定すれば,メール送信ダイアログを
501         * 開く事が出来ます。
502         * 画像リンク機能
503         * 画像をクリックするリンクは,ラベルの個所に &lt;img&gt;タグを設定します。
504         *
505         * &lt;a href="books.html"&gt;&lt;img src="banner.gif" width="468px" height="60px" alt="関連書籍紹介" border="0"&gt;&lt;/a&gt;
506         *
507         * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの
508         * 文字を自由に登録する事が出来ます。
509         * CSSでクラスを対応 class="XXXX"
510         * タブで移動順を指定する tabindex="タブ順"
511         * ショートカットキーを割り当てる accesskey="ショートカットキー"
512         *
513         * @param   attri 属性群
514         *
515         * @return  ページリンクタグ文字列
516         */
517        public static String link( final Attributes attri ) {
518                return link( attri,"" );
519        }
520
521        /**
522         * ページリンクを作成します。
523         *
524         * @param   attri 属性群
525         * @param   urlEncode 文字列   ( ?key1=val1&amp;・・・・ という文字列 無いときは "" )
526         *
527         * @return  ページリンクタグ文字列
528         */
529        public static String link( final Attributes attri, final String urlEncode ) {
530
531                String href = addUrlEncode( attri.get( "href" ),urlEncode );
532
533                String values = attri.getAttribute( LINK_KEY );
534                String body   = attri.get( "body" );
535                if( body == null ) { body = attri.get( "href" ) ; }
536
537                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
538                rtn.append("<a href=\"");
539                rtn.append( href );
540                rtn.append( "\" " );
541                rtn.append( values );
542                rtn.append( ">" );
543                rtn.append( body );
544                rtn.append( "</a>" );
545
546                return rtn.toString();
547        }
548
549        /**
550         * xlink 形式のページリンクを作成します。
551         *
552         * 基本的には、link と同じです。アドレスの指定も、href で指定してください。
553         * 内部的に、xlink:href に変換します。
554         * また、URL引数を、"&amp;" で結合するのではなく、"&amp;amp;" で結合させます。
555         * これは、xlink そのものが、XML上に記述された場合に、XMLのルールで再度パース
556         * される為です。
557         *
558         * @param   attri 属性群
559         * @param   urlEncode 文字列   ( ?key1=val1&amp;・・・・ という文字列 無いときは "" )
560         *
561         * @return  ページリンクタグ文字列
562         */
563        public static String xlink( final Attributes attri, final String urlEncode ) {
564
565                String href = addUrlEncode( attri.get( "href" ),urlEncode,"&amp;" );
566
567                String values = attri.getAttribute( LINK_KEY );
568                String body   = attri.get( "body" );
569                if( body == null ) { body = attri.get( "href" ) ; }
570
571                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
572                rtn.append("<a xlink:href=\"");
573                rtn.append( href );
574                rtn.append( "\" " );
575                rtn.append( values );
576                rtn.append( ">" );
577                rtn.append( body );
578                rtn.append( "</a>" );
579
580                return rtn.toString();
581        }
582
583        /**
584         * メニューを作成します。
585         *
586         * @param   attri 属性群
587         * @param   opt 選択肢(オプション)
588         *
589         * @return  メニュータグ文字列
590         */
591        public static String select( final Attributes attri,final Options opt ) {
592                String name     = attri.get( "name" );
593                String optAttri = attri.get( "optionAttributes" );
594
595                return select( attri,opt,name,optAttri );
596        }
597
598        /**
599         * メニューを作成します。
600         *
601         * &lt;select size="行数" name="名前" multiple&gt;
602         *   &lt;option value="送信文字1"&gt;コメント&lt;/option&gt;
603         *   &lt;option value="送信文字2"&gt;コメント&lt;/option&gt;
604         *   &lt;option value="送信文字3" selected="selected"&gt;コメント&lt;/option&gt;
605         * &lt;/select&gt;
606         *
607         * <table border="1" frame="box" rules="all" >
608         *   <caption>Attributes に設定できる属性</caption>
609         *   <tr><td>name="名前"</td><td>オプション</td><td>LabelResource.properties のキー</td></tr>
610         *   <tr><td>size="行数"</td><td>オプション</td><td>select要素をリストボックスとして表示する場合の行数</td></tr>
611         *   <tr><td>multiple="multiple"</td><td>オプション</td><td>選択肢の中から複数選択出来るようにする。</td></tr>
612         *   <tr><td>disabled="disabled"</td><td>オプション</td><td>選択や変更の操作をできない状態にする場合に指定</td></tr>
613         *   <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0〜32767の範囲で数字で指定(小さい順に移動)</td></tr>
614         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
615         * </table>
616         *
617         * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの
618         * 文字を自由に登録する事が出来ます。
619         * CSSでクラスを対応 class="XXXX"
620         *
621         * @param   attri       属性群
622         * @param   opt         選択肢(オプション)
623         * @param   name        名前
624         * @param   optAttri オプション属性
625         *
626         * @return  メニュータグ文字列
627         */
628        public static String select( final Attributes attri,final Options opt,final String name,final String optAttri ) {
629                String values  = attri.getAttribute( SELECT_KEY );
630                String options = opt.getOption();
631
632                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
633                rtn.append("<select ");
634                if( name  != null ) { rtn.append("name=\"").append( name ).append( "\" " ); }
635                rtn.append( values );
636                if( optAttri != null ) {
637                        rtn.append( " " );
638                        rtn.append( optAttri );
639                }
640                rtn.append( ">" );
641                rtn.append( options );
642                rtn.append( "</select>" );
643
644                return rtn.toString();
645        }
646
647        /**
648         * オプションを作成します。
649         *
650         * &lt;select size="行数" name="名前" multiple&gt;
651         *   &lt;option value="送信文字1"&gt;コメント&lt;/option&gt;
652         *   &lt;option value="送信文字2"&gt;コメント&lt;/option&gt;
653         *   &lt;option value="送信文字3" selected="selected"&gt;コメント&lt;/option&gt;
654         * &lt;/select&gt;
655         *
656         * <table border="1" frame="box" rules="all" >
657         *   <caption>Attributes に設定できる属性</caption>
658         *   <tr><td>value="値"</td><td>オプション</td><td>送信する値</td></tr>
659         *   <tr><td>selected="selected"</td><td>オプション</td><td>選択肢をあらかじめ選択された状態にしておく</td></tr>
660         *   <tr><td>disabled="disabled"</td><td>オプション</td><td>選択や変更の操作をできない状態にする場合に指定</td></tr>
661         *   <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>選択肢に表示させたいタグの文字列</td></tr>
662         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
663         * </table>
664         *
665         * セレクタとは,リストボックスやメニューなどの option引数にセットする
666         * 複数のデータをoptionタグでくるんだものです。
667         *
668         * @param   attri 属性群
669         *
670         * @return  オプションタグ文字列
671         */
672        public static String option( final Attributes attri ) {
673                String values  = attri.getAttribute( OPTION_KEY );
674                String body     = attri.get( "body" );
675                if( body == null ) { body = "No Label" ; }
676
677                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
678                rtn.append("<option ");
679                rtn.append( values );
680                rtn.append( " >" );
681                rtn.append( body );
682                rtn.append( "</option>" );
683
684                return rtn.toString();
685        }
686
687        /**
688         * フレームタグを作成します。
689         *
690         * &lt;frame marginheight="2px" marginwidth="2px" src="query.jsp" name="QUERY" /&gt;
691         *
692         * <table border="1" frame="box" rules="all" >
693         *   <caption>Attributes に設定できる属性</caption>
694         *   <tr><td>src="URL"</td><td>オプション</td><td>フレームの表示先URLを指定します。</td></tr>
695         *   <tr><td>name="フレーム名"</td><td>オプション</td><td>フレームに付ける名前を指定します。</td></tr>
696         *   <tr><td>longdesc="URI"</td><td>オプション</td><td>フレームの詳しい説明のURI</td></tr>
697         *   <tr><td>marginwidth="左右のマージン"</td><td>オプション</td><td>フレーム内の左右のマージンを指定します。</td></tr>
698         *   <tr><td>marginheight="上下のマージン"</td><td>オプション</td><td>フレーム内の上下のマージンを指定します。</td></tr>
699         *   <tr><td>noresize="noresize"</td><td>オプション</td><td>フレームサイズを変更できないようにします。</td></tr>
700         *   <tr><td>scrolling="スクロールの制御"</td><td>オプション</td><td>yes:スクロールバーを表示 no:表示しない auto:必要に応じて表示(デフォルト)</td></tr>
701         *   <tr><td>frameborder="枠の表示"</td><td>オプション</td><td>0:枠を表示しない  1:枠を表示する。(デフォルト)</td></tr>
702         *   <tr><td>keys="引数にセットするキー"</td><td>オプション</td><td>URI の引数にセットするキーを CSV 形式でセットします。</td></tr>
703         *   <tr><td>value="引数にセットする値"</td><td>オプション</td><td>URI の引数にセットする値を CSV 形式でセットします。</td></tr>
704         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style</td></tr>
705         * </table>
706         *
707         * 設定できる属性
708         *
709         * scrolling属性
710         *
711         *  yes:常にスクロールバーを表示
712         *  no:常にスクロールバーを表示しない
713         *  auto:必要に応じてスクロールバーを表示(デフォルト)
714         *
715         * を指定します。
716         *
717         * frameborder属性
718         *
719         *  0:枠を表示しない
720         *  1:枠を表示する。(デフォルト)
721         *
722         * を指定します。
723         *
724         * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの
725         * 文字を自由に登録する事が出来ます。
726         * CSSでクラスを対応 class="XXXX"
727         *
728         * @param   attri 属性群
729         *
730         * @return  フレームタグ文字列
731         */
732        public static String frame( final Attributes attri ) {
733                return frame( attri,"" );
734        }
735
736        /**
737         * フレームタグを作成します。
738         *
739         * @param   attri 属性群
740         * @param   urlEncode 文字列   ( ?key1=val1&amp;・・・・ という文字列 無いときは "" )
741         *
742         * @return  フレームタグ文字列
743         */
744        public static String frame( final Attributes attri,final String urlEncode ) {
745
746                String src  = addUrlEncode( attri.get( "src" ),urlEncode );
747                String values = attri.getAttribute( FRAME_KEY );
748
749                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
750                rtn.append("<frame src=\"");
751                rtn.append( src );
752                rtn.append( "\" " );
753                rtn.append( values );
754                rtn.append( " />" );
755
756                return rtn.toString();
757        }
758
759        /**
760         * URLエンコード文字列を作成します。
761         * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。
762         * エンコード文字列がある場合は, "?KEY1=VAL1&amp;KEY2=VAL2&amp;・・・" という文字列を
763         * 返します。
764         * つまり、どちらのケースでも、URI に 連結させればよいことになります。
765         *
766         * @param   keys   URLの引数となるキー群
767         * @param   values URLの引数となる値群
768         *
769         * @return  URLエンコード文字列
770         */
771        public static String urlEncode( final String keys,final String values ) {
772                return urlEncode( keys,values,"&" );
773        }
774
775        /**
776         * URLエンコード文字列を作成します。
777         * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。
778         * エンコード文字列がある場合は, "?KEY1=VAL1&amp;KEY2=VAL2&amp;・・・" という文字列を
779         * 返します。
780         * つまり、どちらのケースでも、URI に 連結させればよいことになります。
781         *
782         * @param   keys   URLの引数となるキー群
783         * @param   values URLの引数となる値群
784         * @param   join   URLの引数群を連結させる文字列
785         *
786         * @return  URLエンコード文字列
787         */
788        public static String urlEncode( final String keys,final String values,final String join ) {
789                if( keys == null || values == null ) { return ""; }
790
791                String[] key = StringUtil.csv2Array( keys );
792                String[] val = StringUtil.csv2Array( values );
793
794                return ( urlEncode( key,val,join ) );
795        }
796
797        /**
798         * URLエンコード文字列を作成します。
799         * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。
800         * エンコード文字列がある場合は, "?KEY1=VAL1&amp;KEY2=VAL2&amp;・・・" という文字列を
801         * 返します。
802         * つまり、どちらのケースでも、URI に 連結させればよいことになります。
803         *
804         * @param   key   URLの引数となるキーの配列
805         * @param   val   URLの引数となる値の配列
806         *
807         * @return  URLエンコード文字列
808         */
809        public static String urlEncode( final String[] key,final String[] val ) {
810                return urlEncode( key,val,"&" );
811        }
812
813        /**
814         * URLエンコード文字列を作成します。
815         * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。
816         * エンコード文字列がある場合は, "?KEY1=VAL1&amp;KEY2=VAL2&amp;・・・" という文字列を
817         * 返します。
818         * つまり、どちらのケースでも、URI に 連結させればよいことになります。
819         *
820         * @og.rev 4.3.3.3 (2008/10/22) valに対して副作用を及ぼさないように修正
821         *
822         * @param   key   URLの引数となるキーの配列
823         * @param   val   URLの引数となる値の配列
824         * @param   join   URLの引数群を連結させる文字列
825         *
826         * @return  URLエンコード文字列
827         */
828        public static String urlEncode( final String[] key,final String[] val,final String join ) {
829                if( key == null || key.length == 0 || val == null || val.length == 0 ) {
830                        return "";
831                }
832                else if( key.length != val.length ) {
833                        String errMsg = "urlEncode のキーとバリューの個数が異なります。" + CR
834                                                + "key.length=[" + key.length + "]  val.length=[" + val.length + "]";
835                        throw new RuntimeException( errMsg );
836                }
837
838                // 4.3.3.3 (2008/10/22)
839                String[] tval = new String[val.length];
840
841                for( int i=0; i<val.length; i++ ) {
842                        if( key[i] == null || key[i].length() == 0 ) { return ""; }
843                        if( val[i] == null || val[i].length() == 0 ) { tval[i] = ""; }
844                        else if( val[i].charAt(0) == '[' ) {            // 暫定対応
845                                tval[i] = val[i];
846                        }
847                        else {
848                                tval[i] = StringUtil.urlEncode( val[i] );
849                        }
850//                      else if( val[i].charAt(0) != '[' ) {            // 暫定対応
851//                              tval[i] = StringUtil.urlEncode( val[i] );
852//                      }
853//                      else {
854//                              tval[i] = val[i];
855//                      }
856                }
857
858                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
859
860                rtn.append( key[0] ).append( "=" ).append( tval[0] );
861                for( int i=1; i<key.length; i++) {
862                        rtn.append( join );
863                        rtn.append( key[i] ).append( "=" ).append( tval[i] );
864                }
865                return rtn.toString();
866        }
867
868        /**
869         * URL文字列に、URLエンコード文字列を連結します。
870         *
871         * URL文字列中にすでに "?" 文字が存在する場合は、URLエンコード側の
872         * 文字列とは、 "&amp;" で連結します。
873         * 逆に、"?" が存在しなければ、"?" で連結します。
874         * URLエンコード文字列が null の場合は、連結しません。
875         *
876         * @param   url URL文字列
877         * @param   encode URLエンコード文字列
878         *
879         * @return  連結文字列
880         */
881        public static String addUrlEncode( final String url,final String encode ) {
882                return addUrlEncode( url,encode,"&" );
883        }
884
885        /**
886         * URL文字列に、URLエンコード文字列を連結します。
887         *
888         * URL文字列中にすでに "?" 文字が存在する場合は、URLエンコード側の
889         * 文字列とは、 join (例 "&amp;" ) で連結します。
890         * 逆に、"?" が存在しなければ、"?" で連結します。
891         * URLエンコード文字列が null の場合は、連結しません。
892         * 連結する、encode 文字列の先頭が、join 文字列の場合、そのまま連結します。
893         * 先頭が、そうでない場合は、join 文字列で連結します。
894         * "?" が存在せず、encode 文字列の先頭が、join 文字列の場合は、、
895         * encode 文字列の先頭を取り除いて、"?" で連結します。
896         *
897         * 例:
898         *    @. abc.html    key1=val1&amp;key2=val2      ⇒ abc.html?key1=val1&amp;key2=val2
899         *    A.abc.html   &amp;key1=val1&amp;key2=val2  ⇒ abc.html?key1=val1&amp;key2=val2
900         *    B.abc.html?key1=val1    key2=val2          ⇒ abc.html?key1=val1&amp;key2=val2
901         *    C.abc.html?key1=val1   &amp;key2=val2      ⇒ abc.html?key1=val1&amp;key2=val2
902         *
903         * @og.rev 5.2.1.0 (2010/10/01) urlがnullの場合に、NullPointerExceptionが発生するバグを修正
904         *
905         * @param   url URL文字列
906         * @param   encode URLエンコード文字列
907         * @param   join   URLの引数群を連結させる文字列
908         *
909         * @return  連結文字列
910         */
911        public static String addUrlEncode( final String url,final String encode,final String join ) {
912                // 5.2.1.0 (2010/10/01) urlがnullの場合に、NullPointerExceptionが発生するバグを修正
913                String tmpUrl = ( url == null ? "" : url );
914
915                if( encode == null || encode.length() == 0 ) { return tmpUrl; }
916
917                final String rtn ;
918                if( tmpUrl.indexOf( '?' ) < 0 ) {
919                        if( encode.startsWith( join ) ) {
920                                rtn = tmpUrl + "?" + encode.substring(join.length());           // A
921                        }
922                        else {
923                                rtn = tmpUrl + "?" + encode;                                                            // @
924                        }
925                }
926                else {
927                        if( encode.startsWith( join ) ) {
928                                rtn = tmpUrl + encode;                                          // C
929                        }
930                        else {
931                                rtn = tmpUrl + join + encode;                           // B
932                        }
933                }
934                return rtn ;
935        }
936
937        /**
938         * 指定位置に画像を配置します。
939         *
940         * @param   attri 属性群
941         *
942         * @return  イメージタグ文字列
943         */
944        public static String img( final Attributes attri ) {
945                String values = attri.getAttribute( IMAGE_KEY );
946                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
947                rtn.append( "<img " );
948                rtn.append( values );
949                rtn.append( " />" );
950
951                return rtn.toString();
952        }
953
954        /**
955         * フォームを作成します。
956         *
957         * &lt;form action="URI" method="HTTPメソッド" enctype="MIMEタイプ" target="フレーム名" ・・・ &gt;フォーム等&lt;/form&gt;
958         *
959         * <table border="1" frame="box" rules="all" >
960         *   <caption>Attributes に設定できる属性</caption>
961         *   <tr><td>action="URI"</td><td>必須</td><td>送信されたフォームデータを処理するプログラムURI</td></tr>
962         *   <tr><td>method="HTTPメソッド"</td><td>オプション</td><td>get/post</td></tr>
963         *   <tr><td>enctype="MIMEタイプ"</td><td>オプション</td><td>フォームデータ送信時のMIMEタイプ</td></tr>
964         *   <tr><td>accept-charset="文字セット"</td><td>オプション</td><td>データとして受付可能な文字セットの指定</td></tr>
965         *   <tr><td>accept="MIMEタイプ"</td><td>オプション</td><td>データとして処理可能なMIMEタイプを指定</td></tr>
966         *   <tr><td>name="名前"</td><td>オプション</td><td>スクリプト等から参照する場合の名前</td></tr>
967         *   <tr><td>target="フレーム名"</td><td>オプション</td><td>フォームを送信した結果を表示させるフレーム</td></tr>
968         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
969         *   <tr><td>body="フォーム等の文字列"</td><td>必須</td><td>input 等のフォーム要素</td></tr>
970         * </table>
971         *
972         * @param   attri 属性群
973         *
974         * @return  フォームタグ文字列
975         */
976        public static String form( final Attributes attri ) {
977                String values = attri.getAttribute( FORM_KEY );
978                String body   = attri.get( "body" );
979                if( body == null ) { body = "" ; }
980
981                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
982                rtn.append("<form ");
983                rtn.append( values );
984                rtn.append( ">" );
985                rtn.append( CR );
986                rtn.append( body );
987                rtn.append( CR );
988                rtn.append("</form>");
989
990                return rtn.toString();
991        }
992
993        /**
994         * 汎用インライン要素(SPAN)を作成します。
995         *
996         * &lt;span class="XXXX" ・・・ &gt;テキスト等&lt;/span&gt;
997         *
998         * <table border="1" frame="box" rules="all" >
999         *   <caption>Attributes に設定できる属性</caption>
1000         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
1001         *   <tr><td>body="テキスト等の文字列"</td><td>オプション</td><td>このテキストを修飾します。</td></tr>
1002         * </table>
1003         *
1004         * @param   attri 属性群
1005         *
1006         * @return  SPANタグ文字列
1007         */
1008        public static String span( final Attributes attri ) {
1009                String values = attri.getAttribute( SPAN_KEY );
1010
1011                String optAttri = attri.get( "optionAttributes" );
1012                String body   = attri.get( "body" );
1013                if( body == null ) { body = "" ; }
1014
1015                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
1016                rtn.append("<span ");
1017                rtn.append( values );
1018                if( optAttri != null ) {
1019                        rtn.append( " " );
1020                        rtn.append( optAttri );
1021                }
1022                rtn.append( ">" );
1023                rtn.append( body );
1024                rtn.append( "</span>" );
1025
1026                return rtn.toString();
1027        }
1028
1029        /**
1030         * 整形済みテキスト(PRE)を作成します。
1031         *
1032         * &lt;pre class="XXXX" ・・・ &gt;テキスト等&lt;/pre&gt;
1033         *
1034         * <table border="1" frame="box" rules="all" >
1035         *   <caption>Attributes に設定できる属性</caption>
1036         *   <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr>
1037         *   <tr><td>body="テキスト等の文字列"</td><td>オプション</td><td>このテキストを修飾します。</td></tr>
1038         * </table>
1039         *
1040         * @param   attri 属性群
1041         *
1042         * @return  PREタグ文字列
1043         */
1044        public static String pre( final Attributes attri ) {
1045                String values = attri.getAttribute( PRE_KEY );
1046
1047                String optAttri = attri.get( "optionAttributes" );
1048                String body   = attri.get( "body" );
1049                if( body == null ) { body = "" ; }
1050
1051                StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
1052                rtn.append("<pre ");
1053                rtn.append( values );
1054                if( optAttri != null ) {
1055                        rtn.append( " " );
1056                        rtn.append( optAttri );
1057                }
1058                rtn.append( ">" );
1059                rtn.append( body );
1060                rtn.append( "</pre>" );
1061
1062                return rtn.toString();
1063        }
1064
1065        /**
1066         * URLチェック用のキーを返します。
1067         *
1068         * 引数に指定されたhrefに対して、時間とユーザーIDを付加した暗号化文字列を
1069         * 引数に追加します。
1070         *
1071         * 暗号化は、org.opengion.fukurou.util.HybsCryptographyを使用します。
1072         * 暗号化を行う文字列のフォーマットは、[href],time=[checkTime],userid=[loginUser]です。
1073         *
1074         * @og.rev 4.3.7.1 (2009/06/08) 新規追加
1075         * @og.rev 4.3.7.4 (2009/07/01) 循環参照を解消
1076         * @og.rev 5.8.8.0 (2015/06/05) キー指定対応で別メソッドに処理を委譲
1077         *
1078         * @param   href チェック対象のURL
1079         * @param   key チェックキーのパラメーターキー
1080         * @param   userid ユーザーID
1081         * @param   time 有効時間
1082         *
1083         * @return  チェックキー
1084         * @see org.opengion.fukurou.security.HybsCryptography
1085         */
1086        public static String addURLCheckKey( final String href, final String key, final String userid, final long time ) {
1087//              String checkKey = href;
1088//              checkKey = checkKey.replace( "../", "" );
1089                
1090//              checkKey = checkKey + ",time=" + time + ",userid=" + userid;
1091//              checkKey = HYBS_CRYPTOGRAPHY.encrypt( checkKey );
1092//              return addUrlEncode( href, key + "=" + checkKey );
1093
1094                return addURLCheckKey( href, key, userid, time, null );
1095        }
1096        
1097        /**
1098         * URLチェック用のキーを返します。
1099         *
1100         * 引数に指定されたhrefに対して、時間とユーザーIDを付加した暗号化文字列を
1101         * 引数に追加します。
1102         *
1103         * 暗号化は、org.opengion.fukurou.util.HybsCryptographyを使用します。
1104         * cryptを渡した場合はそのキーを利用して変換をかけますが、NULLの場合は標準キーで暗号化されます。
1105         * 暗号化を行う文字列のフォーマットは、[href],time=[checkTime],userid=[loginUser]です。
1106         *
1107         * @og.rev 5.8.8.0 (2015/06/05) 新規作成
1108         *
1109         * @param   href チェック対象のURL
1110         * @param   key チェックキーのパラメーターキー
1111         * @param   userid ユーザーID
1112         * @param   time 有効時間
1113         * @param       crypt 暗号化クラス
1114         *
1115         * @return  チェックキー
1116         * @see org.opengion.fukurou.security.HybsCryptography
1117         */
1118        public static String addURLCheckKey( final String href, final String key, final String userid, final long time, final HybsCryptography crypt ) {
1119                String checkKey = href;
1120
1121                checkKey = checkKey + ",time=" + time + ",userid=" + userid;
1122                
1123                if( crypt == null ){
1124                        checkKey = HYBS_CRYPTOGRAPHY.encrypt( checkKey );
1125                }
1126                else{
1127                        checkKey = crypt.encrypt( checkKey );
1128                }
1129
1130                return addUrlEncode( href, key + "=" + checkKey );
1131        }
1132
1133        /**
1134         * Aタグの文字列を解析して、href属性にURLチェック用の暗号化文字列を付加した形で、
1135         * Aタグを再構築し、返します。
1136         *
1137         * @og.rev 4.3.7.1 (2009/06/08) 新規追加
1138         * @og.rev 4.3.7.4 (2009/07/01) 循環参照を解消
1139         * @og.rev 5.8.8.0 (2015/06/05) キー指定対応で別メソッドに処理を委譲
1140         *
1141         * @param   tag Aタグ文字列
1142         * @param   key チェックキーのパラメーターキー
1143         * @param   userid ユーザーID
1144         * @param   time 有効時間
1145         *
1146         * @return  URLチェックキーが付加されたAタグ文字列
1147         */
1148        public static String embedURLCheckKey( final String tag, final String key, final String userid, final long time ) {
1149//              String rtn = tag;
1150//              int hrefStr = rtn.indexOf( "href=\"" );
1151//              if( hrefStr >= 0 ) {
1152//                      int hrefEnd = rtn.indexOf( "\"",hrefStr + 6 );
1153//                      if( hrefEnd >= 0 ) {
1154//                              String href = rtn.substring( hrefStr + 6, hrefEnd );
1155//                              href = XHTMLTag.addURLCheckKey( href, key, userid, time );
1156//                              rtn = rtn.substring( 0,  hrefStr ) + "href=\"" + href + rtn.substring( hrefEnd );
1157//                      }
1158//              }
1159//              return rtn;
1160                return embedURLCheckKey( tag, key, userid, time, null  );
1161        }
1162        
1163        /**
1164         * Aタグの文字列を解析して、href属性にURLチェック用の暗号化文字列を付加した形で、
1165         * Aタグを再構築し、返します。
1166         *
1167         * @og.rev 5.8.8.0 (2015/06/05) 新規作成
1168         *
1169         * @param   tag Aタグ文字列
1170         * @param   key チェックキーのパラメーターキー
1171         * @param   userid ユーザーID
1172         * @param   time 有効時間
1173         * @param       crypt 暗号化クラス
1174         *
1175         * @return  URLチェックキーが付加されたAタグ文字列
1176         */
1177        public static String embedURLCheckKey( final String tag, final String key, final String userid, final long time, final HybsCryptography crypt ) {
1178                String rtn = tag;
1179                int hrefStr = rtn.indexOf( "href=\"" );
1180                if( hrefStr >= 0 ) {
1181                        int hrefEnd = rtn.indexOf( "\"",hrefStr + 6 );
1182                        if( hrefEnd >= 0 ) {
1183                                String href = rtn.substring( hrefStr + 6, hrefEnd );
1184                                href = XHTMLTag.addURLCheckKey( href, key, userid, time, crypt );
1185                                rtn = rtn.substring( 0,  hrefStr ) + "href=\"" + href + rtn.substring( hrefEnd );
1186                        }
1187                }
1188                return rtn;
1189        }
1190}