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 */
016package org.opengion.fukurou.model;
017
018import org.opengion.fukurou.system.OgRuntimeException ;         // 6.4.2.0 (2016/01/29)
019
020/**
021 * DataModel の実装クラスです。
022 * Formatter で使用されるDataModelインターフェースに、対応する
023 * 実データを管理します。
024 * データ設定時に、コピーしますので、基本的には、オリジナルの書き換えは
025 * できません。
026 * 実データも、1行分のみ持っています。
027 *
028 * @og.group 画面表示
029 *
030 * @version  4.0
031 * @author   Kazuhiko Hasegawa
032 * @since    JDK5.0,
033 */
034// 8.5.5.1 (2024/02/29) spotbugs CT_CONSTRUCTOR_THROW(コンストラクタで、Excweptionを出さない) class を final にすれば、警告は消える。
035// public class ArrayDataModel implements DataModel<String> {
036public final class ArrayDataModel implements DataModel<String> {
037        private final boolean useThrow ;                        // 6.9.5.0 (2018/04/23) getColumnNo のカラム名が存在しない場合に、Exception を throw するかどうか
038        private final String[] names ;
039        private String[] values ;
040
041        /**
042         * 引数に名前配列を指定したコンストラクター
043         *
044         * @og.rev 6.9.5.0 (2018/04/23) カラム名が存在しない場合に、Exception を throw するかどうかを指定可能にする。
045         *
046         * @param       nms             名前配列
047         * @throws  IllegalArgumentException 引数の名前配列が null の場合
048         */
049        public ArrayDataModel( final String[] nms ) {
050                this( nms , false );                    // 6.9.5.0 (2018/04/23) カラム名が存在しない場合は、-1 を返す設定。
051        }
052
053        /**
054         * 引数に名前配列を指定したコンストラクター
055         *
056         * getColumnNoメソッドで、カラム名が存在しない場合に、Exception を throw するかどうかを、
057         * 第2パラメータで指定します。true で、Exception を throw するです。
058         * このメソッドは、Formatter から呼ばれるため、インスタンス生成時にフラグ設定を行っておく必要があります。
059         *
060         * @og.rev 6.9.5.0 (2018/04/23) カラム名が存在しない場合に、Exception を throw するかどうかを指定可能にする。
061         *
062         * @param       nms                     名前配列
063         * @param   useThrow    カラム名が存在しない場合に、Exception を throw するかどうか [true:throw する/false:-1 を返す]
064         * @throws  IllegalArgumentException 引数の名前配列が null の場合
065         */
066        public ArrayDataModel( final String[] nms , final boolean useThrow ) {
067                if( nms == null ) {
068                        final String errMsg = "引数の名前配列に、null は設定できません。";
069                        throw new IllegalArgumentException( errMsg );
070                }
071
072                final int size = nms.length ;
073                names = new String[size] ;
074                System.arraycopy( nms,0,names,0,size );
075                this.useThrow = useThrow;                                       // 6.9.5.0 (2018/04/23)
076        }
077
078        /**
079         * row にあるセルの設定値を置き換えます。
080         *
081         * @param   vals  新しい配列値。
082         * @param   row   値が変更される行(無視されます)
083         */
084        @Override       // DataModel
085        public void setValues( final String[] vals, final int row ) {
086                final int size = vals.length;
087                values = new String[size];
088                System.arraycopy( vals,0,values,0,size );
089        }
090
091        /**
092         * カラム名に対応する カラム番号を返します。
093         *
094         * 特殊なカラムが指定された場合は、負の値を返します。
095         * 例えば、[KEY.カラム名]、[I]、[ROW.ID] など、特定の負の値を返します。
096         * また、カラム名が元のデータモデルに存在しない場合も、負の値か、
097         * Exception を返します。負の値なのか、Exception なのかは、
098         * 実装に依存します。
099         *
100         * @og.rev 6.9.5.0 (2018/04/23) カラム名が存在しない場合に、Exception を throw するかどうかを指定可能にする。
101         *
102         * @param       columnName      値が参照されるカラム名
103         *
104         * @return  指定されたセルのカラム番号。存在しなければ、-1
105         * @throws  IllegalArgumentException 引数のカラム名が null の場合
106         */
107        @Override       // DataModel
108        public int getColumnNo( final String columnName ) {
109                if( columnName == null ) {
110                        final String errMsg = "引数のカラム名に、null は設定できません。";
111                        throw new IllegalArgumentException( errMsg );
112                }
113
114                int address = -1;
115                for( int i=0; i<names.length; i++ ) {
116                        if( columnName.equalsIgnoreCase( names[i] ) ) {
117                                address = i;
118                                break;
119                        }
120                }
121
122                // 6.9.5.0 (2018/04/23) カラム名が存在しない場合に、Exception を throw するかどうか
123                if( useThrow && address < 0 ) {
124                        final String errMsg = "カラム名が存在しません:[" + columnName + "]" ;
125                        throw new OgRuntimeException( errMsg );
126                }
127
128                return address;
129        }
130
131        /**
132         * カラム名配列に対応する カラム番号配列を返します。
133         *
134         * これは、#getColumnNo( String ) に対する 複数のカラム名を検索した
135         * 場合と同じです。
136         *
137         * @og.rev 6.3.9.1 (2015/11/27) メソッドの出口は、最後の1か所にすべきです(PMD)。
138         * @og.rev 6.8.6.0 (2018/01/19) 可変長引数から、通常配列に変更。
139         * @og.rev 6.9.5.0 (2018/04/23) #getColumnNo(String)を呼ぶように修正
140         *
141//       * @param       clmNms  値が参照されるカラム名配列(可変長引数)
142         * @param       clmNms  値が参照されるカラム名配列
143         *
144         * @return  指定されたセルのカラム番号配列。
145         * @og.rtnNotNull
146         */
147//      public int[] getColumnNos( final String... clmNms ) {
148        public int[] getColumnNos( final String[] clmNms ) {
149
150                final int size = clmNms == null ? 0 : clmNms.length ;
151
152                final int[] clmNos = new int[size];
153                for( int j=0; j<size; j++ ) {
154                        // 6.9.5.0 (2018/04/23) #getColumnNo(String)を呼ぶように修正
155                        clmNos[j] = getColumnNo( clmNms[j] );
156//                      int address = -1;
157//                      for( int i=0; i<names.length; i++ ) {
158//                              if( clmNms[j].equalsIgnoreCase( names[i] ) ) {
159//                                      address = i;
160//                                      break;
161//                              }
162//                      }
163//                      clmNos[j] = address;
164                }
165
166                return clmNos;
167        }
168
169        /**
170         * カラム名配列を返します。
171         *
172         * @return      カラム名配列
173         * @og.rtnNotNull
174         */
175        @Override       // DataModel
176        public String[] getNames() {
177                return names.clone();
178        }
179
180        /**
181         * row にあるセルの属性値を配列で返します。
182         *
183         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
184         *
185         * @param   row     値が参照される行(無視されます)
186         *
187         * @return  指定されたセルの属性値
188         * @og.rtnNotNull
189         */
190        @Override       // DataModel
191        public String[] getValues( final int row ) {
192                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
193                if( values == null ) {
194                        final String errMsg = "#setValues(String[],int)を先に実行しておいてください。";
195                        throw new OgRuntimeException( errMsg );
196                }
197
198                return values.clone();
199        }
200
201        /**
202         * row および clm にあるセルの属性値をStringに変換して返します。
203         *
204         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
205         *
206         * @param   row     値が参照される行(無視されます)
207         * @param   clm     値が参照される列
208         *
209         * @return  指定されたセルの値
210         *
211         */
212        @Override       // DataModel
213        public String getValue( final int row, final int clm ) {
214                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
215                if( values == null ) {
216                        final String errMsg = "#setValues(String[],int)を先に実行しておいてください。";
217                        throw new OgRuntimeException( errMsg );
218                }
219
220                return values[clm];
221        }
222
223        /**
224         * clm のNativeタイプを返します。
225         * Nativeタイプはorg.opengion.fukurou.model.NativeTypeで定義されています。
226         *
227         * @og.rev 4.1.1.2 (2008/02/28) 新規追加
228         * @og.rev 5.1.8.0 (2010/07/01) NativeType#getType(String) のメソッドを使用するように変更。
229         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
230         *
231         * @param  clm      値が参照される列
232         *
233         * @return Nativeタイプ
234         * @see org.opengion.fukurou.model.NativeType
235         */
236        @Override       // DataModel
237        public NativeType getNativeType( final int clm ) {
238                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
239                if( values == null ) {
240                        final String errMsg = "#setValues(String[],int)を先に実行しておいてください。";
241                        throw new OgRuntimeException( errMsg );
242                }
243
244                return NativeType.getType( values[clm] );
245        }
246}