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.table; 017 018import org.opengion.hayabusa.db.AbstractTableFilter; 019import org.opengion.hayabusa.db.DBTableModel; 020import org.opengion.hayabusa.db.DBColumn; 021 022import org.opengion.hayabusa.resource.ResourceFactory; 023import org.opengion.hayabusa.resource.ResourceManager; 024import org.opengion.hayabusa.resource.CodeData; 025 026import org.opengion.fukurou.util.ErrorMessage; 027import org.opengion.fukurou.util.StringUtil; 028 029import java.util.Locale; 030import 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 */ 090public class TableFilter_CLMSET extends AbstractTableFilter { 091 //* このプログラムのVERSION文字列を設定します。 {@value} */ 092 private static final String VERSION = "5.6.6.1 (2013/07/12)" ; 093 094 private static final int NO_CLM = 0; 095 private static final int NO_CLS = 1; 096 private static final int NO_LEN1 = 2; 097 private static final int NO_LEN2 = 3; 098 private static final int NO_BIKO = 4; 099 private static final int NO_REN = 5; 100 private static final int NO_EDI = 6; 101 private static final int NO_TYP = 7; 102 103 // 5.5.8.2 (2012/11/09) RENDERER,EDITOR,DBTYPE の条件分けを変更します。 104 // 処理は、上から順番に判定していきますので、ご注意ください。 105 //* RENDERER,EDITOR,DBTYPE の条件分けの マスターデータレコード を設定します。 {@value} */ 106 private static final String[][] MASTER_DATA = new String[][] { 107 // clm , cls , =len , >=len , biko , renderer , editor , dbtype 108 { "DY" , null , "4" , null , null , "MD" , "TEXT" , "X" } , // 日付文字列(時分) 109 { "DY" , null , "6" , null , null , "YM" , "YM" , "YM" } , // 日付文字列(年日) 110 { "DY" , null , "8" , null , null , "YMD" , "YMD" , "YMD" } , // 日付文字列(年月日) 111 { "DY" , null , "14" , null , null , "YMDH" , "YMDH" , "YMDH" } , // 日付文字列(年月日時分秒) 112 { "TM" , null , "4" , null , null , "HM" , "TEXT" , "HM" } , // 時間文字列(時分) 113 { "TM" , null , "6" , null , null , "HMS" , "TEXT" , "HMS" } , // 時間文字列(時分秒) 114 { "CD" , null , null , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース 115 { "FG" , null , null , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース 116 { "KB" , null , null , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース 117 { null , "NU" , "1" , null , ":" , "MENU" , "MENU" , "S9" } , // NUMBER(整数) 118 { null , "IN" , "1" , null , ":" , "MENU" , "MENU" , "S9" } , // INTEGER , INT64 119 { null , null , "1" , null , ":" , "MENU" , "MENU" , "X" } , // CODEリソース 120 { null , "VA" , null , "30" , null , "LABEL" , "TEXT" , "KX" } , // VARCHAR , VARCHAR2(30桁以上は漢字) 121 { null , "VA" , null , null , null , "LABEL" , "TEXT" , "X" } , // VARCHAR , VARCHAR2(30桁以下は英数字) 122 { null , "NU" , "," , null , null , "NUMBER" , "NUMBER" , "R" } , // NUMBER(少数) 123 { null , "NU" , null , null , null , "NUMBER" , "NUMBER" , "S9" } , // NUMBER(整数) 124 { null , "IN" , null , null , null , "NUMBER" , "NUMBER" , "S9" } , // INTEGER , INT64 125 { null , "DE" , null , null , null , "NUMBER" , "NUMBER" , "R" } , // DECIMAL 126 { null , "TI" , "8" , null , null , "YMD" , "YMD" , "YMD" } , // TIMESTAMP(8桁) 127 { null , "TI" , "14" , null , null , "YMDH" , "YMDH" , "YMDH" } , // TIMESTAMP(14桁) 128 { null , "TI" , null , null , null , "DATE" , "YMDH" , "DATE" } , // TIMESTAMP 129 { null , "DA" , "8" , null , null , "DATE" , "YMD" , "DATE" } , // DATE(8桁) 130 { null , "DA" , null , null , null , "DATE" , "YMDH" , "DATE" } , // DATE 131 { null , "CH" , null , null , null , "LABEL" , "TEXT" , "X" } , // CHAR 132 { null , "CL" , null , null , null , "LABEL" , "TEXT" , "KX" } , // CLOB 133 { null , null , null , null , null , "LABEL" , "TEXT" , "X" } // その他 134 } ; 135 136 /** 137 * keys の整合性チェックを行うための初期設定を行います。 138 * 139 * @og.rev 5.6.6.1 (2013/07/12) keys の整合性チェック対応 140 * 141 * @param keysMap keys の整合性チェックを行うための Map 142 */ 143 @Override 144 protected void init( final Map<String,String> keysMap ) { 145 keysMap.put( "USE_RESOURCE" , "リソースを利用するかどうかを指定[true/false](初期値:true)" ); 146 keysMap.put( "CLM" , "カラムリソースのキーとなる値が設定されているカラム名を指定" ); 147 keysMap.put( "SYSTEM_ID" , "リソースを使う場合に、コードリソースの作成システムIDを指定" ); 148 keysMap.put( "LANG" , "リソースを使う場合に、ラベルリソースの言語を指定" ); 149 keysMap.put( "RENDERER" , "設定するカラム名" ); 150 keysMap.put( "EDITOR" , "設定するカラム名" ); 151 keysMap.put( "DBTYPE" , "設定するカラム名" ); 152 keysMap.put( "BIKO" , "設定するカラム名" ); 153 keysMap.put( "CLS_NAME" , "設定するカラム名" ); 154 keysMap.put( "USE_LENGTH" , "設定するカラム名" ); 155 } 156 157 /** 158 * DBTableModel処理を実行します。 159 * 160 * @og.rev 5.5.2.6 (2012/05/25) protected変数を、private化したため、getterメソッドで取得するように変更 161 * @og.rev 5.5.7.4 (2012/10/25) 備考欄の処理は、ここでは行いません。 162 * @og.rev 5.5.8.2 (2012/11/09) RENDERER,EDITOR,DBTYPE の条件分けを変更します。 163 * @og.rev 5.5.8.5 (2012/11/27) USE_RESOURCE 引数追加 164 * 165 * @return 処理結果のDBTableModel 166 */ 167 public DBTableModel execute() { 168 DBTableModel table = getDBTableModel(); // 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加 169 170 boolean useResource = StringUtil.nval( getValue("USE_RESOURCE"), true ); // 5.5.8.5 (2012/11/27) USE_RESOURCE 引数追加 171 172 // 5.5.8.5 (2012/11/27) 初期化タイミングを遅らします。 173 ResourceManager resource = null; 174 175 if( useResource ) { 176 String systemId = getValue( "SYSTEM_ID" ); 177 String lang = getValue( "LANG" ); 178 resource = ResourceFactory.newInstance( systemId,lang,false ); 179 } 180 181 int clmNo = table.getColumnNo( "CLM",false ); // 存在しない場合は、-1 を返す。 182 int renNo = table.getColumnNo( "RENDERER",false ); 183 int ediNo = table.getColumnNo( "EDITOR",false ); 184 int typNo = table.getColumnNo( "DBTYPE",false ); 185 int bikoNo = table.getColumnNo( "BIKO",false ); 186 187 int clsNo = table.getColumnNo( "CLS_NAME",false ); // 5.5.7.4 (2012/10/25) CLS_NAME カラム番号の取得 188 int lenNo = table.getColumnNo( "USE_LENGTH",false ); // 5.5.7.4 (2012/10/25) USE_LENGTH カラム番号の取得 189 190 if( clmNo >= 0 && renNo >= 0 && ediNo >= 0 && typNo >= 0 ) { 191 String[] data = null; 192 int rowCnt = table.getRowCount(); 193 DBColumn column = null ; 194 for( int row=0; row<rowCnt; row++ ) { 195 String clmVal = null; 196 try { 197 data = table.getValues( row ); 198 clmVal = data[clmNo].trim().toUpperCase(Locale.JAPAN); // 変換する元のカラム名 199 // 5.5.8.5 (2012/11/27) USE_RESOURCE 引数追加。 200 if( useResource ) { 201 column = resource.getDBColumn( clmVal ); 202 } 203 // 以下の設定は、副作用を及ぼしています。注意 204 if( column != null ) { 205 data[renNo] = column.getRenderer() ; 206 data[ediNo] = column.getEditor() ; 207 data[typNo] = column.getDbType() ; 208 209 // 5.5.7.4 (2012/10/25) BIKO の設定は、検索時にカラムがあり、MENUレンデラーで、備考がNULLの場合のみ再設定する。 210 if( bikoNo >= 0 && "MENU".equalsIgnoreCase( data[renNo] ) && ( data[bikoNo] == null || data[bikoNo].isEmpty() ) ) { 211 CodeData code = resource.getCodeData( clmVal ); 212 if( code != null ) { 213 data[bikoNo] = code.toCodeString() ; 214 } 215 } 216 } 217 // 5.5.8.2 (2012/11/09) RENDERER,EDITOR,DBTYPE の条件分けを変更します。 218 else { 219 String clsVal = (clsNo < 0 || data[clsNo] == null ) ? "" : data[clsNo].trim().toUpperCase(Locale.JAPAN); 220 String lenVal = (lenNo < 0 || data[lenNo] == null ) ? "" : data[lenNo].trim().replace( '.',',' ) ; 221 String bikoVal = (bikoNo < 0 || data[bikoNo] == null ) ? "" : data[bikoNo]; 222 223 // 長さで、小数部が、 0 の場合は、整数のみと判断する。 224 int cm = lenVal.indexOf( ",0" ); 225 if( cm >= 0 ) { lenVal = lenVal.substring( 0,cm ); } 226 227 String[] selData = serchMasterData( clmVal,clsVal,lenVal,bikoVal ); 228 229 // 副作用を及ぼします。 230 data[renNo] = selData[NO_REN]; 231 data[ediNo] = selData[NO_EDI]; 232 data[typNo] = selData[NO_TYP]; 233 234 if( lenVal.contains( "," ) ) { data[lenNo] = lenVal ; } // "," が含まれている場合は、再設定 235 } 236 } 237 catch( RuntimeException ex ) { 238 ErrorMessage errMessage = makeErrorMessage( "TableFilter_CLMSET Error",ErrorMessage.NG ); 239 errMessage.addMessage( row+1,ErrorMessage.NG,ex.getMessage() ); 240 errMessage.addMessage( row+1,ErrorMessage.NG,StringUtil.array2csv( data ) ); 241 errMessage.addMessage( row+1,ErrorMessage.NG,"CLM=[" + clmVal + "]" ); 242 } 243 } 244 } 245 246 return table; 247 } 248 249 /** 250 * RENDERER,EDITOR,DBTYPE の条件分けを、マスターデータレコードから見つけて、対応するレコードの配列を返します。。 251 * 252 * これは、マスタデータは、順番に評価していき、最初に成立した値をセットします。 253 * マスタデータは、clm,cls,len,biko について条件設定しておき、条件が成立するかどうか判断hし、成立するレコードを 254 * 返すことで、そのレコードに該当する、RENDERER,EDITOR,DBTYPE の値を返します。 255 * これで、ある程度複雑な条件判定が可能になります。 256 * マスタデータの null は、条件に含めない(無条件成立)を意味します。 257 * 258 * @og.rev 5.5.8.2 (2012/11/09) 新規追加 259 * 260 * @param clmVal カラムデータ(not null保障 , 大文字保障) 261 * @param clsVal クラスデータ(not null保障 , 大文字保障) 262 * @param lenVal 長さデータ(not null , カンマ保障) 263 * @param bikoVal 備考データ(not null保障) 264 * @return レコードの配列 265 */ 266 private String[] serchMasterData( final String clmVal,final String clsVal,final String lenVal,final String bikoVal ) { 267 String lenVal2 = lenVal.contains( "," ) ? "," : lenVal ; // 少数を含む場合は、"," を、そうでない場合は、そのまま返す。 268 269 int size = MASTER_DATA.length; 270 for( int i=0; i<size; i++ ) { 271 String[] rowData = MASTER_DATA[i]; 272 if( ( rowData[NO_CLM] == null || clmVal.startsWith( rowData[NO_CLM] ) ) && 273 ( rowData[NO_CLS] == null || clsVal.startsWith( rowData[NO_CLS] ) ) && 274 ( rowData[NO_LEN1] == null || rowData[NO_LEN1].equalsIgnoreCase( lenVal2 ) ) && 275 ( rowData[NO_LEN2] == null || Integer.parseInt( lenVal ) >= Integer.parseInt( rowData[NO_LEN2] ) ) && 276 ( rowData[NO_BIKO] == null || bikoVal.contains( rowData[NO_BIKO] ) ) ) { 277 return rowData ; 278 } 279 } 280 281 return MASTER_DATA[size-1] ; // MASTER_DATA の最終レコードでマッチするので、来ないはず 282 } 283}