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.fukurou.business;
017    
018    import org.opengion.fukurou.model.DataModel;
019    import org.opengion.fukurou.model.NativeType;
020    
021    import java.util.Map;
022    import java.util.HashMap;
023    import java.util.Arrays;
024    
025    /**
026     * 業務ロジãƒ?‚¯をå?ç�?�™るためã?ãƒ??ブルモãƒ?ƒ«ですã?
027     *
028     * こã?ãƒ??ブルモãƒ?ƒ«では、オブジェクト生成時に、カラãƒ??列ã?値配å?をå?に、å?部ãƒ??タを生成しã€?
029     * そã?後ã?、行ã?追åŠ?‚„値の変更はできませんã€?
030     *
031     * @og.rev 5.1.1.0 (2009/12/01) 新規作æ?
032     * @og.group 業務ロジãƒ?‚¯
033     *
034     * @version 5.0
035     * @author Hiroki Nakamura
036     * @since JDK1.6,
037     */
038    public class ArrayTableModel implements DataModel<String> {
039            private static final String CR = System.getProperty("line.separator");          // 5.6.7.0 (2013/07/27) 追åŠ?
040    
041            private final String[] names;
042            private final String[][] vals;
043            private final String[] modTypes;
044    
045            private Map<Integer,String[]> rtnMap = null;      // 5.6.0.3 (2012/01/24) 変更されたå?をã?書き戻すためã?Map<インãƒ?ƒƒクス,値配å?> 
046    
047            /**
048             * 引数に名前配å?、å?配å?を指定したコンストラクター
049             *
050             * @param       nms     名前配å?
051             * @param       vs      値?’重配å?
052             * @throws  IllegalArgumentException 引数の配å?が不正な場å�?
053             */
054            public ArrayTableModel( final String[] nms, final String[][] vs ) {
055                    this( nms, vs, null );
056            }
057    
058            /**
059             * 引数に名前配å?、å?配å?、変更区åˆ??列をæŒ?®šしたコンストラクター
060             *
061             * @og.rev 5.6.7.0 (2013/07/27) エラーメãƒ?‚»ージを判りやすくするã€?
062             * @og.rev 5.7.2.3 (2014/01/31) vsのチェãƒ?‚¯条件を戻ã�?
063             * @og.rev 5.7.3.1 (2014/02/14) nmsのチェãƒ?‚¯条件も戻ã�?
064             *
065             * @param       nms     名前配å?
066             * @param       vs      値?’重配å?
067             * @param       ms      変更区åˆ??配å?
068             * @throws  IllegalArgumentException 引数の配å?が不正な場å�?
069             */
070            public ArrayTableModel( final String[] nms, final String[][] vs, final String[] ms ) {
071                    if( nms == null || nms.length == 0 ) {
072                            String errMsg = "引数の名前配å?に、null は設定できませんã€?;
073                            throw new IllegalArgumentException( errMsg );
074                    }
075                    // 5.6.7.0 (2013/07/27) エラーメãƒ?‚»ージを判りやすくするã€?
076                    // 5.7.2.3 (2014/01/31) 結果?�行でlength=0で通るようなのでvsのエラーチェãƒ?‚¯条件を戻すã?
077                    if( vs == null ) {
078    //      if( vs == null || vs.length == 0 || vs[0] == null || vs[0].length == 0 ) {
079                            String errMsg = "引数の値配å?に、null は設定できませんã€?;
080                            throw new IllegalArgumentException( errMsg );
081                    }
082                    // 5.7.3.1 (2014/02/14) 5.7.2.3での戻しでは不十åˆ?� ったã?でこちらも戻ã�?
083                    if( vs.length > 0 ) {
084                            if( vs[0] == null || vs[0].length == 0 || nms.length != vs[0].length ) {
085    //                      if( nms.length != vs[0].length ) {
086    //                              String errMsg = "名前配å?と値配å?のカラãƒ?•°が異なりますã?" ;
087                                    String errMsg = "名前配å?と値配å?のカラãƒ?•°が異なりますã?"     + CR
088                                                    + "   nms   =" + Arrays.toString( nms   )                       + CR
089                                                    + "   vs[0] =" + Arrays.toString( vs[0] ) ;
090                                    throw new IllegalArgumentException( errMsg );
091                            }
092                    }
093    
094                    int cols = nms.length;
095                    names = new String[cols];
096                    System.arraycopy( nms, 0, names, 0, cols );
097    
098                    int rows = vs.length;
099                    vals = new String[rows][cols];
100                    for( int i = 0; i < rows; i++ ) {
101                            System.arraycopy( vs[i], 0, vals[i], 0, cols );
102                    }
103    
104                    if( ms != null && ms.length > 0 ) {
105                            if( vs.length == ms.length ) {
106                                    modTypes = new String[rows];
107                                    System.arraycopy( ms, 0, modTypes, 0, rows );
108                            }
109                            else {
110                                    // 5.6.7.0 (2013/07/27) エラーメãƒ?‚»ージを判りやすくするã€?
111    //                              String errMsg = "変更区åˆ?‚’æŒ?®šするå?合ã?値配å?の行数とä¸??するå¿?¦�がありますã?";
112                                    String errMsg = "変更区åˆ?‚’æŒ?®šするå?合ã?値配å?の行数とä¸??するå¿?¦�がありますã?"    + CR
113                                                    + "   変更区åˆ?行数 =" + ms.length         + CR
114                                                    + "   値配å?   行数 =" + vs.length ;
115                                    throw new IllegalArgumentException( errMsg );
116                            }
117    //                      if( vs.length != ms.length ) {
118    //                              String errMsg = "変更区åˆ?‚’æŒ?®šするå?合ã?値配å?の行数とä¸??するå¿?¦�がありますã?";
119    //                              throw new IllegalArgumentException( errMsg );
120    //                      }
121    //                      else {
122    //                              modTypes = new String[rows];
123    //                              System.arraycopy( ms, 0, modTypes, 0, rows );
124    //                      }
125                    }
126                    else {
127                            modTypes = null;
128                    }
129            }
130    
131            /**
132             * rowでæŒ?®šされた行番号(インãƒ?ƒƒクス番号)に行を追åŠ?�—ますã?
133             *
134             * 値配å?をセãƒ?ƒˆする場合ã?、以下ã?条件をæº?�Ÿすå¿?¦�がありますã?
135             *   ?‘.行番号はã€???rowCount-1) のç¯?›²
136             *   ?’.å?配å?は、not nullã€?かつ ?‘件以ä¸?
137             *   ?“.å?配å?の個数は、å?部カラãƒ?•°と同じ
138             *
139             * ここで登録した値は、å?部の値配å?と別管ç�?�•れますã?で、セãƒ?ƒˆ後に、å?びゲãƒ?ƒˆしてã‚?
140             * ここでセãƒ?ƒˆした値を取りå?すことはできませんã€?
141             * またã?同じ行番号でセãƒ?ƒˆした場合ã?、後でセãƒ?ƒˆした値が有効ですã?
142             *
143             * ※ インãƒ?ƒƒクス(row)とは、このArrayTableModel に持つ vals 配å?の行ã?インãƒ?ƒƒクスですã?
144             * よって、オリジナルのDBTableModelの行番号ではありませんã€?
145             *
146             * @og.rev 5.6.0.3 (2012/01/24) 変更されたå?をã?書き戻す機è?を追åŠ?�—ますã?
147             *
148             * @param   vals  配å?値
149             * @param   row   追åŠ?�™るインãƒ?ƒƒクス
150             * @throws      IllegalArgumentException 引数が1,2,3ã?条件をæº?�Ÿさなã�??合ã?
151             */
152            public void setValues( final String[] vals, final int row ) {
153    //              throw new RuntimeException( "こã?クラスでは、setValuesメソãƒ?ƒ‰はサポã?トされてã�?�¾せん" );
154                    if( row < 0 || row > getRowCount() ) {
155                            String errMsg = "引数のインãƒ?ƒƒクスはã€??? + (getRowCount()-1) + " の間でæŒ?®šしてください。index=[" + row + "]";
156                            throw new IllegalArgumentException( errMsg );
157                    }
158                    else if( vals == null || vals.length == 0 ) {
159                            String errMsg = "引数の値配å?に、null、またã? 0件配å?はæŒ?®šできません。index=[" + row + "]";
160                            throw new IllegalArgumentException( errMsg );
161                    }
162                    else if( vals.length != names.length ) {
163                            String errMsg = "引数の値配å?の個数と、å?部カラãƒ?•°がä¸??しませんã€?
164                                                    + " index=[" + row + "] : 引数個数=[" + vals.length + "] != å†?ƒ¨カラãƒ?•°=[" + names.length + "]";
165                            throw new IllegalArgumentException( errMsg );
166                    }
167    
168                    if( rtnMap == null ) { rtnMap = new HashMap<Integer,String[]>(); }
169    
170                    int cols = vals.length;
171                    String[] newVals = new String[cols];
172                    System.arraycopy( vals, 0, newVals, 0, cols );
173    
174                    rtnMap.put( Integer.valueOf( row ) , newVals );
175            }
176    
177            /**
178             * BizLogicで、データが変更されたå?合ã?、このMapで値の配å?を返しますã?
179             * Mapのキーは、インãƒ?ƒƒクス(row)のIntegerオブジェクトですã?値は、設定された String配å?ですã?
180             * なにも変更がされてã�?�ªければ、null を返しますã?
181             *
182             * ※ インãƒ?ƒƒクス(row)とは、このArrayTableModel に持つ vals 配å?の行ã?インãƒ?ƒƒクスですã?
183             * よって、オリジナルのDBTableModelの行番号ではありませんã€?
184             *
185             * @og.rev 5.6.0.3 (2012/01/24) 変更されたå?をã?書き戻すためã?Map&lt;インãƒ?ƒƒクス,値配å?&gt; を返しますã?
186             *
187             * @return      書き戻すためã?Map?œインãƒ?ƒƒクス,値配å???
188             * @see AbstractBizLogic#isRequireTable()
189             */
190            public Map<Integer,String[]> getModifyVals() {
191                    return rtnMap;
192            }
193    
194            /**
195             * カラãƒ?��に対応すã‚?カラãƒ?•ª号を返しますã?
196             *
197             * 特殊なカラãƒ?�ŒæŒ?®šされた場合ã?、è²??値を返しますã?
198             * 例えば、[KEY.カラãƒ?��]、[I]、[ROW.ID] など、特定ã?è²??値を返しますã?
199             * またã?カラãƒ?��がå?のãƒ??タモãƒ?ƒ«に存在しなã�??合も、è²??値かã?
200             * Exception を返しますã?è²??値なのかã?Exception なのかã?ã€?
201             * 実è£?�«依存しますã?
202             *
203             * @param       columnName      値が参照されるカラãƒ?��
204             *
205             * @return  æŒ?®šされたセルのカラãƒ?•ª号。存在しなければã€?1
206             * @throws  IllegalArgumentException 引数のカラãƒ?��ã�?null の場å�?
207             */
208            public int getColumnNo( final String columnName ) {
209                    if( columnName == null ) {
210                            String errMsg = "引数のカラãƒ?��に、null は設定できませんã€?;
211                            throw new IllegalArgumentException( errMsg );
212                    }
213    
214                    int address = -1;
215                    for( int i = 0; i < names.length; i++ ) {
216                            if( columnName.equalsIgnoreCase( names[i] ) ) {
217                                    address = i;
218                                    break;
219                            }
220                    }
221    
222                    return address;
223            }
224    
225            /**
226             * カラãƒ?��配å?に対応すã‚?カラãƒ?•ª号配å?を返しますã?
227             *
228             * これはã€?getColumnNo( String ) に対する è¤?•°のカラãƒ?��を検索した
229             * 場合と同じですã?
230             *
231             * @param       clmNms  値が参照されるカラãƒ?��配å?
232             *
233             * @return  æŒ?®šされたセルのカラãƒ?•ª号配å?ã€?
234             */
235            public int[] getColumnNos( final String[] clmNms ) {
236                    if( clmNms == null ) { return new int[0]; }
237    
238                    int[] clmNos = new int[clmNms.length];
239                    for( int j = 0; j < clmNms.length; j++ ) {
240                            int address = -1;
241                            for( int i = 0; i < names.length; i++ ) {
242                                    if( clmNms[j].equalsIgnoreCase( names[i] ) ) {
243                                            address = i;
244                                            break;
245                                    }
246                            }
247                            clmNos[j] = address;
248                    }
249    
250                    return clmNos;
251            }
252    
253            /**
254             * カラãƒ?��配å?を返しますã?
255             *
256             * @return      カラãƒ?��配å?
257             */
258            public String[] getNames() {
259                    return names.clone();
260            }
261    
262            /**
263             * row にあるセルの属æ?値をé?列で返しますã?
264             *
265             * @param   row     値が参照されるè¡?
266             *
267             * @return  æŒ?®šされたセルの属æ?値配å?
268             */
269            public String[] getValues( final int row ) {
270                    return vals[row].clone();
271            }
272    
273            /**
274             * row および clm にあるセルの属æ?値をStringに変換して返しますã?
275             *
276             * @param   row     値が参照されるè¡?
277             * @param   clm     値が参照されるå?
278             *
279             * @return  æŒ?®šされたセルの値
280             *
281             */
282            public String getValue( final int row, final int clm ) {
283                    return vals[row][clm];
284            }
285    
286            /**
287             * row および clm にあるセルの属æ?値をStringに変換して返しますã?
288             *
289             * @param   row     値が参照されるè¡?
290             * @param   clm     値が参照されるå?(キー)
291             *
292             * @return  æŒ?®šされたセルの値
293             *
294             */
295            public String getValue( final int row, final String clm ) {
296                    return vals[row][getColumnNo( clm )];
297            }
298    
299            /**
300             * ãƒ??タãƒ??ブルå†??行ã?数を返しますã?
301             *
302             * @return  モãƒ?ƒ«の行数
303             *
304             */
305            public int getRowCount() {
306                    return vals.length;
307            }
308    
309            /**
310             * row 単位に変更されたタイãƒ?追åŠ?変更/削除)を返しますã?
311             * タイプã?始めにä¸?º¦登録するとそれ以降に変更はかかりませんã€?
312             * つまりã?始めに 追åŠ?�§作æ?したãƒ??タは、その後変更があっても追åŠ??ままですã?
313             * なにも変更されてã�?�ªã�??合ã?, ""(ゼロストリング)を返しますã?
314             *
315             * @param   row     値が参照されるè¡?
316             *
317             * @return  変更されたタイプã?値
318             */
319            public String getModifyType( final int row ) {
320                    return modTypes == null ? "" : modTypes[row];
321            }
322    
323            /**
324             * clm のNativeタイプを返しますã?
325             * Nativeタイプã?org.opengion.fukurou.model.NativeTypeで定義されてã�?�¾すã?
326             *
327             * @og.rev 5.1.8.0 (2010/07/01) NativeType#getType(String) のメソãƒ?ƒ‰を使用するように変更ã€?
328             *
329             * @param  clm      値が参照されるå?
330             *
331             * @return Nativeタイãƒ?
332             * @see org.opengion.fukurou.model.NativeType
333             */
334            public NativeType getNativeType( final int clm ) {
335    //              return StringUtil.getNativeType( vals[0][clm] );
336                    return NativeType.getType( vals[0][clm] );
337            }
338    
339            /**
340             * こã?オブジェクトã?æ–?­—å?表記を返しますã?
341             * ãƒ?ƒ�ãƒ?‚°用ですã?
342             *
343             * @og.rev 5.6.7.0 (2013/07/27) 新規追åŠ?
344             *
345             * @return æ–?­—å?表現
346             * @see java.lang.Object#toString()
347             */
348            @Override
349            public String toString() {
350                    StringBuilder buf = new StringBuilder();
351    
352                    buf.append( "NAMES=" ).append( Arrays.toString( names ) ).append( CR )
353                            .append( " COL_LEN=" ).append( (names != null) ? names.length : -1 ).append( CR )
354                            .append( " ROW_LEN=" ).append( (vals  != null) ? vals.length  : -1 ).append( CR ) ;
355    
356                    return buf.toString();
357            }
358    }