    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.process;
    017
    018import org.opengion.fukurou.model.DataModel;
    019import org.opengion.fukurou.model.NativeType;
    020import org.opengion.fukurou.util.StringUtil;
    021
    022import java.util.Arrays;
    023
    024/**
    025 * LineModel は、データの１行分を管理する為の TableModel と類似の実装クラスです。
    026 *
    027 * データの１行分を LineModel に割り当てます。
    028 * カラム番号は、0 から始まります。カラム名よりカラム番号を求める場合に、
    029 * 存在しない場合は、-1 を返します。
    030 * カラム番号が -1 の場合は、処理を行いません。
    031 *
    032 * 注意：このクラスは、同期処理されていません。
    033 *
    034 * @version  4.0
    035 * @author   Kazuhiko Hasegawa
    036 * @since    JDK5.0,
    037 */
    038public class LineModel implements DataModel<Object> {           // 4.3.3.6 (2008/11/15) Generics警告対応
    039        /** タブセパレータ  */
    040        private static final String TAB = "\t";   // タブ区切り文字
    041
    042        /** リターンコード  System.getProperty("line.separator")  */
    043        private static final String CR = System.getProperty("line.separator");
    044
    045        private String[]        names   = null;
    046        private Object[]        data    = null;
    047        private int                     dtSize  = 0;
    048        private int                     rowNo   = -1;
    049
    050        /**
    051         * このオブジェクトを初期化します。
    052         * 指定の引数分の内部配列を作成します。
    053         *
    054         * @param   columnCount カラム数
    055         */
    056        public void init( final int columnCount ) {
    057                if( columnCount <= 0 ) {
    058                        String errMsg = "内部配列の数量が 0か、負です。count=[" + columnCount + "]";
    059                        throw new RuntimeException( errMsg );
    060                }
    061                dtSize  = columnCount;
    062                names   = new String[dtSize];
    063                data    = new Object[dtSize];
    064        }
    065
    066        /**
    067         * カラム名配列を指定して、このオブジェクトを初期化します。
    068         *
    069         * @param   clmNms カラム名配列
    070         */
    071        public void init( final String[] clmNms ) {
    072                if( clmNms == null ) {
    073                        String errMsg = "カラム名配列が、 null です。";
    074                        throw new RuntimeException( errMsg );
    075                }
    076                dtSize  = clmNms.length;
    077                names   = new String[dtSize];
    078                System.arraycopy( clmNms,0,names,0,dtSize );
    079                data    = new Object[dtSize];
    080        }
    081
    082        /**
    083         * 名前をセットします。
    084         * 指定のカラム番号が、-1 の場合は、なにもしません。
    085         *
    086         * @param   clm  値が変更されるカラム番号
    087         * @param   key  新しい名前
    088         *
    089         */
    090        public void setName( final int clm,final String key ) {
    091                if( clm >= 0 ) { names[clm] = key; }
    092        }
    093
    094        /**
    095         * カラム番号に対するカラム名を取得します。
    096         * 指定のカラム番号が、-1 の場合は、null を返します。
    097         *
    098         * @param   clm  最初のカラム番号は 0、2番目のカラム番号は 1、などとする。
    099         *
    100         * @return  カラム名
    101         *
    102         */
    103        public String getName( final int clm ) {
    104                return ( clm >= 0 ) ? names[clm] : null ;
    105        }
    106
    107        /**
    108         * カラム名配列を返します。
    109         * 配列オブジェクトは、clone されたコピーを返しますので、
    110         * 内容を書き換えたい場合は、setName() メソッドを使用してください。
    111         *
    112         * @return      カラム名配列
    113         */
    114        public String[] getNames() {
    115                return names.clone();
    116        }
    117
    118        /**
    119         * column に対応した 値を登録します。
    120         * 指定のカラム番号が、-1 の場合は、なにもしません。
    121         *
    122         * @param   clm  値が変更されるカラム番号
    123         * @param   value   新しい値。null も可
    124         *
    125         */
    126        public void setValue( final int clm,final Object value ) {
    127                if( clm >= 0 ) { data[clm] = value; }
    128        }
    129
    130        /**
    131         * column にあるセルの属性値をObjectに変換して返します。
    132         * 指定のカラム番号が、-1 の場合は、null を返します。
    133         *
    134         * @param   clm  値が参照されるカラム番号
    135         *
    136         * @return  指定されたセルの値 Object
    137         *
    138         */
    139        public Object getValue( final int clm ) {
    140                return ( clm >= 0 ) ? data[clm] : null ;
    141        }
    142
    143        /**
    144         * row および clm にあるセルの属性値をStringに変換して返します。
    145         *
    146         * @param   row     値が参照される行
    147         * @param   clm     値が参照される列
    148         *
    149         * @return  指定されたセルの値
    150         *
    151         */
    152        public String getValue( final int row, final int clm) {
    153                String errMsg = "このクラスでは実装されていません。";
    154                throw new UnsupportedOperationException( errMsg );
    155        }
    156
    157        /**
    158         * 属性値配列をセットします。
    159         * このメソッドでは、カラム名配列は更新しません。配列数が異なる場合や、
    160         * 属性値配列が null の場合は設定できません。
    161         * 設定は、配列オブジェクトのコピーをセットしますので、登録元の配列オブジェクトを
    162         * 書き換えた場合でも、このオブジェクトの内部値は変更されませんので、
    163         * 副作用を期待したコーディングは、行わないで下さい。
    164         * 注意：値オブジェクト配列自身はコピーしますが、個々のオブジェクトそのものは、
    165         * arraycopy しているだけです。個々のオブジェクトの状態変化に対しては、
    166         * 各クライアント側で対応が必要です。
    167         *
    168         * @param       values  セットする値配列
    169         * @param       rno             処理中の行番号
    170         */
    171        public void setValues( final Object[] values, final int rno ) {
    172                if( values == null ) {
    173                        String errMsg = "値配列が、 null です。row=[" + rno + "]";
    174                        throw new RuntimeException( errMsg );
    175                }
    176                else if( names.length != values.length ) {
    177                        String errMsg = "カラム名配列と異なる要素の属性値配列は登録できません。" + CR
    178                                                + " names.length=[" + names.length + "],"
    179                                                + " values.length[" + values.length + "],"
    180                                                + " row=[" + rno + "]"  + CR
    181                                                + " names=" + StringUtil.array2csv( names )
    182                                                + " values=" + Arrays.toString( values ) ;              // 5.1.8.0 (2010/07/01) errMsg 修正
    183                        throw new RuntimeException( errMsg );
    184                }
    185
    186                rowNo = rno;
    187                System.arraycopy( values,0,data,0,values.length );
    188        }
    189
    190        /**
    191         * 属性値を配列で返します。
    192         * 配列オブジェクトは、clone されたコピーを返しますので、
    193         * 内容を書き換えたい場合は、setValue() メソッドを使用してください。
    194         *
    195         * @return  指定されたセルの属性値
    196         */
    197        public Object[] getValues() {
    198                return data.clone();
    199        }
    200
    201        /**
    202         * row にあるセルの属性値を配列で返します。
    203         *
    204         * @param   row     値が参照される行
    205         *
    206         * @return  指定されたセルの属性値
    207         */
    208        public String[] getValues( final int row ) {
    209                String errMsg = "このクラスでは実装されていません。";
    210                throw new UnsupportedOperationException( errMsg );
    211        }
    212
    213        /**
    214         * 行データモデル属性に、処理中の行番号情報を設定します。
    215         * 一般に、setValue( int clm, Object value ) との併用時に使用します。
    216         *
    217         * @param       rno     処理中の行番号
    218         */
    219        public void setRowNo( final int rno ) {
    220                rowNo = rno;
    221        }
    222
    223        /**
    224         * 行データモデル属性の、処理中の行番号情報を返します。
    225         *
    226         * @return  処理中の行番号
    227         *
    228         */
    229        public int getRowNo() {
    230                return rowNo;
    231        }
    232
    233        /**
    234         * columnName 名称に対応する カラム番号を返します。存在しない場合は、-1 を返します。
    235         *
    236         * @param   columnName  値が参照されるカラム番号
    237         *
    238         * @return  指定されたセルのカラム番号(存在しない場合は、-1)
    239         *
    240         */
    241        public int getColumnNo( final String columnName ) {
    242                int clmNo = -1;
    243                if( columnName != null ) {
    244                        for( int i=0; i<dtSize; i++ ) {
    245                                if( columnName.equalsIgnoreCase( names[i] ) ) {
    246                                        clmNo = i;
    247                                        break;
    248                                }
    249                        }
    250                }
    251
    252                return clmNo;
    253        }
    254
    255        /**
    256         * データテーブル内の列の数を返します。
    257         *
    258         * @return  モデルの列数
    259         *
    260         */
    261        public int size() {
    262                return dtSize ;
    263        }
    264
    265        /**
    266         * この内部データの名前配列を連結した文字列で、出力します。
    267         *
    268         * @return      内部データの名前配列を連結した文字列
    269         */
    270        public String nameLine() {
    271                String rtn = "No Data";
    272
    273                if( dtSize > 0 ) {
    274                        StringBuilder buf = new StringBuilder();
    275                        buf.append( "#Name" );
    276                        for( int clm=0; clm<dtSize; clm++ ) {
    277                                buf.append( TAB );
    278                                buf.append( names[clm] );
    279                        }
    280                        rtn = buf.toString() ;
    281                }
    282                return rtn ;
    283        }
    284
    285        /**
    286         * この内部データの名前配列を連結した文字列で、出力します。
    287         *
    288         * @return      名前配列を連結した文字列
    289         */
    290        public String dataLine() {
    291                String rtn = "No Data";
    292
    293                if( dtSize > 0 ) {
    294                        StringBuilder buf = new StringBuilder();
    295                        buf.append( rowNo );
    296                        for( int clm=0; clm<dtSize; clm++ ) {
    297                                buf.append( TAB );
    298                                buf.append( data[clm] );
    299                        }
    300                        rtn = buf.toString() ;
    301                }
    302                return rtn ;
    303        }
    304
    305        /**
    306         * この内部データを見える形で出力します。
    307         *
    308         * @return      内部データを見える形
    309         */
    310        @Override
    311        public String toString() {
    312                return nameLine() + CR + dataLine() ;
    313        }
    314
    315        /**
    316         * clm のNativeタイプを返します。
    317         * Nativeタイプはorg.opengion.fukurou.model.NativeTypeで定義されています。
    318         *
    319         * @og.rev 4.1.1.2 (2008/02/28) 新規追加
    320         * @og.rev 5.1.8.0 (2010/07/01) NativeType#getType(String) のメソッドを使用するように変更。
    321         *
    322         * @param  clm      値が参照される列
    323         *
    324         * @return Nativeタイプ
    325         * @see org.opengion.fukurou.model.NativeType
    326         */
    327        public NativeType getNativeType( final int clm ) {
    328                return NativeType.getType( data[clm].toString() );
    329        }
    330}