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の {@カラム} 解析情報 を管理するローカルクラスです。
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               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}