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 */
016 package org.opengion.plugin.table;
017
018 import org.opengion.hayabusa.db.AbstractTableFilter;
019 import org.opengion.hayabusa.db.DBTableModel;
020 import org.opengion.hayabusa.db.DBColumn;
021
022 import org.opengion.hayabusa.resource.ResourceFactory;
023 import org.opengion.hayabusa.resource.ResourceManager;
024 import org.opengion.hayabusa.resource.CodeData;
025
026 import org.opengion.fukurou.util.ErrorMessage;
027 import org.opengion.fukurou.util.StringUtil;
028
029 import java.util.Locale;
030 import java.util.Map;
031
032 /**
033 * TableFilter_CLMSET は、TableFilter インターフェースを継承した、DBTableModel 処?の
034 * 実?ラスです?
035 *
036 * ここでは、CLM,SYSTEM_ID,LANG より、カラ?ソースのRENDERER,EDITOR,DBTYPE,BIKOを設定します?
037 * 検索した DBTableModel の属?として、RENDERER,EDITOR,DBTYPE,BIKO と?名称の
038 * カラ??です?
039 * 引数として?可能なのは、SYSTEM_ID,LANG のみです?
040 * CLM :カラ?ソースのキーとなる?が設定されて?カラ?を指定します?
041 * SYSTEM_ID:コードリソースの作?シス?IDを指定します?無?時は、ログイン時?リソースになります?
042 * LANG:ラベルリソースの?を?します?無?時は、日本語になります?
043 * USE_RESOURCE:リソース??を利用するかど?[true/false]。無?時は、true:利用するになります?
044 *
045 * また?CLM,RENDERER,EDITOR,DBTYPE,BIKO,CLS_NAME,USE_LENGTH で?したカラ? DBTableModel に存在しな??合??
046 * 処?のも?を無視します?そ?場合?、警告も出力されませんので、ご注意く???
047 *
048 * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか?BODY 部にCSS形式で記述します?
049 * 【パラメータ?
050 * {
051 * USE_RESOURCE : [true/false] ; リソースを利用するかど?を指定[true/false](初期値:true)。使??合?DBColumnを構築し、そこか?RENDERE 等を取得します?
052 * CLM : CLM ; カラ?ソースのキーとなる?が設定されて?カラ?を指定します?
053 * SYSTEM_ID : GF ; リソースを使??合に、コードリソースの作?シス?IDを指定します?
054 * LANG : ja ; リソースを使??合に、ラベルリソースの?を?します?
055 * RENDERER : 設定するカラ?
056 * EDITOR : 設定するカラ?
057 * DBTYPE : 設定するカラ?
058 * BIKO : 設定するカラ?
059 * CLS_NAME : 設定するカラ?
060 * USE_LENGTH : 設定するカラ?
061 * }
062 *
063 * @og.formSample
064 * ●形式?
065 * ?<og:tableFilter classId="CLMSET" keys="USE_RESOURCE,CLM,SYSTEM_ID,RENDERER,EDITOR,DBTYPE,BIKO,CLS_NAME,USE_LENGTH"
066 * vals="true,CLM,SYSTEM_ID,RENDERER,EDITOR,DBTYPE,BIKO,CLS_NAME,USE_LENGTH" />
067 *
068 * ② <og:tableFilter classId="CLMSET" >
069 * {
070 * USE_RESOURCE : [true/false] ; リソースを利用するかど?を指定[true/false](初期値:true)。使??合?DBColumnを構築し、そこか?RENDERE 等を取得します?
071 * CLM : CLM ; カラ?ソースのキーとなる?が設定されて?カラ?を指定します?
072 * SYSTEM_ID : GF ; リソースを使??合に、コードリソースの作?シス?IDを指定します?
073 * LANG : ja ; リソースを使??合に、ラベルリソースの?を?します?
074 * RENDERER : 設定するカラ?
075 * EDITOR : 設定するカラ?
076 * DBTYPE : 設定するカラ?
077 * BIKO : 設定するカラ?
078 * CLS_NAME : 設定するカラ?
079 * USE_LENGTH : 設定するカラ?
080 * }
081 * </og:tableFilter>
082 *
083 * @og.rev 4.1.0.0(2008/01/18) 新規作?
084 * @og.rev 5.6.6.0 (2013/07/05) keys の整合?チェ?を追?
085 *
086 * @version 0.9.0 2000/10/17
087 * @author Kazuhiko Hasegawa
088 * @since JDK1.5,
089 */
090 public class TableFilter_CLMSET extends AbstractTableFilter {
091 //* こ?プログラ??VERSION??を設定します? {@value} */
092 private static final String VERSION = "5.6.6.1 (2013/07/12)" ;
093
094 /**
095 * keys の整合?チェ?を行うための初期設定を行います?
096 *
097 * @og.rev 5.6.6.1 (2013/07/12) keys の整合?チェ?対?
098 *
099 * @param keysMap keys の整合?チェ?を行うための Map
100 */
101 @Override
102 protected void init( final Map<String,String> keysMap ) {
103 keysMap.put( "USE_RESOURCE" , "リソースを利用するかど?を指定[true/false](初期値:true)" );
104 keysMap.put( "CLM" , "カラ?ソースのキーとなる?が設定されて?カラ?を指? );
105 keysMap.put( "SYSTEM_ID" , "リソースを使??合に、コードリソースの作?シス?IDを指? );
106 keysMap.put( "LANG" , "リソースを使??合に、ラベルリソースの?を?? );
107 keysMap.put( "RENDERER" , "設定するカラ?" );
108 keysMap.put( "EDITOR" , "設定するカラ?" );
109 keysMap.put( "DBTYPE" , "設定するカラ?" );
110 keysMap.put( "BIKO" , "設定するカラ?" );
111 keysMap.put( "CLS_NAME" , "設定するカラ?" );
112 keysMap.put( "USE_LENGTH" , "設定するカラ?" );
113 }
114
115 /**
116 * DBTableModel処?実行します?
117 *
118 * @og.rev 5.5.2.6 (2012/05/25) protected変数を?private化したため?getterメソ?で取得するよ?変更
119 * @og.rev 5.5.7.4 (2012/10/25) 備???処??、ここでは行いません?
120 * @og.rev 5.5.8.2 (2012/11/09) RENDERER,EDITOR,DBTYPE の条件?を変更します?
121 * @og.rev 5.5.8.5 (2012/11/27) USE_RESOURCE 引数追?
122 *
123 * @return 処?果のDBTableModel
124 */
125 public DBTableModel execute() {
126 DBTableModel table = getDBTableModel(); // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
127
128 boolean useResource = StringUtil.nval( getValue("USE_RESOURCE"), true ); // 5.5.8.5 (2012/11/27) USE_RESOURCE 引数追?
129
130 // 5.5.8.5 (2012/11/27) 初期化タイミングを遅らします?
131 // String systemId = getValue( "SYSTEM_ID" );
132 // String lang = getValue( "LANG" );
133 // ResourceManager resource = ResourceFactory.newInstance( systemId,lang,false );
134 ResourceManager resource = null;
135
136 if( useResource ) {
137 String systemId = getValue( "SYSTEM_ID" );
138 String lang = getValue( "LANG" );
139 resource = ResourceFactory.newInstance( systemId,lang,false );
140 }
141
142 int clmNo = table.getColumnNo( "CLM",false ); // 存在しな??合??1 を返す?
143 int renNo = table.getColumnNo( "RENDERER",false );
144 int ediNo = table.getColumnNo( "EDITOR",false );
145 int typNo = table.getColumnNo( "DBTYPE",false );
146 int bikoNo = table.getColumnNo( "BIKO",false );
147
148 int clsNo = table.getColumnNo( "CLS_NAME",false ); // 5.5.7.4 (2012/10/25) CLS_NAME カラ?号の取?
149 int lenNo = table.getColumnNo( "USE_LENGTH",false ); // 5.5.7.4 (2012/10/25) USE_LENGTH カラ?号の取?
150
151 // if( clmNo >= 0 && renNo >= 0 && ediNo >= 0 && typNo >= 0 && bikoNo >= 0 ) { // 5.5.7.4 (2012/10/25) BIKO の設定?、??から外す
152 if( clmNo >= 0 && renNo >= 0 && ediNo >= 0 && typNo >= 0 ) {
153 String[] data = null;
154 int rowCnt = table.getRowCount();
155 DBColumn column = null ;
156 // CodeData code ;
157 for( int row=0; row<rowCnt; row++ ) {
158 String clmVal = null;
159 try {
160 data = table.getValues( row );
161 clmVal = data[clmNo].trim().toUpperCase(Locale.JAPAN); // 変換する??カラ?
162 // 5.5.8.5 (2012/11/27) USE_RESOURCE 引数追??
163 if( useResource ) {
164 column = resource.getDBColumn( clmVal );
165 }
166 // 以下?設定?、副作用を及ぼして?す?注?
167 if( column != null ) {
168 data[renNo] = column.getRenderer() ;
169 data[ediNo] = column.getEditor() ;
170 data[typNo] = column.getDbType() ;
171
172 // 5.5.7.4 (2012/10/25) BIKO の設定?、検索時にカラ?あり、MENUレン?ーで、備?NULLの場合?み再設定する?
173 if( bikoNo >= 0 && "MENU".equalsIgnoreCase( data[renNo] ) && ( data[bikoNo] == null || data[bikoNo].isEmpty() ) ) {
174 CodeData code = resource.getCodeData( clmVal );
175 if( code != null ) {
176 data[bikoNo] = code.toCodeString() ;
177 }
178 }
179
180 // 本当?、RENDERER='MENU' の場合?み有効?
181 // code = resource.getCodeData( clmVal );
182 // if( code != null ) {
183 // data[bikoNo] = code.toCodeString() ;
184 // }
185 // // オブジェクトが存在しな??合?、クリアします?
186 // else {
187 // data[bikoNo] = "";
188 // }
189 }
190 // 5.5.7.4 (2012/10/25) オブジェクトが存在しな??合?、?動的に類似の??を設定します?
191 // else {
192 // data[renNo] = "";
193 // data[ediNo] = "";
194 // data[typNo] = "";
195 // data[bikoNo] = "";
196 // if( clsNo >= 0 && data[clsNo] != null ) {
197 // if( "NUMBER".equalsIgnoreCase( data[clsNo] ) ) {
198 // data[renNo] = "NUMBER";
199 // data[ediNo] = "TEXT";
200 // data[typNo] = "S9";
201 // }
202 // else if( data[clsNo].startsWith( "VARCHAR" ) ) {
203 // data[renNo] = "LABEL";
204 // data[ediNo] = "TEXT";
205 // data[typNo] = "X";
206 // if( lenNo >= 0 && data[lenNo] != null && data[lenNo].length() >= 2 ) {
207 // if( Integer.parseInt( data[lenNo] ) >= 30 ) {
208 // data[typNo] = "KX"; // 30ケタ以上?場合?、KX とする?
209 // }
210 // }
211 // }
212 // }
213 // }
214 // 5.5.8.2 (2012/11/09) RENDERER,EDITOR,DBTYPE の条件?を変更します?
215 else {
216 String clsVal = (clsNo < 0 || data[clsNo] == null ) ? "" : data[clsNo].trim().toUpperCase(Locale.JAPAN);
217 String lenVal = (lenNo < 0 || data[lenNo] == null ) ? "" : data[lenNo].trim().replace( '.',',' ) ;
218 String bikoVal = (bikoNo < 0 || data[bikoNo] == null ) ? "" : data[bikoNo];
219
220 // 長さで、小数部が? 0 の場合?、整数のみと判断する?
221 int cm = lenVal.indexOf( ",0" );
222 if( cm >= 0 ) { lenVal = lenVal.substring( 0,cm ); }
223
224 String[] selData = serchMasterData( clmVal,clsVal,lenVal,bikoVal );
225
226 // 副作用を及ぼします?
227 data[renNo] = selData[NO_REN];
228 data[ediNo] = selData[NO_EDI];
229 data[typNo] = selData[NO_TYP];
230
231 if( lenVal.contains( "," ) ) { data[lenNo] = lenVal ; } // "," が含まれて?場合?、?設?
232 }
233 }
234 catch( RuntimeException ex ) {
235 ErrorMessage errMessage = makeErrorMessage( "TableFilter_CLMSET Error",ErrorMessage.NG );
236 errMessage.addMessage( row+1,ErrorMessage.NG,ex.getMessage() );
237 errMessage.addMessage( row+1,ErrorMessage.NG,StringUtil.array2csv( data ) );
238 errMessage.addMessage( row+1,ErrorMessage.NG,"CLM=[" + clmVal + "]" );
239 }
240 }
241 }
242
243 return table;
244 }
245
246 /**
247 * RENDERER,EDITOR,DBTYPE の条件?を?マスター??タレコードから見つけて、対応するレコード?配?を返します??
248 *
249 * これは、?スタ??タは??番に評価して?、最初に成立した?をセ?します?
250 * マスタ??タは、clm,cls,len,biko につ?条件設定しておき、条件が?立するかど?判断hし?成立するレコードを
251 * 返すことで、そのレコードに該当する?RENDERER,EDITOR,DBTYPE の値を返します?
252 * これで、ある程度?な条件判定が可能になります?
253 * マスタ??タの null は、条件に含めな?無条件成立)を意味します?
254 *
255 * @og.rev 5.5.8.2 (2012/11/09) 新規追?
256 *
257 * @param clmVal カラ?ータ(not null保障 , 大?保障)
258 * @param clsVal クラス??タ(not null保障 , 大?保障)
259 * @param lenVal 長さデータ(not null , カンマ保障)
260 * @param bikoVal 備???タ(not null保障)
261 * @return レコード?配?
262 */
263 private String[] serchMasterData( final String clmVal,final String clsVal,final String lenVal,final String bikoVal ) {
264 String lenVal2 = ( lenVal.contains( "," ) ) ? "," : lenVal ; // 少数を含??合??," を?そうでな??合?、そのまま返す?
265
266 int size = MASTER_DATA.length;
267 for( int i=0; i<size; i++ ) {
268 String[] rowData = MASTER_DATA[i];
269 if( ( rowData[NO_CLM] == null || clmVal.startsWith( rowData[NO_CLM] ) ) &&
270 ( rowData[NO_CLS] == null || clsVal.startsWith( rowData[NO_CLS] ) ) &&
271 ( rowData[NO_LEN1] == null || rowData[NO_LEN1].equalsIgnoreCase( lenVal2 ) ) &&
272 ( rowData[NO_LEN2] == null || Integer.parseInt( lenVal ) >= Integer.parseInt( rowData[NO_LEN2] ) ) &&
273 ( rowData[NO_BIKO] == null || bikoVal.contains( rowData[NO_BIKO] ) ) ) {
274 return rowData ;
275 }
276 }
277
278 return MASTER_DATA[size-1] ; // MASTER_DATA の?レコードでマッチする?で、来な???
279 }
280
281 // 5.5.8.2 (2012/11/09) RENDERER,EDITOR,DBTYPE の条件?を変更します?
282 // 処??、上から?番に判定して?ます?で、ご注意く???
283 //* RENDERER,EDITOR,DBTYPE の条件?の マスター??タレコー?を設定します? {@value} */
284 private static final String[][] MASTER_DATA = new String[][] {
285 // clm , cls , =len , >=len , biko , renderer , editor , dbtype
286 { "DY" , null , "4" , null , null , "MD" , "TEXT" , "X" } , // 日付文字?(時?)
287 { "DY" , null , "6" , null , null , "YM" , "YM" , "YM" } , // 日付文字?(年日)
288 { "DY" , null , "8" , null , null , "YMD" , "YMD" , "YMD" } , // 日付文字?(年月日)
289 { "DY" , null , "14" , null , null , "YMDH" , "YMDH" , "YMDH" } , // 日付文字?(年月日時??
290 { "TM" , null , "4" , null , null , "HM" , "TEXT" , "HM" } , // 時間??(時?)
291 { "TM" , null , "6" , null , null , "HMS" , "TEXT" , "HMS" } , // 時間??(時??
292 { "CD" , null , null , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース
293 { "FG" , null , null , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース
294 { "KB" , null , null , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース
295 { null , "NU" , "1" , null , ":" , "MENU" , "MENU" , "S9" } , // NUMBER(整数)
296 { null , "IN" , "1" , null , ":" , "MENU" , "MENU" , "S9" } , // INTEGER , INT64
297 { null , null , "1" , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース
298 { null , "VA" , null , "30" , null , "LABEL" , "TEXT" , "KX" } , // VARCHAR , VARCHAR2(30桁以上?漢?
299 { null , "VA" , null , null , null , "LABEL" , "TEXT" , "X" } , // VARCHAR , VARCHAR2(30桁以下?英数?
300 { null , "NU" , "," , null , null , "NUMBER" , "NUMBER" , "R" } , // NUMBER(少数)
301 { null , "NU" , null , null , null , "NUMBER" , "NUMBER" , "S9" } , // NUMBER(整数)
302 { null , "IN" , null , null , null , "NUMBER" , "NUMBER" , "S9" } , // INTEGER , INT64
303 { null , "DE" , null , null , null , "NUMBER" , "NUMBER" , "R" } , // DECIMAL
304 { null , "TI" , "8" , null , null , "YMD" , "YMD" , "YMD" } , // TIMESTAMP(8?
305 { null , "TI" , "14" , null , null , "YMDH" , "YMDH" , "YMDH" } , // TIMESTAMP(14?
306 { null , "TI" , null , null , null , "DATE" , "YMDH" , "DATE" } , // TIMESTAMP
307 { null , "DA" , "8" , null , null , "DATE" , "YMD" , "DATE" } , // DATE(8?
308 { null , "DA" , null , null , null , "DATE" , "YMDH" , "DATE" } , // DATE
309 { null , "CH" , null , null , null , "LABEL" , "TEXT" , "X" } , // CHAR
310 { null , "CL" , null , null , null , "LABEL" , "TEXT" , "KX" } , // CLOB
311 { null , null , null , null , null , "LABEL" , "TEXT" , "X" } // そ??
312 } ;
313
314 private static final int NO_CLM = 0;
315 private static final int NO_CLS = 1;
316 private static final int NO_LEN1 = 2;
317 private static final int NO_LEN2 = 3;
318 private static final int NO_BIKO = 4;
319 private static final int NO_REN = 5;
320 private static final int NO_EDI = 6;
321 private static final int NO_TYP = 7;
322 }