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     */
016    package org.opengion.hayabusa.report2;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    
021    import org.opengion.hayabusa.common.HybsSystemException;
022    
023    /**
024     * シート単位ã?content.xmlを管ç�?�™るためã?クラスですã?
025     * シートã?ヘッãƒ??、行ã?配å?、フãƒ?‚¿ー及ã?シート名を管ç�?�—ますã?
026     *
027     * @og.group 帳票シスãƒ?ƒ 
028     *
029     * @version  4.0
030     * @author   Hiroki.Nakamura
031     * @since    JDK1.6
032     */
033    class OdsSheet {
034    
035            //======== content.xmlのパã?スで使用 ========================================
036    
037            /* 行ã?開始終äº?‚¿グ */
038            private static final String ROW_START_TAG = "<table:table-row ";
039            private static final String ROW_END_TAG = "</table:table-row>";
040    
041            /* シート名を取得するためã?開始終äº?–‡å­?*/
042            private static final String SHEET_NAME_START = "table:name=\"";
043            private static final String SHEET_NAME_END = "\"";
044    
045            /* 変数定義の開始終äº?–‡字及び区åˆ?‚Šæ–?­?*/
046            private static final String VAR_START = "{@";
047            private static final String VAR_END = "}";
048            private static final String VAR_CON = "_";
049    
050            /* ラインコピã?æ–?­—å? 5.0.0.2 (2009/09/15) */
051            private static final String LINE_COPY = "LINECOPY";
052    
053            private final List<String>        sheetRows       = new ArrayList<String>();
054            private String                  sheetHeader;
055            private String                  sheetFooter;
056            private String                  sheetName;
057            private String                  origSheetName;
058            private String                  confSheetName;
059    
060            /**
061             * シートを行単位にåˆ?§£しますã?
062             *
063             * @og.rev 5.0.0.2 (2009/09/15) ボディ部のカウントを引数に追åŠ?�—、LINECOPY機è?実è£??
064             * @og.rev 5.2.1.0 (2010/10/01) シート名定義対å¿?
065             *
066             * @param sheet シート名
067             * @param bodyRowCount 行番号
068             */
069            public void analyze( final String sheet, final int bodyRowCount ) {
070                    String[] tags = TagParser.tag2Array( sheet, ROW_START_TAG, ROW_END_TAG );
071                    sheetHeader = tags[0];
072                    sheetFooter = tags[1];
073                    for( int i = 2; i < tags.length; i++ ) {
074                            sheetRows.add( tags[i] );
075                            lineCopy( tags[i], bodyRowCount ); // 5.0.0.2 (2009/09/15)
076                    }
077    
078                    sheetName = TagParser.getValueFromTag( sheetHeader, SHEET_NAME_START, SHEET_NAME_END );
079                    origSheetName = sheetName;
080    
081                    confSheetName = null;
082                    if( sheetName != null ) {
083                            int cnfIdx = sheetName.indexOf( "__" );
084                            if( cnfIdx > 0 && !sheetName.endsWith( "__" ) ) {
085                                    confSheetName = sheetName.substring( cnfIdx + 2 );
086                                    sheetName = sheetName.substring( 0, cnfIdx );
087                            }
088                    }
089            }
090    
091            /**
092             * ラインコピã?に関する処ç�?‚’行いますã?
093             *
094             * {&#064;LINE_COPY}が存在した場合に、テーブルモãƒ?ƒ«åˆ?� ã�?
095             * 行をコピã?しますã?
096             * そã?際ã?{&#064;xxx_y}のyをカウントアãƒ??してコピã?しますã?
097             *
098             * 整合æ?等ã?エラーハンドリングはこã?メソãƒ?ƒ‰では行わずã?
099             * 実際のパã?ス処ç�?¸­で行いますã?
100             *
101             * @og.rev 5.0.0.2 (2009/09/15) 追åŠ?
102             * @og.rev 5.1.8.0 (2010/07/01) パã?ス処ç�??å†?ƒ¨実è£?‚’変更
103             *
104             * @param row
105             * @param rowCount
106             */
107            private void lineCopy( final String row, final int rowCount ) {
108    //              int preOffset = -1;
109    //              int curOffset = -1;
110    //
111    //              preOffset = row.indexOf( VAR_START + LINE_COPY );
112    //              // こã?段階で存在しなければ即終äº?
113    //              if( preOffset < 0 ) { return; }
114    //
115    //              curOffset = row.indexOf( VAR_END, preOffset );
116    //              String lcKey = row.substring( preOffset + VAR_START.length(), curOffset );
117    //              StringBuilder tmpBuf = new StringBuilder( row );
118    //              if( LINE_COPY.equals( OdsParseUtil.checkKey( lcKey, tmpBuf ) ) ) {
119    //                      // 存在すればãƒ??ブルモãƒ?ƒ«行数-1回ルーãƒ?自身を除くたã‚?
120    //                      for( int i = 1; i < rowCount; i++ ) {
121    //                              tmpBuf = new StringBuilder();
122    //                              preOffset = -1;
123    //                              curOffset = 0;
124    //                              while( ( preOffset = row.indexOf( VAR_START, preOffset + 1 ) ) >= 0 ) {
125    //                                      tmpBuf.append( row.substring( curOffset, preOffset ) );
126    //                                      curOffset = row.indexOf( VAR_END, preOffset + 1 ) + VAR_END.length();
127    //
128    //                                      // {@XXXX_XX}のXXXX_XXの部åˆ?
129    //                                      String key = row.substring( preOffset + VAR_START.length(), curOffset - VAR_END.length() );
130    //                                      key = OdsParseUtil.checkKey( key, tmpBuf );
131    //                                      // 不整合ã?returnで何もしなã�?�§返しておく
132    //                                      int keyCheck = key.indexOf( '<' );
133    //                                      if( keyCheck >= 0 ) { return; }
134    //                                      tmpBuf.append( VAR_START ).append( incrementKey( key, i ) ).append( VAR_END );
135    //                              }
136    //                              tmpBuf.append( row.substring( curOffset, row.length() ) );
137    //
138    //                              sheetRows.add( tmpBuf.toString() ); // シートに追åŠ?
139    //                      }
140    //              }
141    
142                    // こã?段階で存在しなければ即終äº?
143                    int lcStrOffset = row.indexOf( VAR_START + LINE_COPY );
144                    if( lcStrOffset < 0 ) { return; }
145                    int lcEndOffset = row.indexOf( VAR_END, lcStrOffset );
146                    if( lcEndOffset < 0 ) { return; }
147    
148                    StringBuilder lcStrBuf = new StringBuilder( row );
149                    String lcKey = TagParser.checkKey( row.substring( lcStrOffset + VAR_START.length(), lcEndOffset ), lcStrBuf );
150                    if( lcKey == null || !LINE_COPY.equals( lcKey ) ) { return; }
151    
152                    // 存在すればãƒ??ブルモãƒ?ƒ«行数-1回ルーãƒ?自身を除くたã‚?
153                    for( int i = 1; i < rowCount; i++ ) {
154                            final int cRow = i;
155                            String rowStr = new TagParser() {
156                                    @Override
157                                    protected void exec( final String str, final StringBuilder buf, final int offset ) {
158                                            String key = TagParser.checkKey( str, buf );
159                                            if( key.indexOf( '<' ) >= 0 ){
160                                                    String errMsg = "[ERROR]PARSE:{@と}の整合æ?が不正ですã?変数å†??特定ã?æ–?­—å?に書式設定がされてã�?‚‹可能性がありますã?キー=" + key;
161                                                    throw new HybsSystemException( errMsg );
162                                            }
163                                            buf.append( VAR_START ).append( incrementKey( key, cRow ) ).append( VAR_END );
164                                    }
165                            }.doParse( lcStrBuf.toString(), VAR_START, VAR_END, false );
166                            sheetRows.add( rowStr );
167                    }
168            }
169    
170            /**
171             * xxx_yのy部åˆ?‚’引数åˆ?¿½åŠ?�—て返しますã?
172             * yが数字でなã�??合や、_が無ã�??合ã?そã?まま返しますã?
173             *
174             * @og.rev 5.0.0.2 LINE_COPYで利用するために追åŠ?
175             *
176             * @param key
177             * @param inc
178             *
179             * @return 変更後キー
180             */
181            private String incrementKey( final String key, final int inc ) {
182                    int conOffset = key.lastIndexOf( VAR_CON );
183                    if( conOffset < 0 ) { return key; }
184    
185                    String name = key.substring( 0, conOffset );
186                    int rownum = -1;
187                    try {
188                            rownum = Integer.valueOf( key.substring( conOffset + VAR_CON.length(), key.length() ) );
189                    }
190                    // エラーが起きてもなにもしなã�??
191                    catch( NumberFormatException ex ) {}
192    
193                    // アンãƒ??スコア後が数字に変換できなã�??合ã?ヘッãƒ?ƒ•ãƒ?‚¿として認è­?
194                    if( rownum < 0 ){ return key; }
195                    else                    { return name + VAR_CON + ( rownum + inc ); }
196            }
197    
198            /**
199             * シートã?ヘッãƒ??部åˆ?‚’返しますã?
200             *
201             * @return ヘッãƒ??
202             */
203            public String getHeader() {
204                    return sheetHeader;
205            }
206    
207            /**
208             * シートã?フッター部åˆ?‚’返しますã?
209             *
210             * @return フッター
211             */
212            public String getFooter() {
213                    return sheetFooter;
214            }
215    
216            /**
217             * シート名称を返しますã?
218             *
219             * @return シート名称
220             */
221            public String getSheetName() {
222                    return sheetName;
223            }
224    
225            /**
226             * 定義済シート名称を返しますã?
227             *
228             * @og.rev 5.2.1.0 (2010/10/01) シート名定義対å¿?
229             *
230             * @return 定義済シート名称
231             */
232            public String getConfSheetName() {
233                    return confSheetName;
234            }
235    
236            /**
237             * 定義名変換前ã?シート名称を返しますã?
238             *
239             * @og.rev 5.2.1.0 (2010/10/01) シート名定義対å¿?
240             *
241             * @return 定義済シート名称
242             */
243            public String getOrigSheetName() {
244                    return origSheetName;
245            }
246    
247            /**
248             * シートã?å�?¡Œを配å?で返しますã?
249             *
250             * @og.rev 4.3.1.1 (2008/08/23) あらかじめã?å¿?¦�な配å?の長さを確保しておきますã?
251             *
252             * @return シートã?å�?¡Œã?配å?
253             */
254            public String[] getRows() {
255                    return sheetRows.toArray( new String[sheetRows.size()] );
256            }
257    }
258