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の {@カラム} 解析情報 を管理するローカルクラスです。
022 *
023 * このクラスは、雛形EXCELより取得した、{@カラム} および、{@カラム_枝番}より
024 * カラム、行番号、列番号、枝番を取り出し、セルと1対1で管理する為のクラスです。
025 * 枝番が付かないカラムは、ヘッダー情報になる為、枝番を、−1 で設定します。
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//      public int compareTo( final Object object ) {
208        @Override
209        public int compareTo( final ExcelLayoutData other ) {
210                if( uniqKey.equals( other.uniqKey ) ) { return 0; }
211
212//              if( object instanceof ExcelLayoutData ) {
213//                      ExcelLayoutData other = (ExcelLayoutData)object ;
214                        if( edbn  != other.edbn ) { return edbn - other.edbn; }
215                        if( ! clm.equals( other.clm ) ) { return clm.compareTo( other.clm ); }
216                        if( rowNo  != other.rowNo ) { return rowNo - other.rowNo; }
217                        return colNo - other.colNo;
218//              }
219//              throw new ClassCastException();
220        }
221
222        /**
223         * このクラスの文字列表現を返します。
224         *
225         * 内部文字列(uniqKey)と同じ値です。
226         * ヘッダー:clm + ":[" + rowNo + "," + colNo + "]"
227         * 明細    :clm + "_" + edbn + ":[" + rowNo + "," + colNo + "]"
228         *
229         * @return      文字列表現
230         */
231        @Override
232        public String toString() {
233                return uniqKey;
234        }
235}