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.DBTableModel;
021    
022    import org.opengion.fukurou.util.ErrorMessage;
023    import org.opengion.fukurou.util.StringUtil;
024    
025    import java.util.Map;
026    import java.util.HashMap;
027    
028    /**
029     * TableFilter_UNIQ_NAME は、TableFilter インターフェースを継承した、DBTableModel 処?の
030     * 実?ラスです?
031     *
032     * ここでは、NAME_IN,NAME_OUT,GROUP_KEY,TYPE より、名前を?ユニ?ク化します?
033     * 例えば、氏名で、姓と名で、同姓?場合???を付けることで、区別することができます?
034     *
035     * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか?BODY 部にCSS形式で記述します?
036     * 【パラメータ?
037     *  {
038     *       NAME_IN   : NAME_CLM  ;    名前のオリジナルのカラ??します?(??)
039     *       NAME_OUT  : RYAKU_CLM ;    変換後?名前を設定するカラ??します?NAME_INと同じでもかま?せん???)
040     *       GROUP_KEY : CDBUMON   ;    名前をユニ?クにするグループを?するカラ?を指定します?(選?
041     *                                  グループ?ソートされて??があります???はキーブレイク処?ます?
042     *       TYPE      : [1 or 2]  ;    処??方法を?しま?初期値:1)
043     *                                    1:姓と名を?ます?重??は、?? 形式で、ユニ?クになるまで、名の?を増やします?
044     *                                    2:姓と名を?ます?1. と異なる?は、最初に見つけた重??は、?のまま残します?
045     *  }
046     *
047     * 姓名の?は、?角また?、半角?スペ?スで区?ます?また?重?なければ??は付きません?
048     * TYPE="2" の方式?、?例的に、?から?社員は苗字そのままで、後から?社した人に?(??
049     * 付けたい場合に、名前を入社年の古??にならべることで、実現できます?
050     *
051     * @og.formSample
052     * ●形式?
053     *      ?<og:tableFilter classId="UNIQ_NAME" keys="NAME_IN,NAME_OUT" vals="NAME_CLM,RYAKU_CLM" />
054     *
055     *      ② <og:tableFilter classId="UNIQ_NAME" >
056     *                 { NAME_IN  : NAME_CLM  ; }
057     *                 { NAME_OUT : RYAKU_CLM ; }
058     *         </og:tableFilter>
059     *
060     * @og.rev 5.5.0.3(2012/03/12) 新規作?
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.6,
066     */
067    public class TableFilter_UNIQ_NAME 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( "NAME_IN"  , "名前のオリジナルのカラ?????)"             );
081                    keysMap.put( "NAME_OUT" , "変換後?名前を設定するカラ?????)"    );
082                    keysMap.put( "GROUP_KEY", "名前をユニ?クにするグループを?するカラ?を指?  );
083                    keysMap.put( "TYPE"             , "処?法を??初期値:1) [1 or 2]"       );
084            }
085    
086            /**
087             * DBTableModel処?実行します?
088             *
089             * @og.rev 5.5.2.6 (2012/05/25) protected変数を?private化したため?getterメソ?で取得するよ?変更
090             *
091             * @return 処?果のDBTableModel
092             */
093            public DBTableModel execute() {
094                    DBTableModel table = getDBTableModel();         // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
095    
096                    String nameIn   = getValue( "NAME_IN" );
097                    String nameOut  = getValue( "NAME_OUT" );
098                    String groupKey = getValue( "GROUP_KEY" );
099    
100                    int type = StringUtil.nval( getValue( "TYPE" ), 1 );    // NULL??場合?初期値:1
101    
102                    int inClmNo  = table.getColumnNo( nameIn,false );               // 存在しな??合??1 を返す?
103                    int outClmNo = table.getColumnNo( nameOut,false );
104                    int grpClmNo = table.getColumnNo( groupKey,false );
105    
106                    // ??チェ?
107                    if( inClmNo < 0 || outClmNo <0 ) {
108                            String errMsg = "TableFilter_UNIQ_NAME では、NAME_IN、NAME_OUT??は??です?"
109                                                    + " NAME_IN =" + nameIn
110                                                    + " NAME_OUT=" + nameOut ;
111                            throw new HybsSystemException( errMsg );
112                    }
113    
114                    // 名前をユニ?ク化するため?マップ?キーがユニ?ク化する名前?値は、行番号
115                    Map<String,Integer> nameMap = new HashMap<String,Integer>() ;
116    
117                    String[] data  = null;
118                    int rowCnt = table.getRowCount();
119                    String preKey = null;
120                    int row = 0;
121                    try {
122                            for( row=0; row<rowCnt; row++ ) {
123                                    data  = table.getValues( row );
124                                    String orgName = data[inClmNo];         // オリジナルの名称
125    
126                                    if( grpClmNo >= 0 && preKey == null ) {
127                                            preKey = data[grpClmNo];
128                                            if( preKey == null ) { preKey = ""; }
129                                    }
130    
131                                    if( orgName != null && !orgName.isEmpty() ) {
132                                            String[] seimei = makeSeiMei( orgName );
133                                            String sei = seimei[0];
134                                            String mei = seimei[1];
135    
136                                            if( nameMap.containsKey( sei ) ) {      // 存在する場合?つまり重?
137                                                    if( type == 1 ) {       // 重?に??の?(?を付ける?
138                                                            Integer oldInt = nameMap.get( sei );
139                                                            if( oldInt != null ) {  // null の場合?、?に重???み
140                                                                    // オリジナルの姓名を取?
141                                                                    String oldName = table.getValue( oldInt.intValue(),inClmNo );
142                                                                    String[] oldSeimei = makeSeiMei( oldName );
143    
144                                                                    String key = makeKey( nameMap , oldSeimei[0] , oldSeimei[1] );
145                                                                    nameMap.put( key, oldInt );             // 変更後?キーと値
146                                                                    nameMap.put( sei, null );               // 比?に??キーは残すが?は残さな??
147                                                            }
148                                                    }
149    
150                                                    String key = makeKey( nameMap , sei , mei );
151                                                    nameMap.put( key, Integer.valueOf( row ) );
152                                            }
153                                            else {
154                                                    nameMap.put( sei, Integer.valueOf( row ) );
155                                            }
156                                    }
157    
158                                    // キーブレイクのチェ?
159                                    if( grpClmNo >= 0 && !preKey.equals( data[grpClmNo] ) ) {
160                                            preKey = data[grpClmNo];
161                                            if( preKey == null ) { preKey = ""; }
162    
163                                            for( Map.Entry<String,Integer> nameEnt : nameMap.entrySet() ){
164                                                    Integer orgInt = nameEnt.getValue();
165                                                    if( orgInt != null ) {
166                                                            int outrow = orgInt.intValue();
167                                                            table.setValueAt( nameEnt.getKey() , outrow , outClmNo );
168                                                    }
169                                            }
170                                            nameMap.clear();
171                                    }
172                            }
173                            for( Map.Entry<String,Integer> nameEnt : nameMap.entrySet() ){
174                                    Integer orgInt = nameEnt.getValue();
175                                    if( orgInt != null ) {
176                                            int outrow = orgInt.intValue();
177                                            table.setValueAt( nameEnt.getKey() , outrow , outClmNo );
178                                    }
179                            }
180                    }
181                    catch( RuntimeException ex ) {
182                            ErrorMessage errMessage = makeErrorMessage( "TableFilter_UNIQ_NAME Error",ErrorMessage.NG );
183                            errMessage.addMessage( row+1,ErrorMessage.NG,ex.getMessage() );
184                            errMessage.addMessage( row+1,ErrorMessage.NG,StringUtil.array2csv( data ) );
185                            errMessage.addMessage( row+1,ErrorMessage.NG,"NAME_IN=[" + nameIn + "]" );
186                            errMessage.addMessage( row+1,ErrorMessage.NG,"NAME_OUT=[" + nameOut + "]" );
187                            errMessage.addMessage( row+1,ErrorMessage.NG,"GROUP_KEY=[" + groupKey + "]" );
188                            errMessage.addMessage( row+1,ErrorMessage.NG,"TYPE=[" + type + "]" );
189                    }
190                    return table;
191            }
192    
193            /**
194             * オリジナルの姓名から、姓と名を?します?
195             *
196             * @param       orgName オリジナルのフルネ??
197             *
198             * @return 姓と名??結果
199             */
200            private String[] makeSeiMei( final String orgName ) {
201                    String[] seimei = new String[2];
202    
203                    int adrs = orgName.indexOf( ' ' );
204                    if( adrs < 0 ) { adrs = orgName.indexOf( '? ); }
205                    if( adrs < 0 ) {
206                            seimei[0] = orgName.trim();
207                            seimei[1] = "";
208                    }
209                    else {
210                            seimei[0] = orgName.substring( 0,adrs ).trim();
211                            seimei[1] = orgName.substring( adrs+1 ).trim();
212                    }
213    
214                    return seimei ;
215            }
216    
217            /**
218             * マップに存在しな?ーを作?します?マップへの登録は、行いません?
219             *
220             * @param       nameMap 過去に登録されて?名前キーのマッ?
221             * @param       sei             オリジナルの?
222             * @param       mei             オリジナルの?
223             *
224             * @return      新しく作?されたキー
225             */
226            private String makeKey( final Map<String,Integer> nameMap , final String sei , final String mei ) {
227                    String key = null;
228    
229                    boolean flag = true;    // 未処?ラグ
230                    for( int i=1; i<=mei.length(); i++ ) {
231                            key = sei + "(" + mei.substring(0,i) + ")" ;
232                            if( ! nameMap.containsKey( key ) ) {    // 存在しな?
233                                    flag = false;
234                                    break;
235                            }
236                    }
237                    if( flag ) {
238                            for( int i=1; i<10; i++ ) {
239                                    key = sei + mei + "("  + i  + ")" ;
240                                    if( ! nameMap.containsKey( key ) ) {    // 存在しな?
241                                            break;
242                                    }
243                            }
244                    }
245    
246                    return key ;
247            }
248    }