    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.hayabusa.io;
    017
    018import static org.opengion.fukurou.util.HybsConst.CR ;          // 6.1.0.0 (2014/12/26)
    019import org.opengion.fukurou.util.Closer ;
    020import org.opengion.fukurou.util.LogWriter;
    021import org.opengion.fukurou.util.ColorMap;                      // 6.0.2.2 (2014/10/03)
    022// import org.opengion.fukurou.db.DBUtil;                       // 6.0.4.0 (2014/11/28)
    023import org.opengion.fukurou.db.ResultSetValue;          // 6.0.4.0 (2014/11/28)
    024// import org.opengion.hayabusa.common.HybsSystem;
    025import org.opengion.hayabusa.db.DBTableModel;
    026
    027import java.sql.Connection;
    028import java.sql.ResultSet;
    029// import java.sql.ResultSetMetaData;                           // 6.0.4.0 (2014/11/28)
    030import java.sql.SQLException;
    031import java.sql.Statement;
    032
    033import java.util.List;
    034import java.util.ArrayList;
    035import java.util.Arrays;
    036// import java.util.Locale;
    037import java.util.Set;
    038import java.util.HashSet;
    039
    040import java.awt.Color;                                                          // 6.0.2.2 (2014/10/03)
    041
    042import org.jfree.data.Range;
    043import org.jfree.data.category.DefaultCategoryDataset;
    044
    045/**
    046 * HybsCategoryDataset は、org.jfree.data.category.DefaultCategoryDataset を継承したサブクラスで、
    047 * HybsDataset インターフェースの実装クラスになっています。
    048 * これは、JDBCCategoryDatasetの データベース機能と、DBTableModel から Dataset を作成する機能を
    049 * 兼ね備えています。
    050 * HybsDataset インターフェースは、シリーズのラベル指定、カテゴリカラーバー、パレート図用積上げ
    051 * 計算などの処理を行うための、インターフェースで、それらの処理も、HybsCategoryDataset に実装します。
    052 *
    053 * このクラスでは、検索結果を内部で持っておき、getValue(int row, int column)
    054 * メソッドで直接値を返します。
    055 *
    056 * select category,series1,series2,series3,･･･ from ･･･
    057 * series の横持ち(標準と同じ) 対応です。
    058 * category カラムの値は、カテゴリのラベルになり、series1,2,3 のラベルがシリーズラベル、値が
    059 * seriesの値になります。
    060 *
    061 * カテゴリのカラー名の指定を行う場合、最後のカラムが、カラー名の文字列になります。
    062 * select category,series1,series2,series3,･･･,color from ･･･
    063 * color文字列の検索結果は、Dataset には含まれません。
    064 *
    065 * その場合、color カラムがシリーズとして認識されない様に、ChartDatasetTag で、useCategoryColor="true"
    066 * を指定しておく必要があります。このフラグは、HybsCategoryDataset を使う処理以外では効果が
    067 * ありません（シリーズとして使用されてしまう）のでご注意ください。
    068 * このフラグは、カテゴリカラーバーを使う場合には必要ですが、カテゴリカラーバーと（例えばパレート図）
    069 * を合成する場合に、パレート図側にも useCategoryColor="true" を設定しておけば、同じSQL または、
    070 * DBTableModel を使う事ができるというためのフラグです。
    071 *
    072 * なお、Colorコードは、このクラスで作成しますが、Renderer に与える必要があります。
    073 * 通常のRenderer には、categoryにカラーを指定する機能がありませんので、HybsBarRenderer に
    074 * setCategoryColor( Color[] ) メソッドを用意します。(正確には、HybsDrawItem インターフェース)
    075 * このRenderer で、getItemPaint( int  , int )メソッドをオーバーライドすることで、カテゴリごとの
    076 * 色を返します。
    077 *
    078 * @og.rev 5.8.5.0 (2015/02/06) 6.0.2.2 (2014/10/03) からの逆移植
    079 *
    080 * @version  5.8.5.0 (2015/02/06)
    081 * @author   Kazuhiko Hasegawa
    082 * @since    JDK1.6,
    083 */
    084public class HybsCategoryDataset extends DefaultCategoryDataset implements HybsDataset {
    085        private static final long serialVersionUID = 602220141003L ;
    086
    087        private final Set<String> cateCheck       = new HashSet<String>();          // category の重複チェック
    088        private final int       hsCode  = Long.valueOf( System.nanoTime() ).hashCode() ;        // 5.1.9.0 (2010/08/01) equals,hashCode
    089
    090        private String[]        seriesLabels            ;
    091        private boolean         isColorCategory         ;                               // 6.0.2.2 (2014/10/03)
    092        private boolean         isParetoData            ;                               // 6.0.2.2 (2014/10/03)
    093
    094        private Number[][]      numdata                         ;
    095        private Color[]         categoryColor           ;
    096        private Range           range                           ;
    097
    098        /**
    099         * CategoryDataset を構築するに当たり、初期パラメータを設定します。
    100         *
    101         * @og.rev 6.0.2.2 (2014/10/03) 新規追加
    102         *
    103         * @param lbls  シリーズのラベル名配列
    104         * @param isColCate  カテゴリのカラー名の指定有無(true:使用する)
    105         * @param isPareto   パレート図用のDatasetとして処理するかどうか(true:処理する)
    106         */
    107        public void initParam( final String[] lbls , final boolean isColCate , final boolean isPareto ) {
    108                // 6.0.2.5 (2014/10/31) refactoring
    109//              seriesLabels    = lbls;
    110                if( lbls != null ) { seriesLabels = lbls.clone(); }
    111                isColorCategory = isColCate;
    112                isParetoData    = isPareto;
    113        }
    114
    115        /**
    116         * コネクションと、SQL文字列から、CategoryDataset のデータを作成します。
    117         * 元となる処理は、org.jfree.data.jdbc.JDBCCategoryDataset#executeQuery( Connection,String ) です。
    118         *
    119         * このメソッドでは、先に #initParam(String[],boolean,isPareto) のパラメータを使用して
    120         * 検索した結果のデータを加工、処理します。
    121         * また、内部的に、データをキャッシュする事と、データ範囲を示す レンジオブジェクト を作成します。
    122         *
    123         * @og.rev 6.0.2.2 (2014/10/03) 新規追加
    124         * @og.rev 6.0.2.3 (2014/10/19) パレート図は、100分率にする。
    125         * @og.rev 6.0.4.0 (2014/11/28) ResultSetValue を使用するように変更。
    126         * @og.rev 6.9.7.0 (2018/05/14) データ０件のときは、処理を中断します。 5.10.15.0(2019/08/30)で追加
    127         *
    128         * @param con  コネクション
    129         * @param query  SQL文字列
    130         *
    131         * @throws SQLException データベースアクセス時のエラー
    132         * @see         org.jfree.data.jdbc.JDBCCategoryDataset#executeQuery( Connection,String )
    133         * @see         org.opengion.fukurou.db.ResultSetValue
    134         */
    135        public void execute( final Connection con, final String query ) throws SQLException {
    136
    137                // Range を予め求めておきます。
    138                double minimum = Double.POSITIVE_INFINITY;
    139                double maximum = Double.NEGATIVE_INFINITY;
    140                double sum     = 0.0d;                                  // 6.0.2.3 (2014/10/19) パレート図用合計
    141
    142                List<Color> colorList = null;                     // 6.0.2.2 (2014/10/03) カテゴリカラー
    143
    144                Statement statement = null;
    145                ResultSet resultSet = null;
    146                try {
    147                        statement = con.createStatement();
    148                        resultSet = statement.executeQuery(query);
    149
    150                        // 6.0.4.0 (2014/11/28) ResultSetValue を使用するように変更。
    151//                      ResultSetMetaData metaData = resultSet.getMetaData();
    152                        final ResultSetValue rsv = new ResultSetValue( resultSet );
    153
    154//                      int dataSize = metaData.getColumnCount() -1;    // series の個数は、category 分を引いた数。
    155                        int dataSize = rsv.getColumnCount() -1;                 // series の個数は、category 分を引いた数。
    156                        if( isColorCategory ) {                                                 // ColorCategory使用時
    157                                colorList       = new ArrayList<Color>();         // カテゴリカラー
    158                                dataSize--;                                                                     // 最終カラムが Colorコードなので、マイナスする。
    159                        }
    160
    161                        if( dataSize<1 ) {
    162                                final String errMsg = "JDBCCategoryDataset.executeQuery() : insufficient columns "
    163                                                        + "returned from the database. \n"
    164                                                        + " SQL=" + query ;
    165                                throw new SQLException( errMsg );
    166                        }
    167
    168                        // 6.0.2.0 (2014/09/19) シリーズのラベル名配列を使うときは、シリーズ数必要。
    169                        if( seriesLabels != null && seriesLabels.length < dataSize ) {
    170                                final String errMsg = "seriesLabels を使用する場合は、必ずシリーズ数以上指定してください。"
    171                                                                + CR
    172                                                                + " seriesLabels=" + Arrays.toString( seriesLabels )
    173                                                                + CR
    174                                                                + " seriesLabels.length=" + seriesLabels.length
    175                                                                + " dataSize=" + dataSize
    176                                                                + CR ;
    177                                throw new IllegalArgumentException( errMsg );
    178                        }
    179
    180                        String[] series  = new String[dataSize];
    181                        // 6.0.4.0 (2014/11/28) ResultSetValue を使用するように変更。
    182                        final String[] names   = rsv.getNames();
    183//                      int[] columnType = new int[dataSize];
    184                        // ORACLEの引数は、配列＋１から始まるので、metaDataはi＋2から取得。series と、seriesLabels は０から始まる。
    185                        for( int i=0; i<dataSize; i++ ) {
    186                                series[i] = seriesLabels != null && seriesLabels[i] != null
    187                                                                        ? seriesLabels[i]
    188//                                                                      : metaData.getColumnLabel(i+2).toUpperCase( Locale.JAPAN );
    189                                                                        : names[i+1] ;
    190//                              columnType[i] = metaData.getColumnType(i+2);
    191                        }
    192
    193                        final List<Number[]> rowList = new ArrayList<Number[]>();
    194                        // 6.0.4.0 (2014/11/28) ResultSetValue を使用するように変更。
    195//                      while (resultSet.next()) {
    196                        while (rsv.next()) {
    197                                Number[] clmList = new Number[dataSize];
    198                                // first column contains the row key...
    199                                // 6.0.2.0 (2014/09/19) columnKeyは、series , rowKey は、category に変更する。
    200//                              String category = resultSet.getString(1);                                       // 4.3.3.6 (2008/11/15) Generics警告対応
    201                                final String category = uniqCategory( resultSet.getString(1) ); // 6.0.2.3 (2014/10/10) categoryの重複回避
    202
    203                                for( int i=0; i<dataSize; i++ ) {                                    // 6.0.2.2 (2014/10/03) dataSize 分回す。
    204                                        Number value = null;
    205                                        // 6.0.2.1 (2014/09/26) org.opengion.fukurou.db.DBUtil に、移動
    206                                        try {
    207                                                // JDBCのアドレス指定は、+2 する。(category 分と、ｱﾄﾞﾚｽが１から始まる為。)
    208//                                              value = DBUtil.getNumber( columnType[i],resultSet.getObject(i+2) );
    209                                                // ResultSetValueのカラム番号は、+1 する。(category 分があるため)
    210                                                value = rsv.getNumber( i+1 );
    211                                        }
    212                                        catch( SQLException ex ) {              // 6.0.4.0 (2014/11/28) ResultSetValue を使用するので。
    213                                                LogWriter.log( ex );
    214                                        }
    215                                        catch( RuntimeException ex ) {
    216                                                LogWriter.log( ex );
    217                                        }
    218
    219                                        clmList[i] = value;
    220                                        addValue(value, series[i], category);           // 6.0.2.0 (2014/09/19) columnKeyは、series , rowKey は、category に変更する。
    221                                        // Range 求め
    222                                        if( value != null ) {
    223                                                final double dbl = value.doubleValue();
    224                                                if( isParetoData ) {                                    // 6.0.2.3 (2014/10/19) パレート図用合計
    225                                                        sum += dbl ;
    226                                                } else {
    227                                                        if( dbl     < minimum ) { minimum = dbl; }
    228                                                        if( maximum < dbl     ) { maximum = dbl; }
    229                                                }
    230                                        }
    231                                }
    232                                rowList.add( clmList );
    233                                // 6.0.2.2 (2014/10/03) ColorCategory は、最後のカラム
    234                                if( isColorCategory ) {
    235                                        // 6.0.4.0 (2014/11/28) ResultSetValue を使用するように変更。
    236//                                      String colStr = resultSet.getString(dataSize+2);                // 最後のカラム
    237                                        final String colStr = rsv.getValue(dataSize+1);                         // 最後のカラム
    238                                        final Color color   = ColorMap.getColorInstance( colStr );      // 6.0.2.1 (2014/09/26) StringUtil → ColorMap
    239                                        colorList.add( color );
    240                                }
    241                        }
    242                        // 6.9.7.0 (2018/05/14) データ０件のときは、処理を中断します。
    243                        if( rowList.isEmpty() ) { return; }
    244
    245                        numdata = rowList.toArray( new Number[dataSize][rowList.size()] );
    246                }
    247                finally {
    248                        Closer.resultClose( resultSet );
    249                        Closer.stmtClose( statement );
    250                }
    251
    252                // colorList が null でないかどうかで判定。
    253                if( isColorCategory && colorList != null ) {
    254                        categoryColor = colorList.toArray( new Color[colorList.size()] );
    255                }
    256
    257                // 6.0.2.3 (2014/10/19) パレート図は、100分率にする。
    258//              if( isParetoData ) { maximum = changeParetoData(); }
    259                if( isParetoData ) {
    260                        changeParetoData( sum );
    261                        minimum = 0.0;
    262                        maximum = 100.0;
    263                }
    264
    265                range = new Range( minimum, maximum );
    266        }
    267
    268        /**
    269         * DBTableModelオブジェクトから、CategoryDataset のデータを作成します。
    270         * openGionの独自処理メソッドです。
    271         *
    272         * このメソッドでは、先に #initParam(String[],boolean,isPareto) のパラメータを使用して
    273         * 検索した結果のデータを加工、処理します。
    274         * また、内部的に、データをキャッシュする事と、データ範囲を示す レンジオブジェクト を作成します。
    275         *
    276         * @og.rev 6.0.2.2 (2014/10/03) 新規追加
    277         * @og.rev 6.0.2.3 (2014/10/19) パレート図は、100分率にする。
    278         * @og.rev 6.9.7.0 (2018/05/14) データ０件のときは、処理を中断します。 5.10.15.0(2019/08/30)追加
    279         *
    280         * @param table DBTableModelオブジェクト
    281         * @see         #execute( Connection,String )
    282         */
    283        public void execute( final DBTableModel table ) {
    284                // 6.9.7.0 (2018/05/14) データ０件のときは、処理を中断します。
    285                if( table == null || table.getRowCount() == 0 ) { return; }
    286
    287                final int clmNo = table.getColumnCount();
    288                final int rowNo = table.getRowCount();
    289
    290                // Range を予め求めておきます。
    291                double minimum = Double.POSITIVE_INFINITY;
    292                double maximum = Double.NEGATIVE_INFINITY;
    293                double sum     = 0.0d;                                  // 6.0.2.3 (2014/10/19) パレート図用合計
    294
    295                int dataSize = clmNo -1;                                                // series の個数は、category 分を引いた数。
    296                List<Color> colorList = null;                     // 6.0.2.2 (2014/10/03) カテゴリカラー
    297                if( isColorCategory ) {                                                 // ColorCategory使用時
    298                        colorList       = new ArrayList<Color>();         // カテゴリカラー
    299                        dataSize--;                                                                     // 最終カラムが Colorコードなので、マイナスする。
    300                }
    301
    302                numdata = new Number[rowNo][clmNo];
    303
    304                // ※ DBTableModel の row,col と、Dataset の row,col は、逆になっています。
    305                for( int row=0; row<rowNo; row++ ) {
    306//                      String   category = table.getValue( row,0 );                                    // １番目(アドレス=0)はカラムの設定値
    307                        final String   category = uniqCategory( table.getValue( row,0 ) );      // 6.0.2.3 (2014/10/10) categoryの重複回避
    308                        final String[] vals     = table.getValues( row );
    309                        for( int clm=0; clm<dataSize; clm++ ) {
    310                                final String sval = vals[clm+1];                                // ２番目(アドレス=1)からカラムデータを取得
    311                                final double val  = ( sval == null || sval.isEmpty() ) ? 0.0d : Double.parseDouble( sval ) ;
    312
    313                                addValue( val , seriesLabels[clm] , category );         // val,row,clm
    314//                              numdata[row][clm] = new Double( val );
    315                                numdata[row][clm] = Double.valueOf( val );                      // 6.0.2.4 (2014/10/17) 効率の悪いメソッド
    316                                // Range 求め
    317                                if( isParetoData ) {                                    // 6.0.2.3 (2014/10/19) パレート図用合計
    318                                        sum += val ;
    319                                } else {
    320                                        if( val     < minimum ) { minimum = val; }
    321                                        if( maximum < val     ) { maximum = val; }
    322                                }
    323                        }
    324
    325                        // 6.0.2.2 (2014/10/03) ColorCategory は、最後のカラム
    326                        if( isColorCategory ) {
    327                                final String colStr = vals[dataSize+1];                 // 最後のカラム
    328                                final Color color   = ColorMap.getColorInstance( colStr );      // 6.0.2.1 (2014/09/26) StringUtil → ColorMap
    329                                colorList.add( color );
    330                        }
    331                }
    332
    333                // colorList が null でないかどうかで判定。
    334                if( isColorCategory && colorList != null ) {
    335                        categoryColor = colorList.toArray( new Color[colorList.size()] );
    336                }
    337
    338                // 6.0.2.3 (2014/10/19) パレート図は、100分率にする。
    339//              if( isParetoData ) { maximum = changeParetoData(); }
    340                if( isParetoData ) {
    341                        changeParetoData( sum );
    342                        minimum = 0.0;
    343                        maximum = 100.0;
    344                }
    345
    346                range = new Range( minimum, maximum );
    347        }
    348
    349        /**
    350         * 指定された行列から、数字オブジェクトを取得します。
    351         *
    352         * @param       row     行番号(シリーズ：横持=clm相当)
    353         * @param       column  カラム番号(カテゴリ：縦持ち=row相当)
    354         *
    355         * @return      指定の行列の値
    356         */
    357        @Override
    358        public Number getValue( final int row, final int column ) {
    359                // 注意：行列の順序が逆です。
    360                return numdata[column][row];
    361        }
    362
    363        /**
    364         * レンジオブジェクトを取得します。(独自メソッド)
    365         *
    366         * @return      レンジオブジェクト
    367         */
    368        public Range getRange() {
    369                return range;
    370        }
    371
    372        /**
    373         * パレート図用のDatasetに値を書き換えます。(独自メソッド)
    374         *
    375         * 色々と方法はあると思いますが、簡易的に、内部の Number配列を
    376         * 積上げ計算して、パレート図用のデータを作成します。
    377         * レンジオブジェクト も変更します。
    378         *
    379         * ※ 注意：親クラスの内部に持っている実データは変更されていないので、
    380         * 場合によっては、おかしな動きをするかもしれません。
    381         * その場合は、上位にもデータをセットするように変更する必要があります。
    382         *
    383         * なお、行列の順序が、イメージと異なりますので、注意願います。
    384         * (columnは、series , row は、category で、シリーズを積み上げます)
    385         *
    386         * @og.rev 6.0.2.1 (2014/09/26) 新規追加
    387         * @og.rev 6.0.2.2 (2014/10/03) HybsDataset i/f
    388         * @og.rev 6.0.2.3 (2014/10/19) パレート図は、100分率にする。
    389         *
    390         * @param  sum データの合計
    391         */
    392//      private double changeParetoData() {
    393        private void changeParetoData( final double sum ) {
    394//              if( numdata == null || numdata.length == 0 || numdata[0].length == 0 ) { return 0.0d; }
    395                if( numdata == null || numdata.length == 0 || numdata[0].length == 0 || sum == 0.0 ) { return ; }
    396
    397                final int rowCnt = numdata[0].length ;
    398                final int clmCnt = numdata.length ;
    399
    400//              double maximum = Double.NEGATIVE_INFINITY;
    401                for( int rowNo=0; rowNo<rowCnt; rowNo++ ) {                  // 行列が逆。
    402                        double val = 0.0;               // 初期値
    403                        for( int clmNo=0; clmNo<clmCnt; clmNo++ ) {          // 積上げ計算するカラムでループを回す。
    404                                final Number v1Num = numdata[clmNo][rowNo];
    405                                if(v1Num != null) {
    406                                        val += v1Num.doubleValue();                             // 積上げ計算は、元の値のままにしておきます。
    407                                }
    408                                // データをセットするときに、１００分率にします。
    409//                              numdata[clmNo][rowNo] = new Double(val);
    410                                numdata[clmNo][rowNo] = Double.valueOf( Math.round( val * 1000.0 / sum ) / 10.0 );
    411        // きちんと計算するなら、BigDecimal で、スケールを指定して四捨五入すべき・・・かも
    412        //                      java.math.BigDecimal bd = new BigDecimal( val * 100.0 / sum );
    413        //                      numdata[clmNo][rowNo] = bd.setScale( 1, java.math.RoundingMode.HALF_UP );
    414                        }
    415//                      if( maximum < val ) { maximum = val; }                       // パレート図用の積上げなので、最大値は、最後のデータ
    416                }
    417
    418//              return maximum;
    419        }
    420
    421        /**
    422         * categoryカラー配列を取得します。(独自メソッド)
    423         *
    424         * このクラスは、一番最後のカラムを、色文字列として処理し、categoryにColorを指定できます。
    425         * select文で指定されていなかった場合は、null を返します。
    426         *
    427         * select category,series1,series2,series3,･･･,color from ･･･
    428         *
    429         * @og.rev 6.0.2.2 (2014/10/03) 新規追加
    430         *
    431         * なお、Colorコードは、このクラスで作成しますが、Renderer に与える必要があります。
    432         * 通常のRenderer には、categoryにカラーを指定する機能がありませんので、HybsBarRenderer に
    433         * setCategoryColor( Color[] ) メソッドを用意します。(正確には、HybsDrawItem インターフェース)
    434         * このRenderer で、getItemPaint( int  , int )メソッドをオーバーライドすることで、カテゴリごとの
    435         * 色を返します。
    436         * この設定を行うと、シリーズは、カテゴリと同一色になります。
    437         *
    438         * @return      categoryカラー配列(なければ null)
    439         */
    440        public Color[] getCategoryColor() {
    441                // 6.0.2.5 (2014/10/31) refactoring
    442//              return categoryColor;
    443                return ( categoryColor == null ) ? null : categoryColor.clone();
    444        }
    445
    446        /**
    447         * category の重複をさけて、必要であれば、新しいカテゴリ名を作成します。
    448         *
    449         * カテゴリが同じ場合、JFreeChartでは、表示されません。これは、同じカテゴリと認識され
    450         * 値が上書きされるためです。
    451         * この問題は、なかなか気づきにくく、デバッグ等に時間がかかってしまいます。
    452         * 重複チェックを行い、警告してもよいのですが、ここでは、新しいカテゴリ名を作成することで
    453         * エラーを回避しつつ、とりあえずグラフ表示をするようにします。
    454         *
    455         * @og.rev 6.0.2.3 (2014/10/10) 新規追加
    456         *
    457         * @param       category        元のカテゴリ名
    458         * @return      新しい元のカテゴリ名
    459         */
    460        private String uniqCategory( final String category ) {
    461                String newCate = category ;
    462                int i = 0;
    463                while( !cateCheck.add( newCate ) ) {    // すでに存在している場合。
    464                        newCate = category + "(" + (i++) + ")" ;
    465                }
    466
    467                return newCate ;
    468        }
    469
    470        /**
    471         * この文字列と指定されたオブジェクトを比較します。
    472         *
    473         * 親クラスで、equals メソッドが実装されているため、警告がでます。
    474         *
    475         * @og.rev 5.1.8.0 (2010/07/01) findbug対応
    476         * @og.rev 5.1.9.0 (2010/08/01) findbug対応
    477         *
    478         * @param       object  比較するオブジェクト
    479         *
    480         * @return      Objectが等しい場合は true、そうでない場合は false
    481         */
    482        @Override
    483        public boolean equals( final Object object ) {
    484                if( super.equals( object ) ) {
    485                        return hsCode == ((HybsCategoryDataset)object).hsCode;
    486                }
    487                return false;
    488        }
    489
    490        /**
    491         * このオブジェクトのハッシュコードを取得します。
    492         *
    493         * @og.rev 5.1.8.0 (2010/07/01) findbug対応
    494         * @og.rev 5.1.9.0 (2010/08/01) findbug対応
    495         *
    496         * @return      ハッシュコード
    497         */
    498        @Override
    499        public int hashCode() { return hsCode ; }
    500}