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 * また,イメージ <img ・・・・> を指定することも,可能です。 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 * <input type="text" name="名前" value="送信文字" ....> 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 return hidden(name,value,name); 383 } 384 385 /** 386 * HIDDEN フォームを作成します。 387 * 388 * @og.rev 5.5.4.0 (2012/07/02) ID属性追加 389 * 390 * @param name フォームの名前 391 * @param value 値 392 * @param id フォームのID 393 * 394 * @return HIDDENフォームタグ文字列 395 */ 396 public static String hidden( final String name, final String value, final String id ) { 397 StringBuilder rtn = new StringBuilder( BUFFER_SMALL ); 398 399 rtn.append( "<input type=\"hidden\" " ); 400 rtn.append( "name=\"" ).append( name ); 401 rtn.append( "\" value=\"" ).append( value ); 402 rtn.append( "\" id=\"" ).append( id ); 403 rtn.append( "\" />" ); 404 405 return rtn.toString(); 406 } 407 408 /** 409 * テキストエリアを作成します。 410 * 411 * <textarea name="名前" rows="4" cols="40" ....>送信文字列 </textarea> 412 * 413 * <table border="1" frame="box" rules="all" > 414 * <caption>Attributes に設定できる属性</caption> 415 * <tr><td>name="名前"</td><td>オプション</td><td>LabelResource.properties のキー</td></tr> 416 * <tr><td>rows="行数"</td><td>オプション</td><td>入力フィールドの表示行数</td></tr> 417 * <tr><td>cols="幅"</td><td>オプション</td><td>入力フィールドの表示幅(文字数)</td></tr> 418 * <tr><td>disabled="disabled"</td><td>オプション</td><td>選択や変更の操作をできない状態にする場合に指定</td></tr> 419 * <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0~32767の範囲で数字で指定(小さい順に移動)</td></tr> 420 * <tr><td>accesskey="ショートカットキー"</td><td>オプション</td><td>文字セット中の1文字:WindowsであればAltキーと同時使用</td></tr> 421 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr> 422 * <tr><td>value="値"</td><td>オリジナル</td><td>name属性と共に送信される値</td></tr> 423 * <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>画像や文字などボタン上に表示させたいタグの文字列</td></tr> 424 * <tr><td>サポート外</td><td>未実装</td><td>readonly属性</td></tr> 425 * </table> 426 * 427 * 設定できる属性 428 * 429 * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの 430 * 文字を自由に登録する事が出来ます。 431 * CSSでクラスを対応 class="XXXX" 432 * タブで移動順を指定する tabindex="タブ順" 433 * ショートカットキーを割り当てる accesskey="ショートカットキー" 434 * 435 * @param attri 属性群 436 * 437 * @return 入力フォームタグ文字列 438 */ 439 public static String textarea( final Attributes attri ) { 440 String values = attri.getAttribute( TEXTAREA_KEY ); 441 String body = attri.get( "body" ); 442 if( body == null ) { body = "" ; } 443 444 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 445 rtn.append("<textarea "); 446 rtn.append( values ); 447 rtn.append( ">" ); 448 rtn.append( body ); 449 rtn.append( "</textarea>" ); 450 451 return rtn.toString(); 452 } 453 454 /** 455 * ページリンクを作成します。 456 * 457 * <A href="URL" target="ターゲット名">ラベル</A> 458 * 459 * <table border="1" frame="box" rules="all" > 460 * <caption>Attributes に設定できる属性</caption> 461 * <tr><td>href="URL"</td><td>必須</td><td>リンク先のURLを指定します。</td></tr> 462 * <tr><td>charset="文字セット"</td><td>オプション</td><td>リンク先の文字コードセットを指定します。</td></tr> 463 * <tr><td>hreflang="言語セット"</td><td>オプション</td><td>リンク先の基本となる言語コードを指定します。</td></tr> 464 * <tr><td>type="MIMEタイプ"</td><td>オプション</td><td>リンク先のMIMEタイプを指定します。</td></tr> 465 * <tr><td>name="名前"</td><td>オプション</td><td>この要素をリンクの到達点とするための名前を指定します。</td></tr> 466 * <tr><td>rel="リンクタイプ"</td><td>オプション</td><td>この文書からみた href 属性で指定されるリンク先との関係</td></tr> 467 * <tr><td>rev="リンクタイプ"</td><td>オプション</td><td>href 属性で指定されるリンク先からみた、この文書との関係</td></tr> 468 * <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0~32767の範囲で数字で指定(小さい順に移動)</td></tr> 469 * <tr><td>accesskey="ショートカットキー"</td><td>オプション</td><td>文字セット中の1文字:WindowsであればAltキーと同時使用</td></tr> 470 * <tr><td>target="フレーム名"</td><td>オプション</td><td>リンク先のフレーム名</td></tr> 471 * <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>画像や文字などをリンクにできます。</td></tr> 472 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr> 473 * <tr><td>サポート外</td><td>未実装</td><td>shape属性、coords属性</td></tr> 474 * </table> 475 * 476 * 設定できる属性 477 * 478 * ラベルなしの場合, href属性の "URL" そのものを付けます。 479 * 480 * target属性のフレーム名は 481 * 482 * _top フレームを解除して,リンク先をフレーム全体に表示する。 483 * _parent リンク先を親フレームに表示する。 484 * _self リンク先を自分自身に表示する。 485 * _blank 新しいウインドウを開いて,表示する。 486 * その他 フレーム作成時の名前で指定可能。 487 * 488 * を指定します。 489 * なしの場合 _self (自分自身)を指定します。 490 * 491 * リンクメール機能 492 * URLを,mailto:メールアドレス で設定すれば,メール送信ダイアログを 493 * 開く事が出来ます。 494 * 画像リンク機能 495 * 画像をクリックするリンクは,ラベルの個所に <img>タグを設定します。 496 * 497 * <a href="books.html"><img src="banner.gif" width="468px" height="60px" alt="関連書籍紹介" border="0"></a> 498 * 499 * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの 500 * 文字を自由に登録する事が出来ます。 501 * CSSでクラスを対応 class="XXXX" 502 * タブで移動順を指定する tabindex="タブ順" 503 * ショートカットキーを割り当てる accesskey="ショートカットキー" 504 * 505 * @param attri 属性群 506 * 507 * @return ページリンクタグ文字列 508 */ 509 public static String link( final Attributes attri ) { 510 return link( attri,"" ); 511 } 512 513 /** 514 * ページリンクを作成します。 515 * 516 * @param attri 属性群 517 * @param urlEncode 文字列 ( ?key1=val1&・・・・ という文字列 無いときは "" ) 518 * 519 * @return ページリンクタグ文字列 520 */ 521 public static String link( final Attributes attri, final String urlEncode ) { 522 523 String href = addUrlEncode( attri.get( "href" ),urlEncode ); 524 525 String values = attri.getAttribute( LINK_KEY ); 526 String body = attri.get( "body" ); 527 if( body == null ) { body = attri.get( "href" ) ; } 528 529 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 530 rtn.append("<a href=\""); 531 rtn.append( href ); 532 rtn.append( "\" " ); 533 rtn.append( values ); 534 rtn.append( ">" ); 535 rtn.append( body ); 536 rtn.append( "</a>" ); 537 538 return rtn.toString(); 539 } 540 541 /** 542 * xlink 形式のページリンクを作成します。 543 * 544 * 基本的には、link と同じです。アドレスの指定も、href で指定してください。 545 * 内部的に、xlink:href に変換します。 546 * また、URL引数を、"&" で結合するのではなく、"&amp;" で結合させます。 547 * これは、xlink そのものが、XML上に記述された場合に、XMLのルールで再度パース 548 * される為です。 549 * 550 * @param attri 属性群 551 * @param urlEncode 文字列 ( ?key1=val1&・・・・ という文字列 無いときは "" ) 552 * 553 * @return ページリンクタグ文字列 554 */ 555 public static String xlink( final Attributes attri, final String urlEncode ) { 556 557 String href = addUrlEncode( attri.get( "href" ),urlEncode,"&" ); 558 559 String values = attri.getAttribute( LINK_KEY ); 560 String body = attri.get( "body" ); 561 if( body == null ) { body = attri.get( "href" ) ; } 562 563 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 564 rtn.append("<a xlink:href=\""); 565 rtn.append( href ); 566 rtn.append( "\" " ); 567 rtn.append( values ); 568 rtn.append( ">" ); 569 rtn.append( body ); 570 rtn.append( "</a>" ); 571 572 return rtn.toString(); 573 } 574 575 /** 576 * メニューを作成します。 577 * 578 * @param attri 属性群 579 * @param opt 選択肢(オプション) 580 * 581 * @return メニュータグ文字列 582 */ 583 public static String select( final Attributes attri,final Options opt ) { 584 String name = attri.get( "name" ); 585 String optAttri = attri.get( "optionAttributes" ); 586 587 return select( attri,opt,name,optAttri ); 588 } 589 590 /** 591 * メニューを作成します。 592 * 593 * <select size="行数" name="名前" multiple> 594 * <option value="送信文字1">コメント</option> 595 * <option value="送信文字2">コメント</option> 596 * <option value="送信文字3" selected="selected">コメント</option> 597 * </select> 598 * 599 * <table border="1" frame="box" rules="all" > 600 * <caption>Attributes に設定できる属性</caption> 601 * <tr><td>name="名前"</td><td>オプション</td><td>LabelResource.properties のキー</td></tr> 602 * <tr><td>size="行数"</td><td>オプション</td><td>select要素をリストボックスとして表示する場合の行数</td></tr> 603 * <tr><td>multiple="multiple"</td><td>オプション</td><td>選択肢の中から複数選択出来るようにする。</td></tr> 604 * <tr><td>disabled="disabled"</td><td>オプション</td><td>選択や変更の操作をできない状態にする場合に指定</td></tr> 605 * <tr><td>tabindex="Tab移動順"</td><td>オプション</td><td>0~32767の範囲で数字で指定(小さい順に移動)</td></tr> 606 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr> 607 * </table> 608 * 609 * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの 610 * 文字を自由に登録する事が出来ます。 611 * CSSでクラスを対応 class="XXXX" 612 * 613 * @param attri 属性群 614 * @param opt 選択肢(オプション) 615 * @param name 名前 616 * @param optAttri オプション属性 617 * 618 * @return メニュータグ文字列 619 */ 620 public static String select( final Attributes attri,final Options opt,final String name,final String optAttri ) { 621 String values = attri.getAttribute( SELECT_KEY ); 622 String options = opt.getOption(); 623 624 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 625 rtn.append("<select "); 626 if( name != null ) { rtn.append("name=\"").append( name ).append( "\" " ); } 627 rtn.append( values ); 628 if( optAttri != null ) { 629 rtn.append( " " ); 630 rtn.append( optAttri ); 631 } 632 rtn.append( ">" ); 633 rtn.append( options ); 634 rtn.append( "</select>" ); 635 636 return rtn.toString(); 637 } 638 639 /** 640 * オプションを作成します。 641 * 642 * <select size="行数" name="名前" multiple> 643 * <option value="送信文字1">コメント</option> 644 * <option value="送信文字2">コメント</option> 645 * <option value="送信文字3" selected="selected">コメント</option> 646 * </select> 647 * 648 * <table border="1" frame="box" rules="all" > 649 * <caption>Attributes に設定できる属性</caption> 650 * <tr><td>value="値"</td><td>オプション</td><td>送信する値</td></tr> 651 * <tr><td>selected="selected"</td><td>オプション</td><td>選択肢をあらかじめ選択された状態にしておく</td></tr> 652 * <tr><td>disabled="disabled"</td><td>オプション</td><td>選択や変更の操作をできない状態にする場合に指定</td></tr> 653 * <tr><td>body="表示するタグ文字列"</td><td>オリジナル</td><td>選択肢に表示させたいタグの文字列</td></tr> 654 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr> 655 * </table> 656 * 657 * セレクタとは,リストボックスやメニューなどの option引数にセットする 658 * 複数のデータをoptionタグでくるんだものです。 659 * 660 * @param attri 属性群 661 * 662 * @return オプションタグ文字列 663 */ 664 public static String option( final Attributes attri ) { 665 String values = attri.getAttribute( OPTION_KEY ); 666 String body = attri.get( "body" ); 667 if( body == null ) { body = "No Label" ; } 668 669 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 670 rtn.append("<option "); 671 rtn.append( values ); 672 rtn.append( " >" ); 673 rtn.append( body ); 674 rtn.append( "</option>" ); 675 676 return rtn.toString(); 677 } 678 679 /** 680 * フレームタグを作成します。 681 * 682 * <frame marginheight="2px" marginwidth="2px" src="query.jsp" name="QUERY" /> 683 * 684 * <table border="1" frame="box" rules="all" > 685 * <caption>Attributes に設定できる属性</caption> 686 * <tr><td>src="URL"</td><td>オプション</td><td>フレームの表示先URLを指定します。</td></tr> 687 * <tr><td>name="フレーム名"</td><td>オプション</td><td>フレームに付ける名前を指定します。</td></tr> 688 * <tr><td>longdesc="URI"</td><td>オプション</td><td>フレームの詳しい説明のURI</td></tr> 689 * <tr><td>marginwidth="左右のマージン"</td><td>オプション</td><td>フレーム内の左右のマージンを指定します。</td></tr> 690 * <tr><td>marginheight="上下のマージン"</td><td>オプション</td><td>フレーム内の上下のマージンを指定します。</td></tr> 691 * <tr><td>noresize="noresize"</td><td>オプション</td><td>フレームサイズを変更できないようにします。</td></tr> 692 * <tr><td>scrolling="スクロールの制御"</td><td>オプション</td><td>yes:スクロールバーを表示 no:表示しない auto:必要に応じて表示(デフォルト)</td></tr> 693 * <tr><td>frameborder="枠の表示"</td><td>オプション</td><td>0:枠を表示しない 1:枠を表示する。(デフォルト)</td></tr> 694 * <tr><td>keys="引数にセットするキー"</td><td>オプション</td><td>URI の引数にセットするキーを CSV 形式でセットします。</td></tr> 695 * <tr><td>value="引数にセットする値"</td><td>オプション</td><td>URI の引数にセットする値を CSV 形式でセットします。</td></tr> 696 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style</td></tr> 697 * </table> 698 * 699 * 設定できる属性 700 * 701 * scrolling属性 702 * 703 * yes:常にスクロールバーを表示 704 * no:常にスクロールバーを表示しない 705 * auto:必要に応じてスクロールバーを表示(デフォルト) 706 * 707 * を指定します。 708 * 709 * frameborder属性 710 * 711 * 0:枠を表示しない 712 * 1:枠を表示する。(デフォルト) 713 * 714 * を指定します。 715 * 716 * 属性群は,タグの中に,CSS等で使用できる class="XXX" などの 717 * 文字を自由に登録する事が出来ます。 718 * CSSでクラスを対応 class="XXXX" 719 * 720 * @param attri 属性群 721 * 722 * @return フレームタグ文字列 723 */ 724 public static String frame( final Attributes attri ) { 725 return frame( attri,"" ); 726 } 727 728 /** 729 * フレームタグを作成します。 730 * 731 * @param attri 属性群 732 * @param urlEncode 文字列 ( ?key1=val1&・・・・ という文字列 無いときは "" ) 733 * 734 * @return フレームタグ文字列 735 */ 736 public static String frame( final Attributes attri,final String urlEncode ) { 737 738 String src = addUrlEncode( attri.get( "src" ),urlEncode ); 739 String values = attri.getAttribute( FRAME_KEY ); 740 741 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 742 rtn.append("<frame src=\""); 743 rtn.append( src ); 744 rtn.append( "\" " ); 745 rtn.append( values ); 746 rtn.append( " />" ); 747 748 return rtn.toString(); 749 } 750 751 /** 752 * URLエンコード文字列を作成します。 753 * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。 754 * エンコード文字列がある場合は, "?KEY1=VAL1&KEY2=VAL2&・・・" という文字列を 755 * 返します。 756 * つまり、どちらのケースでも、URI に 連結させればよいことになります。 757 * 758 * @param keys URLの引数となるキー群 759 * @param values URLの引数となる値群 760 * 761 * @return URLエンコード文字列 762 */ 763 public static String urlEncode( final String keys,final String values ) { 764 return urlEncode( keys,values,"&" ); 765 } 766 767 /** 768 * URLエンコード文字列を作成します。 769 * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。 770 * エンコード文字列がある場合は, "?KEY1=VAL1&KEY2=VAL2&・・・" という文字列を 771 * 返します。 772 * つまり、どちらのケースでも、URI に 連結させればよいことになります。 773 * 774 * @param keys URLの引数となるキー群 775 * @param values URLの引数となる値群 776 * @param join URLの引数群を連結させる文字列 777 * 778 * @return URLエンコード文字列 779 */ 780 public static String urlEncode( final String keys,final String values,final String join ) { 781 if( keys == null || values == null ) { return ""; } 782 783 String[] key = StringUtil.csv2Array( keys ); 784 String[] val = StringUtil.csv2Array( values ); 785 786 return urlEncode( key,val,join ) ; 787 } 788 789 /** 790 * URLエンコード文字列を作成します。 791 * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。 792 * エンコード文字列がある場合は, "?KEY1=VAL1&KEY2=VAL2&・・・" という文字列を 793 * 返します。 794 * つまり、どちらのケースでも、URI に 連結させればよいことになります。 795 * 796 * @param key URLの引数となるキーの配列 797 * @param val URLの引数となる値の配列 798 * 799 * @return URLエンコード文字列 800 */ 801 public static String urlEncode( final String[] key,final String[] val ) { 802 return urlEncode( key,val,"&" ); 803 } 804 805 /** 806 * URLエンコード文字列を作成します。 807 * エンコードすべき文字列が無い場合は, 0ストリング("") を返します。 808 * エンコード文字列がある場合は, "?KEY1=VAL1&KEY2=VAL2&・・・" という文字列を 809 * 返します。 810 * つまり、どちらのケースでも、URI に 連結させればよいことになります。 811 * 812 * @og.rev 4.3.3.3 (2008/10/22) valに対して副作用を及ぼさないように修正 813 * 814 * @param key URLの引数となるキーの配列 815 * @param val URLの引数となる値の配列 816 * @param join URLの引数群を連結させる文字列 817 * 818 * @return URLエンコード文字列 819 */ 820 public static String urlEncode( final String[] key,final String[] val,final String join ) { 821 if( key == null || key.length == 0 || val == null || val.length == 0 ) { 822 return ""; 823 } 824 else if( key.length != val.length ) { 825 String errMsg = "urlEncode のキーとバリューの個数が異なります。" + CR 826 + "key.length=[" + key.length + "] val.length=[" + val.length + "]"; 827 throw new RuntimeException( errMsg ); 828 } 829 830 // 4.3.3.3 (2008/10/22) 831 String[] tval = new String[val.length]; 832 833 for( int i=0; i<val.length; i++ ) { 834 if( key[i] == null || key[i].length() == 0 ) { return ""; } 835 if( val[i] == null || val[i].length() == 0 ) { tval[i] = ""; } 836 else if( val[i].charAt(0) == '[' ) { // 暫定対応 837 tval[i] = val[i]; 838 } 839 else { 840 tval[i] = StringUtil.urlEncode( val[i] ); 841 } 842 } 843 844 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 845 846 rtn.append( key[0] ).append( "=" ).append( tval[0] ); 847 for( int i=1; i<key.length; i++) { 848 rtn.append( join ); 849 rtn.append( key[i] ).append( "=" ).append( tval[i] ); 850 } 851 return rtn.toString(); 852 } 853 854 /** 855 * URL文字列に、URLエンコード文字列を連結します。 856 * 857 * URL文字列中にすでに "?" 文字が存在する場合は、URLエンコード側の 858 * 文字列とは、 "&" で連結します。 859 * 逆に、"?" が存在しなければ、"?" で連結します。 860 * URLエンコード文字列が null の場合は、連結しません。 861 * 862 * @param url URL文字列 863 * @param encode URLエンコード文字列 864 * 865 * @return 連結文字列 866 */ 867 public static String addUrlEncode( final String url,final String encode ) { 868 return addUrlEncode( url,encode,"&" ); 869 } 870 871 /** 872 * URL文字列に、URLエンコード文字列を連結します。 873 * 874 * URL文字列中にすでに "?" 文字が存在する場合は、URLエンコード側の 875 * 文字列とは、 join (例 "&" ) で連結します。 876 * 逆に、"?" が存在しなければ、"?" で連結します。 877 * URLエンコード文字列が null の場合は、連結しません。 878 * 連結する、encode 文字列の先頭が、join 文字列の場合、そのまま連結します。 879 * 先頭が、そうでない場合は、join 文字列で連結します。 880 * "?" が存在せず、encode 文字列の先頭が、join 文字列の場合は、、 881 * encode 文字列の先頭を取り除いて、"?" で連結します。 882 * 883 * 例: 884 * ①. abc.html key1=val1&key2=val2 ⇒ abc.html?key1=val1&key2=val2 885 * ②.abc.html &key1=val1&key2=val2 ⇒ abc.html?key1=val1&key2=val2 886 * ③.abc.html?key1=val1 key2=val2 ⇒ abc.html?key1=val1&key2=val2 887 * ④.abc.html?key1=val1 &key2=val2 ⇒ abc.html?key1=val1&key2=val2 888 * 889 * @og.rev 5.2.1.0 (2010/10/01) urlがnullの場合に、NullPointerExceptionが発生するバグを修正 890 * 891 * @param url URL文字列 892 * @param encode URLエンコード文字列 893 * @param join URLの引数群を連結させる文字列 894 * 895 * @return 連結文字列 896 */ 897 public static String addUrlEncode( final String url,final String encode,final String join ) { 898 // 5.2.1.0 (2010/10/01) urlがnullの場合に、NullPointerExceptionが発生するバグを修正 899 String tmpUrl = ( url == null ? "" : url ); 900 901 if( encode == null || encode.length() == 0 ) { return tmpUrl; } 902 903 final String rtn ; 904 if( tmpUrl.indexOf( '?' ) < 0 ) { 905 if( encode.startsWith( join ) ) { 906 rtn = tmpUrl + "?" + encode.substring(join.length()); // ② 907 } 908 else { 909 rtn = tmpUrl + "?" + encode; // ① 910 } 911 } 912 else { 913 if( encode.startsWith( join ) ) { 914 rtn = tmpUrl + encode; // ④ 915 } 916 else { 917 rtn = tmpUrl + join + encode; // ③ 918 } 919 } 920 return rtn ; 921 } 922 923 /** 924 * 指定位置に画像を配置します。 925 * 926 * @param attri 属性群 927 * 928 * @return イメージタグ文字列 929 */ 930 public static String img( final Attributes attri ) { 931 String values = attri.getAttribute( IMAGE_KEY ); 932 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 933 rtn.append( "<img " ); 934 rtn.append( values ); 935 rtn.append( " />" ); 936 937 return rtn.toString(); 938 } 939 940 /** 941 * フォームを作成します。 942 * 943 * <form action="URI" method="HTTPメソッド" enctype="MIMEタイプ" target="フレーム名" ・・・ >フォーム等</form> 944 * 945 * <table border="1" frame="box" rules="all" > 946 * <caption>Attributes に設定できる属性</caption> 947 * <tr><td>action="URI"</td><td>必須</td><td>送信されたフォームデータを処理するプログラムURI</td></tr> 948 * <tr><td>method="HTTPメソッド"</td><td>オプション</td><td>get/post</td></tr> 949 * <tr><td>enctype="MIMEタイプ"</td><td>オプション</td><td>フォームデータ送信時のMIMEタイプ</td></tr> 950 * <tr><td>accept-charset="文字セット"</td><td>オプション</td><td>データとして受付可能な文字セットの指定</td></tr> 951 * <tr><td>accept="MIMEタイプ"</td><td>オプション</td><td>データとして処理可能なMIMEタイプを指定</td></tr> 952 * <tr><td>name="名前"</td><td>オプション</td><td>スクリプト等から参照する場合の名前</td></tr> 953 * <tr><td>target="フレーム名"</td><td>オプション</td><td>フォームを送信した結果を表示させるフレーム</td></tr> 954 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr> 955 * <tr><td>body="フォーム等の文字列"</td><td>必須</td><td>input 等のフォーム要素</td></tr> 956 * </table> 957 * 958 * @param attri 属性群 959 * 960 * @return フォームタグ文字列 961 */ 962 public static String form( final Attributes attri ) { 963 String values = attri.getAttribute( FORM_KEY ); 964 String body = attri.get( "body" ); 965 if( body == null ) { body = "" ; } 966 967 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 968 rtn.append("<form "); 969 rtn.append( values ); 970 rtn.append( ">" ); 971 rtn.append( CR ); 972 rtn.append( body ); 973 rtn.append( CR ); 974 rtn.append("</form>"); 975 976 return rtn.toString(); 977 } 978 979 /** 980 * 汎用インライン要素(SPAN)を作成します。 981 * 982 * <span class="XXXX" ・・・ >テキスト等</span> 983 * 984 * <table border="1" frame="box" rules="all" > 985 * <caption>Attributes に設定できる属性</caption> 986 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr> 987 * <tr><td>body="テキスト等の文字列"</td><td>オプション</td><td>このテキストを修飾します。</td></tr> 988 * </table> 989 * 990 * @param attri 属性群 991 * 992 * @return SPANタグ文字列 993 */ 994 public static String span( final Attributes attri ) { 995 String values = attri.getAttribute( SPAN_KEY ); 996 997 String optAttri = attri.get( "optionAttributes" ); 998 String body = attri.get( "body" ); 999 if( body == null ) { body = "" ; } 1000 1001 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 1002 rtn.append("<span "); 1003 rtn.append( values ); 1004 if( optAttri != null ) { 1005 rtn.append( " " ); 1006 rtn.append( optAttri ); 1007 } 1008 rtn.append( ">" ); 1009 rtn.append( body ); 1010 rtn.append( "</span>" ); 1011 1012 return rtn.toString(); 1013 } 1014 1015 /** 1016 * 整形済みテキスト(PRE)を作成します。 1017 * 1018 * <pre class="XXXX" ・・・ >テキスト等</pre> 1019 * 1020 * <table border="1" frame="box" rules="all" > 1021 * <caption>Attributes に設定できる属性</caption> 1022 * <tr><td>汎用属性</td><td>オプション</td><td>class,id,title,style,lang,dir,xml:lang</td></tr> 1023 * <tr><td>body="テキスト等の文字列"</td><td>オプション</td><td>このテキストを修飾します。</td></tr> 1024 * </table> 1025 * 1026 * @param attri 属性群 1027 * 1028 * @return PREタグ文字列 1029 */ 1030 public static String pre( final Attributes attri ) { 1031 String values = attri.getAttribute( PRE_KEY ); 1032 1033 String optAttri = attri.get( "optionAttributes" ); 1034 String body = attri.get( "body" ); 1035 if( body == null ) { body = "" ; } 1036 1037 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 1038 rtn.append("<pre "); 1039 rtn.append( values ); 1040 if( optAttri != null ) { 1041 rtn.append( " " ); 1042 rtn.append( optAttri ); 1043 } 1044 rtn.append( ">" ); 1045 rtn.append( body ); 1046 rtn.append( "</pre>" ); 1047 1048 return rtn.toString(); 1049 } 1050 1051 /** 1052 * URLチェック用のキーを返します。 1053 * 1054 * 引数に指定されたhrefに対して、時間とユーザーIDを付加した暗号化文字列を 1055 * 引数に追加します。 1056 * 1057 * 暗号化は、org.opengion.fukurou.util.HybsCryptographyを使用します。 1058 * 暗号化を行う文字列のフォーマットは、[href],time=[checkTime],userid=[loginUser]です。 1059 * 1060 * @og.rev 4.3.7.1 (2009/06/08) 新規追加 1061 * @og.rev 4.3.7.4 (2009/07/01) 循環参照を解消 1062 * 1063 * @param href チェック対象のURL 1064 * @param key チェックキーのパラメーターキー 1065 * @param userid ユーザーID 1066 * @param time 有効時間 1067 * 1068 * @return チェックキー 1069 * @see org.opengion.fukurou.security.HybsCryptography 1070 */ 1071 public static String addURLCheckKey( final String href, final String key, final String userid, final long time ) { 1072 String checkKey = href; 1073 1074 checkKey = checkKey.replace( "../", "" ); 1075 checkKey = checkKey + ",time=" + time + ",userid=" + userid; 1076 checkKey = HYBS_CRYPTOGRAPHY.encrypt( checkKey ); 1077 1078 return addUrlEncode( href, key + "=" + checkKey ); 1079 } 1080 1081 /** 1082 * Aタグの文字列を解析して、href属性にURLチェック用の暗号化文字列を付加した形で、 1083 * Aタグを再構築し、返します。 1084 * 1085 * @og.rev 4.3.7.1 (2009/06/08) 新規追加 1086 * @og.rev 4.3.7.4 (2009/07/01) 循環参照を解消 1087 * 1088 * @param tag Aタグ文字列 1089 * @param key チェックキーのパラメーターキー 1090 * @param userid ユーザーID 1091 * @param time 有効時間 1092 * 1093 * @return URLチェックキーが付加されたAタグ文字列 1094 */ 1095 public static String embedURLCheckKey( final String tag, final String key, final String userid, final long time ) { 1096 String rtn = tag; 1097 int hrefStr = rtn.indexOf( "href=\"" ); 1098 if( hrefStr >= 0 ) { 1099 int hrefEnd = rtn.indexOf( "\"",hrefStr + 6 ); 1100 if( hrefEnd >= 0 ) { 1101 String href = rtn.substring( hrefStr + 6, hrefEnd ); 1102 href = XHTMLTag.addURLCheckKey( href, key, userid, time ); 1103 rtn = rtn.substring( 0, hrefStr ) + "href=\"" + href + rtn.substring( hrefEnd ); 1104 } 1105 } 1106 return rtn; 1107 } 1108}