    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.report;
    017
    018import org.opengion.fukurou.system.LogWriter;
    019
    020/**
    021 * 雛形EXCELの {&#064;カラム} 解析情報 を管理するローカルクラスです。
    022 *
    023 * このクラスは、雛形EXCELより取得した、{&#064;カラム} および、{&#064;カラム_枝番}より
    024 * カラム、行番号、列番号、枝番を取り出し、セルと１対１で管理する為のクラスです。
    025 * 枝番が付かないカラムは、ヘッダー情報になる為、枝番を、－１ で設定します。
    026 * シート単位に呼び出す必要があります。
    027 *
    028 * ｢注意：このクラスは、equals と一致しない自然な順序を持っています。｣
    029 *
    030 * @og.group 帳票システム
    031 *
    032 * @version  4.0
    033 * @author   Kazuhiko Hasegawa
    034 * @since    JDK5.0,
    035 */
    036public class ExcelLayoutData implements Comparable<ExcelLayoutData> {
    037        private final int               edbn    ;
    038        private final String    key             ;
    039        private final String    clm             ;
    040        private final int               rowNo   ;
    041        private final short             colNo   ;
    042
    043        private final String    uniqKey ;
    044        private final int               hcode   ;                       // 6.4.1.1 (2016/01/16) PMD refactoring. Field hashcode has the same name as a method
    045
    046        /**
    047         * コンストラクター
    048         *
    049         * 雛形EXCELの{&#064;カラム}を含むセルの値と、行列番号を設定します。
    050         * 整合性チェックの条件は、先頭が "{&#064;" で、最後が、"}" で、文字列の途中に、
    051         * "{&#064;" が含まれていない場合のみとします。
    052         *
    053         * 内部で、カラムと枝番に分解します。
    054         *
    055         * @param       inkey   処理カラム({&#064;カラム}形式)
    056         * @param       rowNo   行番号
    057         * @param       colNo   列番号
    058         */
    059        public ExcelLayoutData( final String inkey , final int rowNo ,final short colNo ) {
    060                this.key   = inkey.trim();
    061                this.rowNo = rowNo;
    062                this.colNo = colNo;
    063
    064                if( ! key.startsWith( "{@" ) || !key.endsWith( "}" ) ) {
    065                        final String errMsg = "指定のセルのカラム定義が不正です。"
    066                                                + "row,col=[" + rowNo + "," + colNo + "] , key=[" + key + "]" ;
    067                        throw new IllegalArgumentException( errMsg );
    068                }
    069
    070                String tempClm = key.substring( 2,key.length()-1 );     // {@AAA_X} を AAA_X に変換する。
    071                final int idx = tempClm.lastIndexOf( '_' );
    072                int tempEdbn = -1;
    073
    074                if( idx > 0 ) {
    075                        try {
    076                                tempEdbn = Integer.parseInt( tempClm.substring( idx+1 ) );
    077                                tempClm  = tempClm.substring( 0,idx );
    078                        }
    079                        catch( final NumberFormatException ex ) {       // ヘッダーにアンダーバーが使用されているケース
    080//                              final String errMsg2 = "ヘッダーにアンダーバーが使用されています。[" + tempClm + "]" ;
    081                                final String errMsg2 = "ヘッダーにアンダーバーが使用されています。[" + tempClm + "] ERR=" + ex.getMessage() ;                // 6.9.7.0 (2018/05/14) PMD
    082                                LogWriter.log( errMsg2 );
    083                        }
    084                }
    085
    086                edbn = tempEdbn;
    087                clm  = tempClm;
    088
    089                if( edbn < 0 ) {
    090                        uniqKey = clm + ":[" + rowNo + "," + colNo + "]" ;
    091                }
    092                else {
    093                        uniqKey = clm + "_" + edbn + ":[" + rowNo + "," + colNo + "]" ;
    094                }
    095                hcode = uniqKey.hashCode() ;
    096        }
    097
    098        /**
    099         * 内部コンストラクター
    100         *
    101         * 雛形EXCELの{&#064;カラム}を含むセルの値と、行列番号を設定します。
    102         * 内部で、カラムと枝番に分解します。
    103         *
    104         * @param       other           ExcelLayoutDataオブジェクト
    105         * @param       newRowNo        行番号
    106         * @param       newEdbn         列番号
    107         */
    108        private ExcelLayoutData( final ExcelLayoutData other , final int newRowNo, final int newEdbn ) {
    109                key   = other.key;
    110                rowNo = newRowNo;
    111                colNo = other.colNo;
    112
    113                edbn = newEdbn;
    114                clm  = other.clm;
    115
    116                if( edbn < 0 ) {
    117                        uniqKey = clm + ":[" + rowNo + "," + colNo + "]" ;
    118                }
    119                else {
    120                        uniqKey = clm + "_" + edbn + ":[" + rowNo + "," + colNo + "]" ;
    121                }
    122                hcode = uniqKey.hashCode() ;
    123        }
    124
    125        /**
    126         * 枝番を取得します。
    127         *
    128         * @return      ハッシュコード
    129         */
    130        public int getEdbn() { return edbn ; }
    131
    132        /**
    133         * カラム名を取得します。
    134         *
    135         * @return      カラム名
    136         */
    137        public String getClm() { return clm ; }
    138
    139        /**
    140         * 行番号を取得します。
    141         *
    142         * @return      行番号
    143         */
    144        public int getRowNo() { return rowNo ; }
    145
    146        /**
    147         * 列番号を取得します。
    148         *
    149         * @return      列番号
    150         */
    151        public short getColNo() { return colNo ; }
    152
    153        /**
    154         * 登録時のオリジナルのキー({&#064;カラム_枝番})を取得します。
    155         *
    156         * @return      オリジナルのキー
    157         */
    158        public String getKey() { return key ; }
    159
    160        /**
    161         * 行番号と枝番が異なる新しい ExcelLayoutData を返します。
    162         *
    163         * @param       newRowNo        行番号
    164         * @param       newEdbn         枝番
    165         *
    166         * @return      新しいExcelLayoutData
    167         * @og.rtnNotNull
    168         */
    169        public ExcelLayoutData copy( final int newRowNo, final int newEdbn ) {
    170                return new ExcelLayoutData( this,newRowNo,newEdbn );
    171        }
    172
    173        /**
    174         * このオブジェクトのハッシュコードを取得します。
    175         * 内部文字列(uniqKey)のハッシュコードと同じ値です。
    176         *
    177         * @return      ハッシュコード
    178         */
    179        @Override
    180        public int hashCode() { return hcode ; }
    181
    182        /**
    183         * この文字列と指定されたオブジェクトを比較します。
    184         *
    185         * 引数が null でなく、このオブジェクトと同じ内部文字列(uniqKey)を持つ
    186         * ExcelLayoutData オブジェクトである場合にだけ、結果は true になります。
    187         *
    188         * @param       object  比較するオブジェクト
    189         *
    190         * @return      Objectが等しい場合は true、そうでない場合は false
    191         */
    192        @Override
    193        public boolean equals( final Object object ) {
    194                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    195                return object instanceof ExcelLayoutData && uniqKey.equals( ((ExcelLayoutData)object).uniqKey ) ;
    196
    197        }
    198
    199        /**
    200         * 自然比較メソッド
    201         * インタフェース Comparable の 実装です。
    202         * edbn 、clm 、rowNo 、colNo の順で比較します。
    203         *
    204         * @param       other   比較対象のObject
    205         *
    206         * @return      このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数
    207         */
    208        @Override
    209        public int compareTo( final ExcelLayoutData other ) {
    210                if( uniqKey.equals( other.uniqKey ) ) { return 0; }
    211
    212                if( edbn  != other.edbn ) { return edbn - other.edbn; }
    213                if( ! clm.equals( other.clm ) ) { return clm.compareTo( other.clm ); }
    214                if( rowNo  != other.rowNo ) { return rowNo - other.rowNo; }
    215                return colNo - other.colNo;
    216        }
    217
    218        /**
    219         * このクラスの文字列表現を返します。
    220         *
    221         * 内部文字列(uniqKey)と同じ値です。
    222         * ヘッダー：clm + ":[" + rowNo + "," + colNo + "]"
    223         * 明細    ：clm + "_" + edbn + ":[" + rowNo + "," + colNo + "]"
    224         *
    225         * @return      文字列表現
    226         */
    227        @Override
    228        public String toString() {
    229                return uniqKey;
    230        }
    231}