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    
021    import org.opengion.fukurou.util.ErrorMessage;
022    import org.opengion.fukurou.util.StringUtil;
023    
024    import java.util.Locale;
025    import java.util.Map;
026    
027    /**
028     * TableFilter_DTYPE は、TableFilter インターフェースを継承した、DBTableModel 処?の
029     * 実?ラスです?
030     *
031     * ここでは、キーの CLS_NAME,USE_LENGTH より、DTYPE の値を設定します?
032     *  CLS_NAME は、VARCHAR2, NUMBER などのカラ??属?を表します?
033     *  USE_LENGTH は??使用桁数)です?
034     *  DTYPE は、X(10) ?? S9(8) などの簡易型カラ??です?
035     * エンジンを使用したシス?では、この属?より、さらに詳細にカラ?定義する?
036     * DBTYPE 属?が?あります???は、この定義を使用するように?替えて?予定です?
037     *
038     * CLS_NAME,USE_LENGTH,DTYPE の カラ?につ?は、?期?はこ?ままですが?
039     * keys , vals に?すれ?、別名につ?も使用することが可能です?
040     *
041     * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか?BODY 部にCSS形式で記述します?
042     * 【パラメータ?
043     *  {
044     *       CLS_NAME   : CLS_NAME   ;    VARCHAR2, NUMBER などのカラ??を指定するカラ?を指定します?(初期値:CLS_NAME)
045     *       USE_LENGTH : USE_LENGTH ;    長?使用桁数)を表すカラ?を指定します?                 (初期値:USE_LENGTH)
046     *       DTYPE      : DTYPE      ;    X,R,S9,R,D,CLOB など、エンジンを使用したシス?で規定した詳細定義(初期値:DTYPE)
047     *  }
048     *
049     * @og.formSample
050     * ●形式?
051     *      ?<og:tableFilter classId="DTYPE" keys="CLS_NAME,USE_LENGTH,DTYPE" vals='"TABLE_NAME,CLM"' />
052     *
053     *      ② <og:tableFilter classId="DTYPE" >
054     *               {
055     *                   CLS_NAME   : CLS_NAME   ;
056     *                   USE_LENGTH : USE_LENGTH ;
057     *                   DTYPE      : DTYPE      ;
058     *               }
059     *         </og:tableFilter>
060     *
061     * @og.rev 5.6.6.0 (2013/07/05) keys の整合?チェ?を追?
062     *
063     * @version  0.9.0  2000/10/17
064     * @author   Kazuhiko Hasegawa
065     * @since    JDK1.5,
066     */
067    public class TableFilter_DTYPE extends AbstractTableFilter {
068            //* こ?プログラ??VERSION??を設定します?       {@value} */
069            private static final String VERSION = "5.6.6.1 (2013/07/12)" ;
070    
071            /**
072             * keys の整合?チェ?を行うための初期設定を行います?
073             *
074             * @og.rev 5.6.6.1 (2013/07/12) keys の整合?チェ?対?
075             *
076             * @param       keysMap keys の整合?チェ?を行うための Map
077             */
078            @Override
079            protected void init( final Map<String,String> keysMap ) {
080                    keysMap.put( "CLS_NAME"         , "VARCHAR2, NUMBER などのカラ??を指定するカラ?を指?初期値:CLS_NAME)"                                          );
081                    keysMap.put( "USE_LENGTH"       , "長?使用桁数)を表すカラ?を指?(初期値:USE_LENGTH)"     );
082                    keysMap.put( "DTYPE"            , "X,R,S9,R,D,CLOB など、エンジンを使用したシス?で規定した詳細定義(初期値:DTYPE)" );
083            }
084    
085            /**
086             * DBTableModel処?実行します?
087             *
088             * @og.rev 5.5.2.6 (2012/05/25) protected変数を?private化したため?getterメソ?で取得するよ?変更
089             * @og.rev 5.5.8.2 (2012/11/09) X,S9 の条件?を変更します?(MICS対?
090             *
091             * @return 処?果のDBTableModel
092             */
093            public DBTableModel execute() {
094                    DBTableModel table = getDBTableModel();         // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
095    
096                    String cls = StringUtil.nval( getValue( "CLS_NAME" )    ,"CLS_NAME" );
097                    String len = StringUtil.nval( getValue( "USE_LENGTH" )  ,"USE_LENGTH" );
098                    String typ = StringUtil.nval( getValue( "DTYPE" )               ,"DTYPE" );
099    
100                    int clsNo  = table.getColumnNo( cls,false );    // 存在しな??合??1 を返す?
101                    int lenNo  = table.getColumnNo( len,false );
102                    int typNo  = table.getColumnNo( typ,false );
103    
104                    if( clsNo >= 0 && lenNo >= 0 && typNo >= 0 ) {
105                            String[] data  = null;
106                            int rowCnt = table.getRowCount();
107                            String clsVal = null;
108                            String lenVal = null;
109                            for( int row=0; row<rowCnt; row++ ) {
110                                    try {
111                                            data   = table.getValues( row );
112                                            clsVal = ( data[clsNo] == null ) ? "" : data[clsNo].trim().toUpperCase(Locale.JAPAN) ;  // CLS_NAME(VARCHAR,NUMBER など)
113                                            lenVal = ( data[lenNo] == null ) ? "" : data[lenNo].trim().replace( '.',',' ) ;                 // USE_LENGTH(使用桁数)
114    
115                                            // 長さで、小数部が? 0 の場合?、整数のみと判断する?
116                                            int cm = lenVal.indexOf( ",0" );
117                                            if( cm >= 0 ) { lenVal = lenVal.substring( 0,cm ); }
118    
119                                            // 5.5.8.2 (2012/11/09) X,S9 の条件?を変更します?(MICS対?
120                                            String typVal = makeDTYPE( clsVal ,lenVal ) ;
121                                            data[typNo] = typVal;
122    
123                                            if( lenVal.contains( "," ) ) { data[lenNo] = lenVal ; }         // "," が含まれて?場合?、?再設?
124    
125            //                              table.setValueAt( typVal,row,typNo );
126    
127    //                                      StringBuilder typVal = new StringBuilder();
128    //                                      // 5.5.8.2 (2012/11/09) X,S9 の条件?を変更します?
129    //                                      String clsVal2 = clsVal.substring(0,2);                                         // 先??文字で判定します?
130    //                                      // NUMBER , INTEGER , INT64 , DECIMAL
131    //                                      if( "NU".equalsIgnoreCase( clsVal2 ) || "IN".equalsIgnoreCase( clsVal2 ) || "DE".equalsIgnoreCase( clsVal2 ) ) {
132    //                                              typVal.append( "S9(" );
133    //                                      }
134    //                                      // TIMESTAMP , DATE
135    //                                      else if( "TI".equalsIgnoreCase( clsVal2 ) || "DA".equalsIgnoreCase( clsVal2 ) ) {
136    //                                              typVal.append( "T(" );
137    //                                      }
138    //                                      // VARCHAR , VARCHAR2 , CHAR , CLOB
139    //                      //              else if( "VA".equalsIgnoreCase( clsVal2 ) || "CH".equalsIgnoreCase( clsVal2 ) || "CL".equalsIgnoreCase( clsVal2 ) ) {
140    //                      //                      typVal.append( "X(" );
141    //                      //              }
142    //                                      else {
143    //                                              typVal.append( "X(" );
144    //                                      }
145    //
146    ////                                    if( "NUMBER".equalsIgnoreCase( clsVal ) ) {
147    ////                                            typVal.append( "S9(" );
148    ////                                    }
149    ////                                    else {
150    ////                                            typVal.append( "X(" );
151    ////                                    }
152    //
153    //                                      int cm = lenVal.indexOf( ".0" );
154    //                                      if( cm > 0 ) {
155    //                                              typVal.append( lenVal.substring( 0,cm ) );
156    //                                      }
157    //                                      else {
158    //                                              typVal.append( lenVal );
159    //                                      }
160    //                                      typVal.append( ')' );
161    //
162    //                                      table.setValueAt( typVal.toString(),row,typNo );
163                                    }
164                                    catch( RuntimeException ex ) {
165                                            ErrorMessage errMessage = makeErrorMessage( "TableFilter_DTYPE Error",ErrorMessage.NG );
166                                            errMessage.addMessage( row+1,ErrorMessage.NG,ex.getMessage() );
167                                            errMessage.addMessage( row+1,ErrorMessage.NG,StringUtil.array2csv( data ) );
168                                            errMessage.addMessage( row+1,ErrorMessage.NG,"CLS=[" + clsVal + "],LEN=[" + lenVal + "]" );
169                                    }
170                            }
171                    }
172    
173                    return table;
174            }
175    
176            /**
177             * クラス,長さデータ から、DTYPE ??を作?します?
178             *
179             * if????から、?スタ??タを利用した条件判定方式で判定します?
180             * また?以前から?、S9:数?と?X:???ではなく?R:少数、D:日時?CLOB:?ス?を追?ます?
181             * 桁数未設定?場合??桁数) を使用せず、記号?になります?
182             *
183             * @og.rev 5.5.8.2 (2012/11/09) 新規追?
184             *
185             * @param  clsVal クラス??タ(not null保障 , 大?保障)
186             * @param  lenVal 長さデータ(not null , カンマ保障)
187             * @return 対応す?DTYPE ??
188             */
189            private String makeDTYPE( final String clsVal,final String lenVal ) {
190                    StringBuilder typVal = new StringBuilder();
191    
192                    int size = MASTER_DATA.length;
193                    for( int i=0; i<size; i++ ) {
194                            String clsMstr = MASTER_DATA[i][NO_CLS];
195                            String lenMstr = MASTER_DATA[i][NO_LEN];
196    
197                            if( ( clsMstr  == null || clsVal.startsWith( clsMstr ) ) &&
198                                    ( lenMstr  == null || lenVal.contains(   lenMstr ) ) ) {
199                                    typVal.append( MASTER_DATA[i][NO_TYP] );
200                                    break ;
201                            }
202                    }
203                    if( typVal.length() == 0 ) { typVal.append( MASTER_DATA[size-1][NO_TYP] ); }            // MASTER_DATA の?レコードでマッチする?で、来な???
204    
205                    if( ! lenVal.isEmpty() ) {              // 長さが存在する場合??xx)の数字部?記述する。これが通常のケース
206                            typVal.append( "(" ).append( lenVal ).append( ")" );
207                    }
208    
209                    return typVal.toString();
210            }
211    
212            // 5.5.8.2 (2012/11/09) DTYPE の条件?を変更します?
213            //* DTYPE の条件?の マスター??タレコー?を設定します?  {@value} */
214            private static final String[][] MASTER_DATA = new String[][] {
215            //    cls       , len   , dbtype
216                    { "VA"  , null  , "X"           } ,             // VARCHAR , VARCHAR2
217                    { "NU"  , ","   , "R"           } ,             // NUMBER(少数)
218                    { "NU"  , null  , "S9"          } ,             // NUMBER(整数)
219                    { "IN"  , null  , "S9"          } ,             // INTEGER , INT64
220                    { "DE"  , null  , "R"           } ,             // DECIMAL
221                    { "TI"  , null  , "D"           } ,             // TIMESTAMP
222                    { "DA"  , null  , "D"           } ,             // DATE
223                    { "CL"  , null  , "CLOB"        } ,             // CLOB
224                    { null  , null  , "X"           }               // そ??CHAR , LONG ?
225            } ;
226    
227            private static final int NO_CLS  = 0;
228            private static final int NO_LEN  = 1;
229            private static final int NO_TYP  = 2;
230    }