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.common.HybsSystemException;
019    import org.opengion.hayabusa.db.AbstractTableFilter;
020    import org.opengion.hayabusa.db.DBColumn;
021    import org.opengion.hayabusa.db.DBTableModel;
022    
023    import org.opengion.hayabusa.resource.ResourceFactory;
024    import org.opengion.hayabusa.resource.ResourceManager;
025    
026    import org.opengion.fukurou.util.ErrorMessage;
027    import org.opengion.fukurou.util.StringUtil;
028    import java.util.regex.Pattern;
029    import java.util.regex.Matcher;
030    import java.util.Locale;
031    import java.util.Map;
032    
033    /**
034     * TableFilter_DBARG は、TableFilter インターフェースを継承した、DBTableModel 処?の
035     * 実?ラスです?
036     *
037     * ここでは、テキストから?オブジェクト名、カラ?、クラス、利用桁数を?り?します?
038     *
039     * ソースの?スト部は?,NAME_JA VARCHAR2(100) " と?形式??ストになって?す?
040     * これを?カラ?、クラス名部、使用桁数部に?します?上記?例では?
041     * それぞれを?NAME_JA、VARCHAR2?00 に?して、文字?配?に格納します?
042     * また?これら?ソースに?--" ?"/ * ??? * /" などのコメントが含まれるケース?
043     * あります?"--" コメント?、それ以降を無視しますが?/ *" コメント?、?行に
044     * またがる為、今回は処?象から外します?
045     * ソースの?スト部には、それら以外に、OBJECT_NAME に相当する行や?);" などの
046     * ソースの???後?無効な部?あります?無効な部??、null を返すことで
047     * 登録処?ら省?ください?
048     *
049     * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか?BODY 部にCSS形式で記述します?
050     * 【パラメータ?
051     *  {
052     *       TEXT       : 処?おこな??ソースの?スト部のカラ?
053     *       OBJ_NAME   : キーとなるオブジェクト名のカラ?
054     *       SEQNO      : ソースの行番号のカラ?
055     *       CLM        : 処?果のカラ?を?納するカラ?
056     *       CLS_NAME   : 処?果のクラス名を格納するカラ?
057     *       USE_LENGTH : 処?果の利用桁数を?納するカラ?
058     *       CLM_NAME   : 処?果のカラ?称?ラベル?を格納するカラ?
059     *       MAX_LENGTH : 処?果の桁数を?納するカラ?
060     *  }
061     *
062     * @og.formSample
063     * ●形式?
064     *              select A.OBJECT_NAME AS OBJ_NAME,B.LINE AS SEQNO,'' AS CLM ,
065     *                      '' AS CLS_NAME,'' AS USE_LENGTH,'' AS CLM_NAME,
066     *                      '' AS TABLE_NAME ,'' AS MAX_LENGTH,
067     *                      B.TEXT , '{@SYSTEM_ID}' AS SYSTEM_ID,'{@TBLSYU}' AS TBLSYU
068     *              from USER_OBJECTS A inner join USER_SOURCE B
069     *              on    A.OBJECT_NAME = B.NAME
070     *              where A.OBJECT_TYPE = 'TYPE'
071     *              and   B.TYPE        = 'TYPE'
072     *              and   not A.OBJECT_NAME like '%ARRAY'
073     *              order by A.OBJECT_NAME,B.LINE
074     *      ?<og:tableFilter classId="DBARG"
075     *                              keys="TEXT,OBJ_NAME,SEQNO,CLM,CLS_NAME,USE_LENGTH,CLM_NAME,MAX_LENGTH"
076     *                              vals="TEXT,OBJ_NAME,SEQNO,CLM,CLS_NAME,USE_LENGTH,CLM_NAME,MAX_LENGTH" />
077     *
078     *      ② <og:tableFilter classId="DBARG" >
079     *               {
080     *                      TEXT       : 処?おこな??ソースの?スト部のカラ?
081     *                      OBJ_NAME   : キーとなるオブジェクト名のカラ?
082     *                      SEQNO      : ソースの行番号のカラ?
083     *                      CLM        : 処?果のカラ?を?納するカラ?
084     *                      CLS_NAME   : 処?果のクラス名を格納するカラ?
085     *                      USE_LENGTH : 処?果の利用桁数を?納するカラ?
086     *                      CLM_NAME   : 処?果のカラ?称?ラベル?を格納するカラ?
087     *                      MAX_LENGTH : 処?果の桁数を?納するカラ?
088     *               }
089     *         </og:tableFilter>
090     *
091     * @og.rev 5.6.6.0 (2013/07/05) keys の整合?チェ?を追?
092     *
093     * @version  0.9.0  2000/10/17
094     * @author   Kazuhiko Hasegawa
095     * @since    JDK1.1,
096     */
097    public class TableFilter_DBARG extends AbstractTableFilter {
098            //* こ?プログラ??VERSION??を設定します?       {@value} */
099            private static final String VERSION = "5.6.6.1 (2013/07/12)" ;
100    
101            /**
102             * keys の整合?チェ?を行うための初期設定を行います?
103             *
104             * @og.rev 5.6.6.1 (2013/07/12) keys の整合?チェ?対?
105             *
106             * @param       keysMap keys の整合?チェ?を行うための Map
107             */
108            @Override
109            protected void init( final Map<String,String> keysMap ) {
110                    keysMap.put( "TEXT"             , "処?おこな??ソースの?スト部のカラ?"              );
111                    keysMap.put( "OBJ_NAME"         , "キーとなるオブジェクト名のカラ?"                                      );
112                    keysMap.put( "SEQNO"            , "ソースの行番号のカラ?"                                                      );
113                    keysMap.put( "CLM"                      , "処?果のカラ?を?納するカラ?"                              );
114                    keysMap.put( "CLS_NAME"         , "処?果のクラス名を格納するカラ?"                             );
115                    keysMap.put( "USE_LENGTH"       , "処?果の利用桁数を?納するカラ?"                              );
116                    keysMap.put( "CLM_NAME"         , "処?果のカラ?称?ラベル?を格納するカラ?"    );
117                    keysMap.put( "MAX_LENGTH"       , "処?果の桁数を?納するカラ?"                                  );
118            }
119    
120            // 5.5.7.4 (2012/10/25) OBJ_NAME,SEQNO 追?
121    //      private static final String[] KEYS = new String[] { "TEXT","CLM","CLS_NAME","USE_LENGTH","CLM_NAME","MAX_LENGTH" };
122            private static final String[] KEYS = new String[] { "TEXT","OBJ_NAME","SEQNO","CLM","CLS_NAME","USE_LENGTH","CLM_NAME","MAX_LENGTH" };
123            private static final int TEXT           = 0;
124            private static final int OBJ_NAME       = 1;                    // 5.5.7.4 (2012/10/25) OBJ_NAME 追?
125            private static final int SEQNO          = 2;                    // 5.5.7.4 (2012/10/25) SEQNO 追?
126            private static final int CLM            = 3;
127            private static final int CLS_NAME       = 4;
128            private static final int USE_LENGTH     = 5;
129            private static final int CLM_NAME       = 6;
130            private static final int MAX_LENGTH     = 7;
131    
132            /**
133             * DBTableModel処?実行します?
134             *
135             * @og.rev 5.5.2.6 (2012/05/25) protected変数を?private化したため?getterメソ?で取得するよ?変更
136             * @og.rev 5.5.7.4 (2012/10/25) OBJ_NAME,SEQNO を追?ることで、SEQNO を振りなおします?
137             *
138             * @return 処?果のDBTableModel
139             */
140            public DBTableModel execute() {
141                    DBTableModel table = getDBTableModel();         // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
142    
143                    String lang = getValue( "LANG" );
144                    ResourceManager resource = ResourceFactory.newInstance( lang );
145    
146                    int size = KEYS.length;
147                    int[] clmNo = new int[size];
148                    for( int i=0; i<size; i++ ) {
149                            String clm = getValue( KEYS[i] );
150                            clmNo[i]  = table.getColumnNo( clm,false );     // 存在しな??合??1
151                            if( clmNo[i] < 0 ) {
152                                    String errMsg = "検索結果に、[" + clm + "]を含めてください? ;
153                                    throw new HybsSystemException( errMsg );
154                            }
155                    }
156    
157                    String[] data  = null;
158                    int rowCnt = table.getRowCount();
159                    DBTableModel rtnTbl = table.newModel();
160                    String bkObjName = "";                                          // 5.5.7.4 (2012/10/25) SEQNO を振りなおすためのキーブレイク
161                    int    seqno     = 1 ;                                          // 5.5.7.4 (2012/10/25) SEQNO
162                    for( int row=0; row<rowCnt; row++ ) {
163                            try {
164                                    data = table.getValues( row );
165                                    String text = data[clmNo[TEXT]] ;
166                                    String[] temp = textSeparate( text );
167                                    if( temp != null ) {
168                                            String objName                  = data[clmNo[OBJ_NAME]];                // 5.5.7.4 (2012/10/25) SEQNO を振りなおす
169                                            if( ! bkObjName.equals( objName ) ) {
170                                                    bkObjName = objName;
171                                                    seqno     = 1;
172                                            }
173    
174                                            data[clmNo[SEQNO]]              = String.valueOf( seqno++ );            // 5.5.7.4 (2012/10/25) SEQNO を振りなおす
175                                            data[clmNo[CLM]]                = temp[0];
176                                            data[clmNo[CLS_NAME]]   = temp[1];
177                                            data[clmNo[USE_LENGTH]] = temp[2];
178                            //              data[clmNo[CLM_NAME]]   = resource.getLabel( temp[0] ) ;
179    
180                                            DBColumn dbClm = resource.getDBColumn( temp[0] );
181                                            if( dbClm != null ) {
182                                                    data[clmNo[CLM_NAME]]   = dbClm.getLabel() ;
183                                                    String len = data[clmNo[MAX_LENGTH]] ;
184                                                    if( len == null || len.length() == 0 ) {
185                                                            data[clmNo[MAX_LENGTH]] = dbClm.getMaxlength() ;
186                                                    }
187                                            }
188                            //              else {
189                            //                      data[clmNo[CLM_NAME]]   = temp[0] ;     // ラベルが存在しな?
190                            //              }
191                                            rtnTbl.addColumnValues( data );
192                                    }
193                            }
194                            catch( RuntimeException ex ) {
195                                    ErrorMessage errMessage = makeErrorMessage( "TableFilter_DBARG Error",ErrorMessage.NG );
196                                    errMessage.addMessage( row+1,ErrorMessage.NG,"ERR MSG",ex.getMessage() );
197                                    errMessage.addMessage( row+1,ErrorMessage.NG,"ERR Data",StringUtil.array2csv( data ) );
198                            }
199                    }
200    
201                    return rtnTbl;
202            }
203    
204    //      private static final Pattern pt = Pattern.compile( "[^\\w]*([\\w]*)[^\\w]*(VARCHAR2|NUMBER)[^\\w]*\\(([^\\)]*)\\)",Pattern.CASE_INSENSITIVE );
205            private static final Pattern pt = Pattern.compile( "[^\\w]*([\\w]*)[^\\w]*(VARCHAR2|NUMBER)[\\s]*([\\(\\d,\\)]*)",Pattern.CASE_INSENSITIVE );
206                                                                                                    //                         (______)       (_______________)       (_____________)
207    
208            /**
209             * ソースの?スト部を?割します?
210             *
211             * ソースの?スト部は?,NAME_JA VARCHAR2(100) " と?形式??ストになって?す?
212             * これを?カラ?、クラス名部、使用桁数部に?します?上記?例では?
213             * それぞれを?NAME_JA、VARCHAR2?00 に?して、文字?配?に格納します?
214             * また?これら?ソースに?--" ?"/ * ??? * /" などのコメントが含まれるケース?
215             * あります?"--" コメント?、それ以降を無視しますが?/ *" コメント?、?行に
216             * またがる為、今回は処?象から外します?
217             * ソースの?スト部には、それら以外に、OBJECT_NAME に相当する行や?);" などの
218             * ソースの???後?無効な部?あります?無効な部??、null を返すことで
219             * 登録処?ら省?ください?
220             *
221             * @og.rev 5.5.7.4 (2012/10/25) カラ??大?化と、桁数の ? 削除
222             * @og.rev 5.5.8.5 (2012/11/27) 桁数なし?場合?対?
223             *
224             * @param       text    ソースの?スト部
225             *
226             * @return      ?後???配?(CLM,CLS_NAME,USE_LENGTHの?、無効な??タは null
227             */
228            private String[] textSeparate( final String text ) {
229    
230                    int adrs = text.indexOf( "--" );
231                    String text2 = (adrs<0) ? text : text.substring( 0,adrs ) ;
232    
233                    String[] rtnTxt = null ;
234                    Matcher mt = pt.matcher( text2 );
235                    if( mt.lookingAt() ) {
236                            String clm = mt.group( 1 );             // カラ??名称:パターンとして、空白は含まな?
237                            String cls = mt.group( 2 );             // クラスの名称(VARCHAR2|NUMBER)
238                            String len = mt.group( 3 );             // 桁数:パターンとして、前後に空白を含??()を含??何もな?ど
239    
240                            // 5.5.8.5 (2012/11/27) 桁数なし?場合?対?
241                            if( len != null ) {
242                                    int st = len.indexOf( '(' );
243                                    int ed = len.indexOf( ')' );
244                                    if( st >= 0 && ed >= 0 ) {
245                                            len = len.substring( st+1,ed );
246                                            len = len.trim().replaceFirst("^0+", "");                                               // 5.5.7.4 (2012/10/25) 先?の 0 を削除する?
247                                    }
248                                    else {
249                                            len = "";
250                                    }
251                            }
252                            else {
253                                    len = "";
254                            }
255    
256    //                      if( clm != null && cls != null && len != null ) {
257                            if( clm != null && cls != null ) {
258                                    clm = clm.toUpperCase(Locale.JAPAN);                                                            // 5.5.7.4 (2012/10/25) 大?化
259                                    cls = cls.toUpperCase(Locale.JAPAN);                                                            // 5.5.7.4 (2012/10/25) 大?化
260    //                              len = len.trim();
261    //                              len = len.trim().replaceFirst("^0+", "");                                                       // 5.5.7.4 (2012/10/25) 先?の 0 を削除する?
262    //                              if( len.length() > 0 ) {
263                                            rtnTxt = new String[] { clm,cls,len };
264    //                              }
265                            }
266                    }
267    
268                    // マッチしな?また? 条件を?さな??合?、null
269                    return rtnTxt ;
270            }
271    }