    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.util.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    hashcode ;
    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                        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                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 (NumberFormatException e) {       // ヘッダーにアンダーバーが使用されているケース
    080                                String errMsg2 = "ヘッダーにアンダーバーが使用されています。[" + tempClm + "]" ;
    081                                LogWriter.log( errMsg2 );
    082                        }
    083                }
    084
    085                edbn = tempEdbn;
    086                clm  = tempClm;
    087
    088                if( edbn < 0 ) {
    089                        uniqKey = clm + ":[" + rowNo + "," + colNo + "]" ;
    090                }
    091                else {
    092                        uniqKey = clm + "_" + edbn + ":[" + rowNo + "," + colNo + "]" ;
    093                }
    094                hashcode = uniqKey.hashCode() ;
    095        }
    096
    097        /**
    098         * 内部コンストラクター
    099         *
    100         * 雛形EXCELの{&#064;カラム}を含むセルの値と、行列番号を設定します。
    101         * 内部で、カラムと枝番に分解します。
    102         *
    103         * @param       other           ExcelLayoutDataオブジェクト
    104         * @param       newRowNo        行番号
    105         * @param       newEdbn         列番号
    106         */
    107        private ExcelLayoutData( final ExcelLayoutData other , final int newRowNo, final int newEdbn ) {
    108                key   = other.key;
    109                rowNo = newRowNo;
    110                colNo = other.colNo;
    111
    112                edbn = newEdbn;
    113                clm  = other.clm;
    114
    115                if( edbn < 0 ) {
    116                        uniqKey = clm + ":[" + rowNo + "," + colNo + "]" ;
    117                }
    118                else {
    119                        uniqKey = clm + "_" + edbn + ":[" + rowNo + "," + colNo + "]" ;
    120                }
    121                hashcode = uniqKey.hashCode() ;
    122        }
    123
    124        /**
    125         * 枝番を取得します。
    126         *
    127         * @return      ハッシュコード
    128         */
    129        public int getEdbn() { return edbn ; }
    130
    131        /**
    132         * カラム名を取得します。
    133         *
    134         * @return      カラム名
    135         */
    136        public String getClm() { return clm ; }
    137
    138        /**
    139         * 行番号を取得します。
    140         *
    141         * @return      行番号
    142         */
    143        public int getRowNo() { return rowNo ; }
    144
    145        /**
    146         * 列番号を取得します。
    147         *
    148         * @return      列番号
    149         */
    150        public short getColNo() { return colNo ; }
    151
    152        /**
    153         * 登録時のオリジナルのキー({&#064;カラム_枝番})を取得します。
    154         *
    155         * @return      オリジナルのキー
    156         */
    157        public String getKey() { return key ; }
    158
    159        /**
    160         * 行番号と枝番が異なる新しい ExcelLayoutData を返します。
    161         *
    162         * @param       newRowNo        行番号
    163         * @param       newEdbn         枝番
    164         *
    165         * @return      新しいExcelLayoutData
    166         */
    167        public ExcelLayoutData copy( final int newRowNo, final int newEdbn ) {
    168                return new ExcelLayoutData( this,newRowNo,newEdbn );
    169        }
    170
    171        /**
    172         * このオブジェクトのハッシュコードを取得します。
    173         * 内部文字列(uniqKey)のハッシュコードと同じ値です。
    174         *
    175         * @return      ハッシュコード
    176         */
    177        @Override
    178        public int hashCode() { return hashcode ; }
    179
    180        /**
    181         * この文字列と指定されたオブジェクトを比較します。
    182         *
    183         * 引数が null でなく、このオブジェクトと同じ内部文字列(uniqKey)を持つ
    184         * ExcelLayoutData オブジェクトである場合にだけ、結果は true になります。
    185         *
    186         * @param       object  比較するオブジェクト
    187         *
    188         * @return      Objectが等しい場合は true、そうでない場合は false
    189         */
    190        @Override
    191        public boolean equals( final Object object ) {
    192                if( object instanceof ExcelLayoutData ) {
    193                        return uniqKey.equals( ((ExcelLayoutData)object).uniqKey ) ;
    194                }
    195                return false ;
    196        }
    197
    198        /**
    199         * 自然比較メソッド
    200         * インタフェース Comparable の 実装です。
    201         * edbn 、clm 、rowNo 、colNo の順で比較します。
    202         *
    203         * @param       other   比較対象のObject
    204         *
    205         * @return      このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数
    206         */
    207        @Override
    208        public int compareTo( final ExcelLayoutData other ) {
    209                if( uniqKey.equals( other.uniqKey ) ) { return 0; }
    210
    211                if( edbn  != other.edbn ) { return edbn - other.edbn; }
    212                if( ! clm.equals( other.clm ) ) { return clm.compareTo( other.clm ); }
    213                if( rowNo  != other.rowNo ) { return rowNo - other.rowNo; }
    214                return colNo - other.colNo;
    215        }
    216
    217        /**
    218         * このクラスの文字列表現を返します。
    219         *
    220         * 内部文字列(uniqKey)と同じ値です。
    221         * ヘッダー：clm + ":[" + rowNo + "," + colNo + "]"
    222         * 明細    ：clm + "_" + edbn + ":[" + rowNo + "," + colNo + "]"
    223         *
    224         * @return      文字列表現
    225         */
    226        @Override
    227        public String toString() {
    228                return uniqKey;
    229        }
    230}