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.report2; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import 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 */ 033class 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 * {@LINE_COPY}が存在した場合に、テーブルモデル分だけ 095 * 行をコピーします。 096 * その際、{@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 // この段階で存在しなければ即終了 109 int lcStrOffset = row.indexOf( VAR_START + LINE_COPY ); 110 if( lcStrOffset < 0 ) { return; } 111 int lcEndOffset = row.indexOf( VAR_END, lcStrOffset ); 112 if( lcEndOffset < 0 ) { return; } 113 114 StringBuilder lcStrBuf = new StringBuilder( row ); 115 String lcKey = TagParser.checkKey( row.substring( lcStrOffset + VAR_START.length(), lcEndOffset ), lcStrBuf ); 116 if( lcKey == null || !LINE_COPY.equals( lcKey ) ) { return; } 117 118 // 存在すればテーブルモデル行数-1回ループ(自身を除くため) 119 for( int i = 1; i < rowCount; i++ ) { 120 final int cRow = i; 121 String rowStr = new TagParser() { 122 @Override 123 protected void exec( final String str, final StringBuilder buf, final int offset ) { 124 String key = TagParser.checkKey( str, buf ); 125 if( key.indexOf( '<' ) >= 0 ){ 126 String errMsg = "[ERROR]PARSE:{@と}の整合性が不正です。変数内の特定の文字列に書式設定がされている可能性があります。キー=" + key; 127 throw new HybsSystemException( errMsg ); 128 } 129 buf.append( VAR_START ).append( incrementKey( key, cRow ) ).append( VAR_END ); 130 } 131 }.doParse( lcStrBuf.toString(), VAR_START, VAR_END, false ); 132 sheetRows.add( rowStr ); 133 } 134 } 135 136 /** 137 * xxx_yのy部分を引数分追加して返します。 138 * yが数字でない場合や、_が無い場合はそのまま返します。 139 * 140 * @og.rev 5.0.0.2 LINE_COPYで利用するために追加 141 * 142 * @param key 143 * @param inc 144 * 145 * @return 変更後キー 146 */ 147 private String incrementKey( final String key, final int inc ) { 148 int conOffset = key.lastIndexOf( VAR_CON ); 149 if( conOffset < 0 ) { return key; } 150 151 String name = key.substring( 0, conOffset ); 152 int rownum = -1; 153 try { 154 rownum = Integer.valueOf( key.substring( conOffset + VAR_CON.length(), key.length() ) ); 155 } 156 // エラーが起きてもなにもしない。 157 catch( NumberFormatException ex ) {} 158 159 // アンダースコア後が数字に変換できない場合はヘッダフッタとして認識 160 if( rownum < 0 ){ return key; } 161 else { return name + VAR_CON + rownum + inc ; } 162 } 163 164 /** 165 * シートのヘッダー部分を返します。 166 * 167 * @return ヘッダー 168 */ 169 public String getHeader() { 170 return sheetHeader; 171 } 172 173 /** 174 * シートのフッター部分を返します。 175 * 176 * @return フッター 177 */ 178 public String getFooter() { 179 return sheetFooter; 180 } 181 182 /** 183 * シート名称を返します。 184 * 185 * @return シート名称 186 */ 187 public String getSheetName() { 188 return sheetName; 189 } 190 191 /** 192 * 定義済シート名称を返します。 193 * 194 * @og.rev 5.2.1.0 (2010/10/01) シート名定義対応 195 * 196 * @return 定義済シート名称 197 */ 198 public String getConfSheetName() { 199 return confSheetName; 200 } 201 202 /** 203 * 定義名変換前のシート名称を返します。 204 * 205 * @og.rev 5.2.1.0 (2010/10/01) シート名定義対応 206 * 207 * @return 定義済シート名称 208 */ 209 public String getOrigSheetName() { 210 return origSheetName; 211 } 212 213 /** 214 * シートの各行を配列で返します。 215 * 216 * @og.rev 4.3.1.1 (2008/08/23) あらかじめ、必要な配列の長さを確保しておきます。 217 * 218 * @return シートの各行の配列 219 */ 220 public String[] getRows() { 221 return sheetRows.toArray( new String[sheetRows.size()] ); 222 } 223} 224