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    }