OSDN Git Service

Ver8.5.2.0
[opengion/opengionV8.git] / uap / webapps / gf / src / org / opengion / hayabusa / taglib / DatalistTag.java
1 /*
2  * Copyright (c) 2009 The openGion Project.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific language
14  * governing permissions and limitations under the License.
15  */
16 package org.opengion.hayabusa.taglib;
17
18 import org.opengion.fukurou.system.OgRuntimeException;                                                  // 6.4.2.0 (2016/01/29)
19 import static org.opengion.fukurou.util.StringUtil.nval;
20
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23
24 import org.opengion.fukurou.util.Options;
25 //import org.opengion.hayabusa.common.HybsSystem;                                                               // 8.5.2.0 (2023/07/14) Delete
26 import org.opengion.fukurou.util.ToString;                                                                              // 6.1.1.0 (2015/01/17)
27
28 /**
29  * フォームの入力欄などで入力候補となるデータリストを定義するHTML拡張タグです。
30  * HTML5 から、新たに追加された要素です。
31  *
32  * データリスト内の選択肢は、optionタグ、queryOptionタグによって指定します。
33  * データリスト の id 属性は、フォームの list 属性と同じキーを指定する事で関連付けします。
34  *
35  * @og.formSample
36  * ●形式:<og:datalist id="…" />
37  * ●body:あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{@XXXX} は解析しません)
38  *
39  * ●Tag定義:
40  *   <og:datalist
41  *       id               ○【TAG】入力候補を表示するフォームの list 属性に設定する id (必須)
42  *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
43  *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
44  *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
45  *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
46  *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
47  *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
48  *   >   ... Body ...
49  *   </og:datalist>
50  *
51  * ●使用例
52  * <og:input type="text" name="tokyo" autocomplete="on" list="tokyo.sel" />
53  *
54  *  <og:datalist id="tokyo.sel" >
55  *      <og:option value="渋谷" />
56  *      <og:option value="新宿" />
57  *      <og:option value="池袋" />
58  *  </og:datalist>
59  *
60  * ただし、値なしのOptionを含めても(addNoValue="true")、HTML5の仕様上、
61  * 値なしのOptionは表示されません。
62  *
63  * @og.group 【HTML5】選択データ制御
64  * @og.rev 5.7.1.0 (2013/12/06) 新規追加
65  *
66  * @version     6.0
67  * @author      Kazuhiko Hasegawa
68  * @since       JDK5.0,
69  */
70 public class DatalistTag extends CommonTagSupport implements OptionAncestorIF {
71         /** このプログラムのVERSION文字列を設定します。 {@value} */
72         private static final String VERSION = "8.5.2.0 (2023/07/14)" ;
73         private static final long serialVersionUID = 852020230714L ;
74
75         private transient Options option        = new Options();
76         /** フォームと関連付けるid */
77         private String id;
78
79         /**
80          * デフォルトコンストラクター
81          *
82          * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
83          */
84         public DatalistTag() { super(); }               // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
85
86         /**
87          * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
88          *
89          * @return      後続処理の指示( EVAL_BODY_INCLUDE )
90          */
91         @Override
92         public int doStartTag() {
93                 // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
94                 return useTag()
95                                         ? EVAL_BODY_INCLUDE             // Body インクルード( extends TagSupport 時)
96                                         : SKIP_BODY ;                   // Body を評価しない
97         }
98
99         /**
100          * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
101          *
102          * @og.rev 5.7.6.2 (2014/05/16) IEのHTML5機能が無効の場合、INDBMENU を作成します。
103          * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
104          * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
105          *
106          * @return      後続処理
107          */
108         @Override
109         public int doEndTag() {
110                 debugPrint();                                   // 4.0.0 (2005/02/28)
111                 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
112                 if( useTag() ) {
113                         // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
114                         if( id == null ) {
115                                 final String errMsg = "idは必須です。" ;
116                                 throw new OgRuntimeException( errMsg );
117                         }
118
119                         final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
120
121 //                      // 5.7.6.2 (2014/05/16) IEのHTML5機能が無効の場合の処理 8.5.2.0 (2023/07/14) Delete
122 //                      final String ieHTML5 = (String)getSessionAttribute( HybsSystem.IE_HTML5_KEY );
123 //                      if( "FALSE".equalsIgnoreCase( ieHTML5 ) ) {
124 //                              final String inName = id.endsWith( ".sel" ) ? id.substring( 0,id.length()-4 ) : id ;
125 //
126 //                              rtn.append("<select id='").append( id )
127 //                                      .append( "' style='position:absolute;' onChange='selChanged(this);' >" )
128 //                                      .append( option.getOption() )
129 //                                      // 8.1.0.0 (2021/12/28) HTML5 準拠に見直し(<script> type属性削除)
130 ////                                    .append( "</select><script type='text/javascript'>makeInputMenu('" )
131 //                                      .append( "</select><script>makeInputMenu('" )
132 //                                      .append( inName ).append( "');</script>" );
133 //                      }
134 //                      else {
135 //                              // display:none は、datalist の optionのBODY部が、HTML5 以外では表示されてしまうため。
136 //                              rtn.append("<div style='display:none;'><datalist id='")
137 //                                      .append( id ).append( "' >" )
138 //                                      .append( option.getOption() )
139 //                                      .append( "</datalist></div>" );
140 //                      }
141                         rtn.append("<datalist id='")
142                                 .append( id ).append( "' >" )
143                                 .append( option.getOption() )
144                                 .append( "</datalist>" );
145
146                         jspPrint( rtn.toString() );
147                 }
148                 return EVAL_PAGE ;
149         }
150
151         /**
152          * タグリブオブジェクトをリリースします。
153          * キャッシュされて再利用されるので、フィールドの初期設定を行います。
154          *
155          */
156         @Override
157         protected void release2() {
158                 super.release2();
159                 option  = new Options();
160                 id              = null;
161         }
162
163         /**
164          * データリストの選択項目を追加します。
165          *
166          * datalist タグのBODY要素の OptionTag よりアクセスされます。
167          *
168          * @param       opt     オプションタグ文字列
169          * @see         org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
170          */
171         @Override       // OptionAncestorIF
172         public void addOption( final String opt ) {
173                 option.add( opt );
174         }
175
176         /**
177          * メニュー項目の最後の項目を削除します。
178          *
179          * select タグのBODY要素の OptionTag よりアクセスされます。
180          *
181          * @og.rev 6.8.0.0 (2017/06/02) メニュー項目の最後の項目を削除。
182          *
183          * @see         org.opengion.hayabusa.taglib.OptionAncestorIF#removeLast()
184          */
185         @Override       // OptionAncestorIF
186         public void removeLast() {
187                 option.removeLast();
188         }
189
190         /**
191          * 【HTML】要素に対して固有の名前(id)をつける場合に設定します。
192          *
193          * @og.tag
194          * データリスト の id 属性は、フォームの list 属性と同じキーを指定する事で関連付けします。
195          *
196          * ※
197          * 内部事情で、inputタグ(columnタグ)の list属性 に設定するキーも、id属性に設定するキーも、
198          * inputタグ(columnタグ)の name属性+".sel" を標準的に使用してください。
199          *
200          * @param       id      固有の名前
201          */
202         @Override
203         public void setId( final String id ) {
204                 this.id = nval( getRequestParameter( id ), null );
205         }
206
207         /**
208          * 値を外部から取り出します。
209          *
210          * OptionTag で、value を取り出して、内部の値と同じ場合は、選択状態にします。
211          *
212          * @og.rev 5.7.1.0 (2013/12/06) 新規追加
213          *
214          * @return      null固定
215          * @see         org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
216          */
217         @Override       // OptionAncestorIF
218         public String getValue() {
219                 // ここでは、何もしません。
220                 return null;
221         }
222
223         /**
224          * 複数選択可能時に全選択を設定するかどうかを返します。
225          *
226          * これは、上位入れ子のタグの OptionTag で、multipleAll を取り出して、
227          * true であれば、全選択に設定します。
228          *
229          * @og.rev 5.7.1.0 (2013/12/06) 新規追加
230          *
231          * @return      false固定
232          * @see         org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
233          */
234         @Override       // OptionAncestorIF
235         public boolean isMultipleAll() {
236                 // ここでは、何もしません。
237                 return false;
238         }
239
240         /**
241          * パラメーター変換({&#064;XXXX}の置き換えをしない状態のパラメーターをセットします。
242          *
243          * ※ ここでは、何もしません。
244          *
245          * @og.rev 5.7.1.0 (2013/12/06) 新規追加
246          *
247          * @param       param   パラメーター
248          * @see         org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
249          */
250         @Override       // OptionAncestorIF
251         public void setRawParam( final String param ) {
252                 // ここでは、何もしません。
253         }
254
255         /**
256          * セレクトメニューの場合、キー:ラベル形式で表示するかどうか[true/false/null]を返します。
257          *
258          * これは、上位入れ子のタグの OptionTag で、addKeyLabel を取り出して、
259          * true であれば、キー:ラベル形式 のオプションを、#addOption( String ) で
260          * 登録させます。
261          *
262          * @og.rev 6.0.4.0 (2014/11/28) キー:ラベル形式で表示するかどうか。新規追加
263          *
264          * @return      null固定
265          * @see         #addOption( String )
266          * @see         org.opengion.hayabusa.taglib.OptionAncestorIF#getAddKeyLabel()
267          */
268         @Override       // OptionAncestorIF
269         public String getAddKeyLabel() {
270                 // ここでは、何もしません。
271                 return null;
272         }
273
274         /**
275          * シリアライズ用のカスタムシリアライズ読み込みメソッド
276          *
277          * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
278          *
279          * @serialData 一部のオブジェクトは、シリアライズされません。
280          *
281          * @param       strm    ObjectInputStreamオブジェクト
282          * @see         #release2()
283          * @throws      IOException     シリアライズに関する入出力エラーが発生した場合
284          * @throws      ClassNotFoundException  クラスを見つけることができなかった場合
285          */
286         private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
287                 strm.defaultReadObject();
288                 option = new Options();
289         }
290
291         /**
292          * このオブジェクトの文字列表現を返します。
293          * 基本的にデバッグ目的に使用します。
294          *
295          * @return      このクラスの文字列表現
296          * @og.rtnNotNull
297          */
298         @Override
299         public String toString() {
300                 return ToString.title( this.getClass().getName() )
301                                 .println( "VERSION"             ,VERSION                )
302                                 .println( "id"                  ,id                             )
303                                 .println( "Other..."    ,getAttributes().getAttribute() )
304                                 .fixForm().toString() ;
305         }
306 }