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.plugin.column; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.common.HybsSystemException; 020import org.opengion.hayabusa.db.AbstractEditor; 021import org.opengion.hayabusa.db.CellEditor; 022import org.opengion.hayabusa.db.SelectionCellEditor; // 6.2.2.0 (2015/03/27) 023import org.opengion.hayabusa.db.DBColumn; 024import org.opengion.hayabusa.db.Selection; 025import org.opengion.hayabusa.db.SelectionFactory; 026import org.opengion.fukurou.util.StringFormat; 027import org.opengion.fukurou.util.XHTMLTag; 028import org.opengion.fukurou.util.TagBuffer; 029 030import static org.opengion.fukurou.util.StringUtil.isNull; // 6.1.1.0 (2015/01/17) 031 032/** 033 * カラムの編集パラメーターのSQL文の実行結果より、datalistを作成して 034 * 入力候補となるデータリストを定義する編集用エディタークラスです。 035 * datalist は、HTML5 から採用されたタグです。 036 * 037 * 編集パラメータには、datalistを作成するための、SQL文を記述します。 038 * このSQL文は、select KEY,LABEL from xx ・・・ という構文で、KEY部分とLABEL部分が 039 * 選択されます。 040 * datalist 自身が、HTML5からの新機能なので、現時点では、これ以上の機能はありません。 041 * 将来的に、DBMENU などと同様に、第三カラム以降を利用可能になると思いますので、 042 * 今は使わないでください。(将来の機能追加時に互換性問題を引き起こすかもしれませんので) 043 * 044 * 入力フィールドとdatalistタグとの関係付は、カラムIDに、"カラムID.sel" で結びつけます。 045 * 046 * <input name="カラムID" list="カラムID.sel" /> 047 * <div style="display:none;"> 048 * <datalist id="カラムID.sel"> 049 * <option value="KEY1">LABEL1</option> 050 * <option value="KEY2">LABEL2</option> 051 * <option value="KEY3">LABEL3</option> 052 * </datalist> 053 * </div> 054 * 055 * divタグは、HTML5 非対応ブラウザを使用した場合、datalist の option がそのまま 056 * テキストとして見えてしまうのを避けるためです。 057 * 058 * 一覧表出力時の getValue( int ,String ) 処理では、Selection オブジェクトの 059 * キャッシュ機能を利用して、同一Selection オブジェクトの間は、datalist は、 060 * 1度しか、出力しない様に制御しています。これにより、共有のdatalist を使用する為、 061 * HTMLの出力データ量を抑えることが可能になります。 062 * (キャッシュを利用しないと100行出力すると100個のdatalistを出力する事になります。) 063 * (同様の機能を持つ INDBMENU では、行ごとにプルダウンデータを作成しています。) 064 * ただし、行単位にSQLの条件を変える機能(AAA:BBB:CCC:DDD引数)が指定された場合は、 065 * 行ごとに出力します。 066 * 067 * 各カラムの値(value値)に、AAA:BBB:CCC:DDD という値を設定できます。これは、 068 * $1,$2,$3,$4 に割り当てなおして、QUERYを実行します。また、$1 は、本来の値として、 069 * メニューの初期値設定等に使用します。上記の例では、AAA が値で、それ以降は、 070 * 引数になります。 071 * 又、$Cには自分自身のカラム名を割り当てます。 072 * この機能を使用すれば、動的メニューを行ごとに条件を変えて作成することが 073 * 可能になります。 074 * 例:select KEY,LABEL from xx where KUBUN='$2' and CDK='$3' 075 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 076 * 変数は、""(ゼロ文字列)として、扱われます。 077 * 078 * カラムの表示に必要な属性は, DBColumn オブジェクト より取り出します。 079 * このクラスは、DBColumn オブジェクト毎に1つ作成されます。 080 * 081 * @og.rev 5.7.4.3 (2014/03/28) 新規作成 082 * @og.rev 6.2.2.0 (2015/03/27) SelectionCellEditor I/Fを追加 083 * @og.group データ編集(HTML5) 084 * 085 * @version 4.0 086 * @author Kazuhiko Hasegawa 087 * @since JDK5.0, 088 */ 089public class Editor_DATALIST extends AbstractEditor implements SelectionCellEditor { 090 /** このプログラムのVERSION文字列を設定します。 {@value} */ 091 private static final String VERSION = "6.4.5.3 (2016/05/13)" ; 092 093 // 5.7.5.0 (2014/04/04) datalist 使用時は、display:none にして、HTML5未対応のブラウザに備える。 094 private static final String DIV1 = "<div style=\"display:none;\">" ; 095 private static final String DIV2 = "</div>" ; 096 097 private final String query ; 098 private final String dbid ; 099 private final String lang ; 100 private final String useSLabel ; // 6.2.0.0 (2015/02/27) SLABEL 対応 101 private final String addKeyLabel ; // 6.2.0.0 (2015/02/27) キー:ラベル形式 102 103 private Selection bkSel ; // 5.7.5.0 (2014/04/04) Selection オブジェクトのキャッシュ機能 104 105 /** 106 * デフォルトコンストラクター。 107 * このコンストラクターで、基本オブジェクトを作成します。 108 * 109 * @og.rev 6.2.0.0 (2015/02/27) SLABEL 対応 110 * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。 111 */ 112 public Editor_DATALIST() { 113 super(); // 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 114 // super(); 115 query = null; 116 dbid = null; 117 lang = null; 118 useSLabel = "auto"; // 6.2.0.0 (2015/02/27) SLABEL 対応 119 addKeyLabel = null; // 6.2.0.0 (2015/02/27) キー:ラベル形式 120 } 121 122 /** 123 * コンストラクター。 124 * 125 * @og.rev 6.2.0.0 (2015/02/27) SLABEL 対応 126 * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。 127 * 128 * @param clm DBColumnオブジェクト 129 */ 130 private Editor_DATALIST( final DBColumn clm ) { 131 super( clm ); 132 tagBuffer.add( XHTMLTag.inputAttri( attributes ) ); 133 134 query = clm.getEditorParam(); 135 dbid = clm.getDbid(); 136 lang = clm.getLang(); // 4.0.0.0 (2006/11/15) 137 useSLabel = clm.getUseSLabel() ; // 6.2.0.0 (2015/02/27) SLABEL 対応 138 addKeyLabel = clm.getAddKeyLabel(); // 6.2.0.0 (2015/02/27) キー:ラベル形式 139 140 // 3.5.5.9 (2004/06/07) 141 if( query == null || query.isEmpty() ) { 142 final String errMsg = "DATALIST Editor では、編集パラメータは必須です。" 143 + " name=[" + name + "]" + CR ; 144 throw new HybsSystemException( errMsg ); 145 } 146 } 147 148 /** 149 * 各オブジェクトから自分のインスタンスを返します。 150 * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に 151 * まかされます。 152 * 153 * @param clm DBColumnオブジェクト 154 * 155 * @return CellEditorオブジェクト 156 * @og.rtnNotNull 157 */ 158 public CellEditor newInstance( final DBColumn clm ) { 159 return new Editor_DATALIST( clm ); 160 } 161 162 /** 163 * データの編集用文字列を返します。 164 * 165 * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、 166 * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に 167 * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。 168 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 169 * 変数は、""(ゼロ文字列)として、扱われます。 170 * 又、$Cには自分自身のカラム名を割り当てます。 171 * 172 * @og.rev 5.7.5.0 (2014/04/04) datalist 使用時は、display:none にして、HTML5未対応のブラウザに備える。 173 * @og.rev 5.7.6.2 (2014/05/16) list属性とid属性の結びつきを、name+".sel" に変更 174 * @og.rev 6.2.0.0 (2015/02/27) SLABEL 対応 175 * @og.rev 6.4.5.3 (2016/05/13) value は、コロン区切りの先頭だけ分離する。 176 * 177 * @param value 入力値 178 * 179 * @return データの編集用文字列 180 * @og.rtnNotNull 181 */ 182 @Override 183 public String getValue( final String value ) { 184 final String newValue = StringFormat.getValue( value ); // 6.4.5.3 (2016/05/13) コロン区切りの先頭だけ 185 186 // input タグの作成 187 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 188 final String intag = new TagBuffer( "input" ) 189 .add( "name" , name ) // 4.3.6.0 (2009/04/01) 190 .add( "id" , name , isNull( attributes.get( "id" ) ) ) // 4.3.7.2 (2009/06/15) 191 .add( "list" , name + ".sel" ) // datalistタグとの関係付けるためのキーワード 192 .add( "value" , newValue ) // 6.4.5.3 (2016/05/13) 193 .add( "size" , size1 ) 194 .add( tagBuffer.makeTag() ) 195 .makeTag(); 196 197 final boolean useSlbl = "true".equalsIgnoreCase( useSLabel ); // 6.2.0.0 (2015/02/27) 198 199 // datalist タグの作成 200 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 201 final String dltag = getOption( 202 new TagBuffer( "datalist" ) 203 .add( "id" , name + ".sel" ) // inputタグとの関係付けるためのキーワード 204 , value 205 , false // キャッシュは使用しない。(つまり、null は返らない) 206 , useSlbl // 6.2.0.0 (2015/02/27) SLABEL 対応 207 ).makeTag() ; 208 209 // DIV1 の display:none は、datalist の optionのBODY部が、HTML5 以外では表示されてしまうのを防ぐため。 210 return intag + CR + DIV1 + dltag + DIV2 + CR; 211 212 } 213 214 /** 215 * name属性を変えた、データ表示/編集用のHTML文字列を作成します。 216 * テーブル上の name に 行番号を付加して、名前_行番号 で登録するキーを作成し, 217 * リクエスト情報を1つ毎のフィールドで処理できます。 218 * 219 * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、 220 * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に 221 * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。 222 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 223 * 変数は、""(ゼロ文字列)として、扱われます。 224 * 又、$Cには自分自身のカラム名を割り当てます。 225 * 226 * @og.rev 5.7.5.0 (2014/04/04) datalist 使用時は、display:none にして、HTML5未対応のブラウザに備える。 227 * @og.rev 5.7.5.0 (2014/04/04) Selection オブジェクトのキャッシュ機能 228 * @og.rev 5.7.6.2 (2014/05/16) list属性とid属性の結びつきを、name+".sel" に変更 229 * @og.rev 6.2.0.0 (2015/02/27) SLABEL 対応 230 * @og.rev 6.4.5.3 (2016/05/13) value は、コロン区切りの先頭だけ分離する。 231 * 232 * @param row 行番号 233 * @param value 入力値 234 * 235 * @return データ表示/編集用の文字列 236 * @og.rtnNotNull 237 */ 238 @Override 239 public String getValue( final int row,final String value ) { 240 final String name2 = name + HybsSystem.JOINT_STRING + row ; 241 242 // 5.7.5.0 (2014/04/04) Selection オブジェクトのキャッシュ機能 (true:使用可能) 243 final boolean useSelCache = value != null && value.indexOf( ':' ) < 0 ; 244 245 final String listId = useSelCache ? name : name2; // キャッシュを使用する場合は、共通の name を使う。 246 247 final String newValue = StringFormat.getValue( value ); // 6.4.5.3 (2016/05/13) コロン区切りの先頭だけ 248 249 // input タグの作成 250 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 251 final String intag = new TagBuffer( "input" ) 252 .add( "name" , name2 ) // 4.3.6.0 (2009/04/01) 253 .add( "id" , name2 , isNull( attributes.get( "id" ) ) ) // 4.3.7.2 (2009/06/15) 254 .add( "list" , listId + ".sel" ) // datalistタグとの関係付けるためのキーワード 255 .add( "value" , newValue ) // 6.4.5.3 (2016/05/13) 256 .add( "size" , size2 ) 257 .add( tagBuffer.makeTag() ) 258 .makeTag( row,newValue ); // 6.4.5.3 (2016/05/13) 259 260 final boolean useSlbl = "auto".equalsIgnoreCase( useSLabel ) || "true".equalsIgnoreCase( useSLabel ); // 6.2.0.0 (2015/02/27) 261 262 // datalist タグの作成 263 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 264 final TagBuffer dltag = getOption( 265 new TagBuffer( "datalist" ) 266 .add( "id" , listId + ".sel" ) // inputタグとの関係付けるためのキーワード 267 , value 268 , useSelCache 269 , useSlbl // 6.2.0.0 (2015/02/27) SLABEL 対応 270 ); 271 272 // キャッシュが効くと、getOption の戻り値は、null になる。 273 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 274 // 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 275 // 反転注意 276 return dltag == null 277 ? intag + CR 278 : intag + CR + DIV1 + dltag.makeTag( row,newValue ) + DIV2 + CR ; // 6.4.5.3 (2016/05/13) 279 } 280 281 /** 282 * 初期値が選択済みの 選択肢(オプション)をTagBuffer に反映します。 283 * このオプションは、引数の値を初期値とするオプションタグ作成し、TagBuffer 284 * に値を設定して返します。 285 * 286 * 第3引数は、Selection オブジェクトのキャッシュ機能を使用するかどうか指定します。 287 * true で、使用する事を前提に、チェックを行います。 288 * DBMENU など、他のメソッドでは、ラベル(短)の使用有無として使用しているため、異なります。 289 * 290 * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、 291 * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に 292 * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。 293 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 294 * 変数は、""(ゼロ文字列)として、扱われます。 295 * 又、$Cには自分自身のカラム名を割り当てます。 296 * 297 * @og.rev 6.2.0.0 (2015/02/27) SLABEL 対応 298 * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。 299 * 300 * @param buf タグ文字列のバッファー 301 * @param value 選択されている値 302 * @param useSelCache Selection オブジェクトのキャッシュ機能を使用するかどうか。 303 * @param useSlbl ラベル(短)をベースとしたオプション表示を行うかどうか。 304 * 305 * @return オプションタグ 306 */ 307 private TagBuffer getOption( final TagBuffer buf,final String value,final boolean useSelCache,final boolean useSlbl ) { 308 309 final StringFormat format = new StringFormat( query, value, name ); 310 final String newQuery = format.format(); 311 312 // 6.2.0.0 (2015/02/27) キー:ラベル形式 313 final Selection selection = SelectionFactory.newDBSelection( newQuery, dbid, lang, addKeyLabel ); 314 315 if( useSelCache ) { 316 if( selection == bkSel ) { return null; } 317 bkSel = selection ; 318 } 319 320 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 321 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid declaring a variable if it is unreferenced before a possible exit point. 322 final String newValue = format.getValue(); 323 return buf.addBody( selection.getOption( newValue, false, useSlbl ) ); // 6.2.0.0 (2015/02/27) SLABEL 対応 324 325 } 326}