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.io.BufferedReader;
019    import java.io.BufferedWriter;
020    import java.io.File;
021    import java.io.FileInputStream;
022    import java.io.FileNotFoundException;
023    import java.io.FileOutputStream;
024    import java.io.IOException;
025    import java.io.InputStreamReader;
026    import java.io.OutputStreamWriter;
027    import java.io.UnsupportedEncodingException;
028    import java.nio.channels.FileChannel;
029    import java.util.ArrayList;
030    import java.util.HashMap;
031    import java.util.List;
032    import java.util.Locale;
033    import java.util.Map;
034    import java.util.Set;
035    
036    import org.opengion.fukurou.model.NativeType;
037    import org.opengion.fukurou.util.Closer;
038    import org.opengion.fukurou.util.FileUtil;
039    import org.opengion.fukurou.util.QrcodeImage;
040    import org.opengion.hayabusa.common.HybsSystem;
041    import org.opengion.hayabusa.common.HybsSystemException;
042    
043    /**
044     * æŒ?®šã•れãŸãƒ‘スã«å­˜åœ¨ã™ã‚‹ODSã®å„XMLファイルをパースã—ã?帳票定義åŠã?
045     * 帳票ãƒ??ã‚¿ã‹ã‚‰æ›¸ãæ›ãˆã¾ã™ã?
046     * æ›¸ãæ›ãˆã?読ã¿å–り先ã¨åŒã˜ãƒ•ァイルã§ã‚ã‚‹ãŸã‚ã€ä¸?—¦èª­ã¿å–ã£ãŸå„XMLã‚?
047     * ãƒ¡ãƒ¢ãƒªä¸Šã«æ ¼ç´ã—ãŸã‹ã‚‰ãƒ‘ース後ã?XMLãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã‚’行ã„ã¾ã™ã?
048     *
049     * パã?ス対象ã¨ãªã‚‹ãƒ•ァイルã¯ä»¥ä¸‹ã?3ã¤ã§ã™ã?
050     *  content.xml シートã?中身を定義
051     *  meta.xml    メタ�?タを定義
052     *  style.xml   帳票ヘッ�?フッターを定義
053     *
054     * content.xmlã®ãƒ‘ã?ス処ç?¨ã—ã¦ã€ã¾ãšxmlファイルをシーãƒ?行å˜ä½ã«åˆ?§£ã—ã¾ã™ã?
055     * ãã?後ã?åˆ?§£ã•れãŸè¡Œæ¯Žã«å¸³ç¥¨ãƒ??タを埋ã‚è¾¼ã¿ã€å?力å?ã®XMLã«æ›¸ãè¾¼ã¿ã‚’行ã„ã¾ã™ã?
056     * 書ãè¾¼ã¿ã¯è¡Œå˜ä½ã«è¡Œã‚れã¾ã™ã?
057     *
058     * ã¾ãŸã?Calcã®ç‰¹æ€§ã¨ã—ã¦ã€?–¢æ•°ã®å¼•æ•°ã«ä¸æ­£ãªå¼•æ•°ãŒæŒ‡å®šã•れãŸå ´åˆã?(Text関数ã®
059     * 引数ã«nullãŒæŒ‡å®šã•れãŸå ´åˆç­?ã€ã‚¨ãƒ©ãƒ¼:XXXã¨ã?†æ–?­—ãŒè¡¨ç¤ºã•れã¾ã™ã?
060     * ã“ã“ã§ã¯ã€ã“れを回é¿ã™ã‚‹ãŸã‚ã€å?ã¦ã®é–¢æ•°ã«isError関数を埋ã‚è¾¼ã¿ã€ã‚¨ãƒ©ãƒ¼è¡¨ç¤ºã‚?
061     * 行ã‚ãªã?‚ˆã?«ã—ã¦ã?¾ã™ã?
062     *
063     * @og.group 帳票シスãƒ?ƒ 
064     *
065     * @version  4.0
066     * @author   Hiroki.Nakamura
067     * @since    JDK1.6
068     */
069    class OdsContentParser {
070    
071            //======== content.xmlã®ãƒ‘ã?スã§ä½¿ç”¨ ========================================
072            /* シートã?開始終äº?‚¿ã‚° */
073            private static final String BODY_START_TAG = "<table:table ";
074            private static final String BODY_END_TAG = "</table:table>";
075    
076            /* 行ã?開始終äº?‚¿ã‚° */
077            private static final String ROW_START_TAG = "<table:table-row ";
078    //      private static final String ROW_END_TAG = "</table:table-row>";
079    
080            /* ペã?ジエンドカãƒ?ƒˆã®éš›ã«ã€è¡Œã‚’éžè¡¨ç¤ºã«ã™ã‚‹ãŸã‚ã®ãƒ??ブル宣è¨?*/
081            private static final String ROW_START_TAG_INVISIBLE = "<table:table-row table:visibility=\"collapse\" ";
082    
083            /* セルã®é–‹å§‹ã‚¿ã‚° */
084            private static final String TABLE_CELL_START_TAG = "<table:table-cell";
085            private static final String TABLE_CELL_END_TAG = "</table:table-cell>";
086    
087            /* シートåã‚’å–å¾—ã™ã‚‹ãŸã‚ã?開始終äº?–‡å­?*/
088            private static final String SHEET_NAME_START = "table:name=\"";
089    //      private static final String SHEET_NAME_END = "\"";
090    
091            /* オブジェクトã?終äº?½ç½®(シートå)を見ã¤ã‘ã‚‹ãŸã‚ã®é–‹å§‹æ–‡å­?*/
092            private static final String OBJECT_SEARCH_STR = "table:end-cell-address=\"";
093    
094            /* å°åˆ·ç¯?›²æŒ?®šã?開始終äº?–‡å­?*/
095            // 4.3.3.5 (2008/11/08) 空白ペã?ジ対策ã§è¿½åŠ?
096            private static final String PRINT_RANGE_START = "table:print-ranges=\"";
097            private static final String PRINT_RANGE_END = "\"";
098    
099            /* 表紙å°åˆ·ç”¨ã®ãƒšã?ジåç§° */
100            private static final String FIRST_PAGE_NAME = "FIRST";
101    
102            /* シートブレイク用ã®ã‚­ãƒ¼ 5.1.7.0 (2010/06/01) */
103            private static final String SHEET_BREAK = "SHEETBREAK";
104    
105            /* 変数定義ã®é–‹å§‹çµ‚äº?–‡å­—åŠã³åŒºåˆ?‚Šæ–?­?*/
106            private static final String VAR_START = "{@";
107            private static final String VAR_END = "}";
108            private static final String VAR_CON = "_";
109    
110            /* ペã?ジエンドカãƒ?ƒˆã®ã‚«ãƒ©ãƒ?–‡å­—å? */
111            private static final String PAGE_END_CUT = "PAGEENDCUT";
112    
113            /* ペã?ジブレイクã®ã‚«ãƒ©ãƒ?–‡å­—å? */
114            private static final String PAGE_BREAK = "PAGEBREAK";
115    
116    //      /* ラインコピã?æ–?­—å? 5.0.0.2 (2009/09/15) */
117    //      private static final String LINE_COPY = "LINECOPY";
118    
119            /* ペã?ジ番å·å‡ºåŠ›ç”¨æ–?­—å? 5.1.6.0 (2010/05/01) */
120            private static final String PAGE_NO= "PAGENO";
121    
122            /* 行番å·å‡ºåŠ›ç”¨æ–?­—å? 5.1.6.0 (2010/05/01) */
123            private static final String ROW_NO= "ROWNO";
124    
125            /* ç”»åƒã?リンクをå–å¾—ã™ã‚‹ãŸã‚ã?開始終äº?–‡å­?*/
126            private static final String DRAW_IMG_START_TAG = "<draw:image xlink:href=\"";
127            private static final String DRAW_IMG_END_TAG = "</draw:image>";
128            private static final String DRAW_IMG_HREF_END = "\"";
129    
130            /* ç”»åƒãƒ•ァイルをä¿å­˜ã™ã‚‹ãŸã‚ã?パス */
131            private static final String IMG_DIR = "Pictures";
132    
133            /* QRコードを処ç?™ã‚‹ãŸã‚ã?カラãƒ? */
134            private static final String QRCODE_PREFIX = "QRCODE.";
135    
136            /* 作æ?ã—ãŸQRコードã?フォルãƒ?åŠã?æ‹¡å¼µå­?*/
137            private static final String QRCODE_FILETYPE = ".png";
138    
139            /* 4.3.3.5 (2008/11/08) å‹•çš„ã«ç”»åƒã‚’入れ替ãˆã‚‹ãŸã‚ã®ãƒ‘スを記述ã™ã‚‹ã‚«ãƒ©ãƒ? */
140            private static final String IMG_PREFIX = "IMG.";
141    
142            /* ファンクション定義を見ã¤ã‘ã‚‹ãŸã‚ã®é–‹å§‹çµ‚äº?–‡å­?*/
143            private static final String OOOC_FUNCTION_START = "oooc:=";
144            private static final String OOOC_FUNCTION_START_3 = "of:="; // 4.3.7.2 (2009/06/15) ODS仕様変更ã«ã¤ã追åŠ?
145    //      private static final String OOOC_FUNCTION_END = "\"";
146            private static final String OOOC_FUNCTION_END = ")\" ";
147    
148            /* セルå†??改行を定義ã™ã‚‹æ–?­—å? 5.0.2.0 (2009/11/01) */
149            private static final String OOO_CR = "</text:p><text:p>";
150    
151            /* グラフオブジェクトã?æ›¸ãæ›ãˆã‚’行ã†ãŸã‚ã®é–‹å§‹çµ‚äº?–‡å­?5.1.8.0 (2010/07/01) */
152            private static final String GRAPH_START_TAG = "<draw:frame ";
153            private static final String GRAPH_END_TAG = "</draw:frame>";
154            /* グラフã?ç¯?›²æŒ?®šã?æ›¸ãæ›ãˆã‚’行ã†ãŸã‚ã®é–‹å§‹çµ‚äº?–‡å­?5.1.8.0 (2010/07/01) */
155            private static final String GRAPH_UPDATE_RANGE_START = "draw:notify-on-update-of-ranges=\"";
156            private static final String GRAPH_UPDATE_RANGE_END = "\"";
157            /* グラフã?オブジェクトã¸ã®ãƒªãƒ³ã‚¯ã®æ›¸ãæ›ãˆã‚’行ã†ãŸã‚ã®é–‹å§‹çµ‚äº?–‡å­?5.1.8.0 (2010/07/01) */
158            private static final String GRAPH_HREF_START = "xlink:href=\"./";
159            private static final String GRAPH_HREF_END = "\"";
160            private static final String GRAPH_OBJREPL = "ObjectReplacements";
161            /* グラフã?オブジェクト毎ã?content.xmlã«è¨˜è¿°ã—ã¦ã‚るシートåã®æ›¸ãæ›ãˆã‚’行ã†ãŸã‚ã®é–‹å§‹çµ‚äº?–‡å­?5.1.8.0 (2010/07/01) */
162            private static final String GRAPH_CONTENT_START = "-address=\"";
163            private static final String GRAPH_CONTENT_END = "\"";
164            /* 生æ?ã—ãŸã‚°ãƒ©ãƒ•ã?オブジェクトをMETA-INF/manifest.xmlã«ç™»éŒ²ã™ã‚‹ãŸã‚ã®é–‹å§‹çµ‚äº?–‡å­—å? 5.1.8.0 (2010/07/01) */
165            private static final String MANIFEST_START_TAG = "<manifest:file-entry ";
166            private static final String MANIFEST_END_TAG = "/>";
167    
168            /* æ•°å€¤ã‚¿ã‚¤ãƒ—ç½®ãæ›ãˆç”¨ã®æ–?­—å? 5.1.8.0 (2010/07/01) */
169            private static final String TABLE_CELL_STRING_TYPE = "office:value-type=\"string\"";
170            private static final String TABLE_CELL_FLOAT_TYPE = "office:value-type=\"float\"";
171            private static final String TABLE_CELL_FLOAT_VAL_START = "office:value=\"";
172            private static final String TABLE_CELL_FLOAT_VAL_END = "\"";
173    
174            /* ãƒ?‚­ã‚¹ãƒˆæ–‡å­—å?ã®é–‹å§‹çµ‚äº?–‡å­—å? 5.1.8.0 (2010/07/01) */
175            private static final String TEXT_START_TAG = "<text:p>";
176            private static final String TEXT_END_TAG = "</text:p>";
177    
178            /* コメンãƒ?アノテーション)ã‚’å?ç?™ã‚‹ãŸã‚ã?カラãƒ? 5.1.8.0 (2010/07/01) */
179            private static final String ANNOTATION_PREFIX = "ANO.";
180            private static final String TEXT_START_ANO_TAG = "<text:p"; // アノテーションã®å ´åˆã?ç½®ãæ›ãˆã‚’
181            private static final String TEXT_START_END_ANO_TAG = ">"; // アノテーションã®å ´åˆã?ç½®ãæ›ãˆã‚’
182    
183            /* コメンãƒ?アノテーション)ã®é–‹å§‹ã?終äº?‚¿ã‚° 5.1.8.0 (2010/07/01) */
184            private static final String ANNOTATION_START_TAG = "<office:annotation";
185            private static final String ANNOTATION_END_TAG = "</office:annotation>";
186    
187            /* オブジェクトを検索ã™ã‚‹ãŸã‚ã®æ–?­—å? 5.1.8.0 (2010/07/01) */
188            private static final String DRAW_START_KEY = "<draw:";
189            private static final String DRAW_END_KEY = "</draw:";
190    
191            /* シートã?開始終äº?‚¿ã‚° 5.2.2.0 (2010/11/01) */
192            private static final String STYLE_START_TAG = "<style:style ";
193            private static final String STYLE_END_TAG = "</style:style>";
194    
195            /* シートåç§° 5.2.2.0 (2010/11/01) */
196            private static final String STYLE_NAME_START_TAG = "style:name=\"";
197            private static final String STYLE_NAME_END_TAG = "\"";
198    
199            /* ãƒ??ブルå†?‚·ãƒ¼ãƒˆåç§° 5.2.2.0 (2010/11/01) */
200            private static final String TABLE_STYLE_NAME_START_TAG = "table:style-name=\"";
201            private static final String TABLE_STYLE_NAME_END_TAG = "\""; // 5.6.3.1 (2013/04/05)
202    
203            //===========================================================================
204    
205            //======== meta.xmlã®ãƒ‘ã?スã§ä½¿ç”¨ ===========================================
206            /* ç·ã‚·ãƒ¼ãƒˆã‚«ã‚¦ãƒ³ãƒˆæ•° */
207            private static final String TABLE_COUNT_START_TAG = "meta:table-count=\"";
208            private static final String TABLE_COUNT_END_TAG = "\"";
209    
210            /* ç·ã‚»ãƒ«ã‚«ã‚¦ãƒ³ãƒˆæ•° */
211            private static final String CELL_COUNT_START_TAG = "meta:cell-count=\"";
212            private static final String CELL_COUNT_END_TAG = "\"";
213    
214            /* ç·ã‚ªãƒ–ジェクトカウント数 */
215            private static final String OBJECT_COUNT_START_TAG = "meta:object-count=\"";
216            private static final String OBJECT_COUNT_END_TAG = "\"";
217            //===========================================================================
218    
219            /*
220             * 処ç?¸­ã®è¡Œç•ªå·ã®çжæ…?
221             * NORMAL : 通常
222             * LASTROW : æœ?µ‚è¡?
223             * OVERFLOW : 終�
224             */
225            private static final int NORMAL = 0;
226            private static final int LASTROW = 1;
227            private static final int OVERFLOW = 2;
228            private int status = NORMAL;
229    
230            /*
231             * å?››å½¢ãƒ•ァイルをå?ç?™ã‚‹éš›ã®åŸºæº–ã¨ãªã‚‹è¡Œæ•°
232             * åˆæœŸ>0 2è¡?{&#064;XXX_1}ã¾ã§)処ç?¾?2 ・・・
233             * å?››å½¢ã§å®šç¾©ã•れã¦ã?‚‹è¡Œç•ªå· + [baseRow] ã®å€¤ãŒDBTableModel上ã?行番å·ã«ç›¸å½“ã™ã‚?
234             * currentMaxRowã¯å?‚·ãƒ¼ãƒˆå?ç?¾Œã?[baseRow]ã¨åŒã˜
235             */
236            private int currentBaseRow = 0;
237            private int currentMaxRow = 0;
238    
239            /* 処ç?—ãŸã?ージ数 */
240            private int pages = 0;
241    
242            /* 処ç?¡ŒãŒãƒšã?ジエンドカãƒ?ƒˆã®å¯¾è±¡ã‹ã©ã?‹ */
243            private boolean isPageEndCut = false;                   // 4.3.1.1 (2008/08/23) ローカル変数�
244    
245            /* ペã?ジブレイクã®å‡¦ç?¸­ã‹ã©ã?‹ */
246            private boolean isPageBreak = false;
247    
248            /* XML宣è¨??æ–?­—å?。å„XMLã§å…±é€šãªã®ã§ã‚¯ãƒ©ã‚¹å¤‰æ•°ã¨ã—ã¦å®šç¾© */
249            private String xmlHeader = null;
250    
251            /* シートブレイク対象ã‹ã©ã?‹ 5.1.7.0 (2010/06/01) */
252            private int sheetBreakClm = -1;
253    
254            /* シートã?ヘッãƒ??部åˆ??å†ãƒ‘ースを行ã†ã‹ã©ã?‹  5.2.2.0 (2010/11/01) */
255            private boolean isNeedsReparse = false;
256    
257            /* ペã?ジåã?マッピング(å…??シートåã«å¯¾ã™ã‚‹æ–°ã—ã„シートå) 5.2.2.0 (2010/11/01) */
258            private final Map<String,List<String>> pageNameMap = new HashMap<String,List<String>>();
259    
260            /* ペã?ジåã«ä¾å­˜ã—ã¦ã?‚‹ã‚¹ã‚¿ã‚¤ãƒ«åç§°ã®ãƒªã‚¹ãƒ?5.2.2.0 (2010/11/01) */
261            private final List<String> repStyleList = new ArrayList<String>();
262    
263            /* manifest.xmlã«è¿½åŠ?Œå¿?¦ãªã‚ªãƒ–ジェクトã?マッãƒ?5.3.1.0 (2011/01/01) */
264            private final Map<String,String> addObjs = new HashMap<String,String>();
265    
266            private final ExecQueue queue;
267            private final String path;
268    
269            /**
270             * コンストラクタ
271             *
272             * @og.rev 5.1.2.0 (2010/01/01) 処ç?—ãŸè¡Œæ•°ã‚’Queueオブジェクトã‹ã‚‰å–å¾?シート数ã?56ã‚’è¶?ˆãŸå?åˆã?対å¿?
273             *
274             * @param qu ExecQueue
275             * @param pt String
276             */
277            OdsContentParser( final ExecQueue qu, final String pt ) {
278                    queue = qu;
279                    path = pt;
280    
281                    currentBaseRow = queue.getExecRowCnt();
282            }
283    
284            /**
285             * パã?ス処ç?‚’実行ã—ã¾ã?
286             *
287             * @og.rev 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
288             * @og.rev 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
289             */
290            public void exec() {
291                    /*
292                     * 雛形ヘッãƒ??フッターã®å®šç¾©
293                     * OOoã§ã¯ãƒšã?ジ毎ã«ãƒ˜ãƒƒãƒ??フッターãŒè¨­å®šã§ããªã?‚ˆã??
294                     * ãªã®ã§ã€å?ã¦ãƒ˜ãƒƒãƒ??扱ã?§å‡¦ç?
295                     */
296                    execStyles();
297    
298                    /* 中身ã®å¤‰æ› */
299                    execContent();
300    
301                    /* ヘッãƒ??部åˆ?«ã‚·ãƒ¼ãƒˆæƒ…å ±ãŒã‚ã‚‹å?åˆã«æ›¸ãæ›ã?*/
302                    if( isNeedsReparse ) {
303                            /* ヘッãƒ??ファイルã®å†ãƒ‘ース */
304                            execContentHeader();
305                            /* ヘッãƒ??ファイルã¨ãれ以é™ã?ファイルã®é€£çµ?*/
306                            execMergeContent();
307                    }
308    
309                    /* メタãƒ??ã‚¿ã®å¤‰æ› */
310                    execMeta();
311    
312                    // 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
313                    /* 追åŠ?—ãŸç”»åƒã?オブジェクトをmanifest.xmlã«è¿½åŠ?*/
314                    if( addObjs.size() > 0 ) {
315                            execManifest();
316                    }
317            }
318    
319            /**
320             * 帳票処ç?‚­ãƒ¥ãƒ¼ã‚’å?ã«ã€content.xmlã‚’æ›¸ãæ›ãˆã¾ã™ã?
321             * ã¾ãšã?XMLã‚’ä¸?—¦ãƒ¡ãƒ¢ãƒªä¸Šã«å±•é–‹ã—ãŸå¾Œã?シートå˜ä½ã«åˆ?§£ã—ã?ãƒ??ã‚¿ã®åŸ‹ã‚è¾¼ã¿ã‚’行ã„ã¾ã™ã?
322             *
323             * @og.rev 4.3.0.0 (2008/07/18) ペã?ジ数ã?56ã‚’è¶?ˆãŸå?åˆã?エラー処ç?
324             * @og.rev 5.0.0.2 (2009/09/15) LINECOPY機è?追åŠ?
325             * @og.rev 5.1.2.0 (2010/01/01) 処ç?—ãŸã?ージ数ã€è¡Œæ•°ã‚’Queueオブジェクトã«ã‚»ãƒ?ƒˆ(シート数ã?56ã‚’è¶?ˆãŸå?åˆã?対å¿?
326             * @og.rev 5.1.7.0 (2010/06/01) è¤?•°ã‚·ãƒ¼ãƒˆå¯¾å¿?
327             * @og.rev 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
328             */
329            private void execContent() {
330                    String fileName = path + "content.xml";
331                    String content = readOOoXml( fileName );
332                    // ファイルã®è§£æžã—ã€ã‚·ãƒ¼ãƒ?行å˜ä½ã«åˆ?§£
333                    String[] tags = tag2Array( content, BODY_START_TAG, BODY_END_TAG );
334    
335                    // 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
336                    // content.xmlã®ãƒ˜ãƒƒãƒ??部åˆ??ã¿æ›¸ãå?ã?
337                    String contentHeader = tags[0];
338                    BufferedWriter bw = null;
339                    try {
340                            bw = getWriter( fileName );
341                            bw.write( xmlHeader );
342                            bw.write( '\n' );
343                            bw.write( contentHeader );
344                            bw.flush();
345                    }
346                    catch ( IOException ex ) {
347                            queue.addMsg( "[ERROR]PARSE:error occurer while content.xml(header) " + fileName + HybsSystem.CR );
348                            throw new HybsSystemException( ex );
349                    }
350                    finally {
351                            Closer.ioClose( bw );
352                            bw = null;
353                    }
354    
355                    String contentFooter = tags[1];
356                    List<OdsSheet> firstSheets = new ArrayList<OdsSheet>();
357                    Map<String, OdsSheet> sheets = new HashMap<String,OdsSheet>();
358                    OdsSheet defaultSheet = null;
359                    for( int i = 2; i < tags.length; i++ ) {
360                            OdsSheet sheet = new OdsSheet();
361                            // sheet.analyze( tags[i] );
362                            sheet.analyze( tags[i],queue.getBody().getRowCount() ); // 5.0.0.2 (2009/09/15)
363    //                      sheets.add( sheet );
364                            // 5.1.7.0 (2010/06/01) è¤?•°ã‚·ãƒ¼ãƒˆå¯¾å¿?
365                            String sheetName = sheet.getSheetName();
366                            if( sheetName.startsWith( FIRST_PAGE_NAME ) ) {
367                                    firstSheets.add( sheet );
368                            }
369                            else {
370                                    sheets.put( sheetName, sheet );
371                                    // ä¸?•ªåˆã‚ã«è¦‹ã¤ã‹ã£ãŸè¡¨ç´™ä»¥å¤–ã?シートをãƒ?ƒ•ォルトシートã¨ã—ã¦è¨­å®?
372                                    if( defaultSheet == null ) {
373                                            defaultSheet = sheet;
374                                    }
375                            }
376    
377                            // 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
378                            if( !isNeedsReparse && contentHeader.indexOf( "=\"" + sheet.getOrigSheetName() + "." ) >= 0 ) {
379                                    isNeedsReparse = true;
380                            }
381    
382                            // 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
383                            pageNameMap.put( sheet.getOrigSheetName(), new ArrayList<String>() );
384                    }
385    
386                    // content.xmlã®æ›¸ãå?ã?
387    //              BufferedWriter bw = null;
388                    try {
389                            // 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
390    //                      bw = getWriter( fileName );
391                            if( isNeedsReparse ) {
392                                    // ヘッãƒ??ã‚’å?パã?スã™ã‚‹å ´åˆã?ã€ã?ãƒ?‚£éƒ¨åˆ?‚’
393                                    // content.xml.tmpã«æ›¸ãå?ã—ã¦ã€å¾Œã§ãƒžã?ジã™ã‚‹
394                                    bw = getWriter( fileName + ".tmp" );
395                                    getRepStyleList( contentHeader );
396                            }
397                            else {
398                                    // ヘッãƒ??ã‚’å?パã?スã™ã—ãªã??åˆã?ã€ã?ãƒ?‚£éƒ¨åˆ?‚’
399                                    // content.xml追åŠ?ƒ¢ãƒ¼ãƒ‰ã§æ›¸ãè¾¼ã¿ã™ã‚‹
400                                    bw = getWriter( fileName, true );
401                            }
402    
403    //                      bw.write( xmlHeader );
404    //                      bw.write( '\n' );
405    //                      // ヘッ�?
406    //                      bw.write( contentHeader );
407    
408                            // 表紙ã?ージã®å‡ºåŠ?
409                            if( queue.getExecPagesCnt() == 0 ) {
410                                    for ( OdsSheet firstSheet : firstSheets ) {
411                                            if ( currentBaseRow >= queue.getBody().getRowCount() ) {
412                                                    break;
413                                            }
414                                            writeParsedSheet( firstSheet, bw );
415                                    }
416                            }
417    
418                            // 5.1.7.0 (2010/06/01) è¤?•°ã‚·ãƒ¼ãƒˆå¯¾å¿?
419                            sheetBreakClm = queue.getBody().getColumnNo( SHEET_BREAK, false );
420    
421                            // 繰り返ã—ペã?ジã®å‡ºåŠ?
422                            while ( currentBaseRow < queue.getBody().getRowCount() ) {
423                                    // 4.3.0.0 (2008/07/18) ペã?ジ数ã?56ã‚’è¶?ˆãŸå?åˆã«ã‚¨ãƒ©ãƒ¼ã¨ã™ã‚‹
424                                    // 5.1.2.0 (2010/01/01) 256シートをè¶?ˆãŸå?åˆã?対å¿?
425    //                              if( pages >= 256 ){
426                                    if( pages >= ExecQueue.MAX_SHEETS_PER_FILE ) {
427    //                                      queue.addMsg( "[ERROR]PARSE:シート数ã?56æžšã‚’è¶?ˆã¾ã—ãŸã€? + HybsSystem.CR );
428    //                                      throw new HybsSystemException();
429                                            queue.setEnd( false );
430                                            break;
431                                    }
432    
433                                    OdsSheet sheet = null;
434                                    if( sheetBreakClm >= 0 ) {
435                                            String sheetName = queue.getBody().getValue( currentBaseRow, sheetBreakClm );
436                                            if( sheetName != null && sheetName.length() > 0 ) {
437                                                    sheet = sheets.get( sheetName );
438                                            }
439                                    }
440                                    if( sheet == null ) { sheet = defaultSheet; }
441    
442                                    writeParsedSheet( sheet, bw );
443                            }
444    
445                            // 5.1.2.0 (2010/01/01) 256シートをè¶?ˆãŸå?åˆã?対å¿?
446                            queue.addExecPageCnt( pages );
447                            queue.setExecRowCnt( currentBaseRow );
448    
449                            // フッター
450                            bw.write( contentFooter );
451                            bw.flush();
452                    }
453                    catch ( IOException ex ) {
454                            queue.addMsg( "[ERROR]PARSE:error occurer while write Parsed Sheet " + fileName + HybsSystem.CR );
455                            throw new HybsSystemException( ex );
456                    }
457                    finally {
458                            Closer.ioClose( bw );
459                    }
460            }
461    
462            /**
463             * シートå˜ä½ã«ãƒ‘ã?スã•ã‚ŒãŸæ–‡æ›¸ãƒ??タを書ãè¾¼ã¿ã¾ã?
464             * 出力ã•れるシートåã«ã¯ã€ã?ージ番å·ã¨åŸºåº•ã¨ãªã‚‹è¡Œç•ªå·ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
465             *
466             * @og.rev 4.2.4.0 (2008/07/04) 行å˜ä½ã«ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ãè¾¼ã‚?‚ˆã?«å¤‰æ›´
467             * @og.rev 5.2.0.0 (2010/09/01) 表紙ã?å ´åˆã?ã€BODY部åˆ??ãƒ??ã‚¿ãŒå«ã¾ã‚Œã¦ã?ªãã¦ã‚‚OK
468             * @og.rev 5.2.1.0 (2010/10/01) シートå定義対å¿?
469             * @og.rev 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
470             *
471             * @param sheet
472             * @param bw
473             * @throws IOException 書ãè¾¼ã¿ã«å¤±æ•—ã—ãŸå?å?
474             */
475            private void writeParsedSheet( final OdsSheet sheet, final BufferedWriter bw ) throws IOException {
476                    // シートå
477    //              String outputSheetName = "Page" + pages + "_" + "Row" + currentBaseRow + "";
478                    String outputSheetName = null;
479                    if( sheet.getConfSheetName() == null ) {
480                            outputSheetName = "Page" + ( queue.getExecPagesCnt() + pages ) + "_" + "Row" + currentBaseRow + "";
481                    }
482                    else {
483                            outputSheetName = sheet.getConfSheetName() + ( queue.getExecPagesCnt() + pages + 1 );
484                    }
485    
486                    // ペã?ジブレイク変数をå?期化
487                    isPageBreak = false;
488    
489                    // シートã?ヘッãƒ??部åˆ?‚’書ãè¾¼ã¿(シートåã‚‚æ›¸ãæ›ã?
490    //              String headerStr = sheet.getHeader().replace( SHEET_NAME_START + sheet.getSheetName(), SHEET_NAME_START + outputSheetName );
491                    String headerStr = sheet.getHeader().replace( SHEET_NAME_START + sheet.getOrigSheetName(), SHEET_NAME_START + outputSheetName );
492    
493                    // å°åˆ·ç¯?›²æŒ?®šéƒ¨åˆ??シートåを変更
494                    // 4.3.3.5 (2008/11/08) 空白ペã?ジ出力ã?対策ã?å°åˆ·ç¯?›²ã®ã‚·ãƒ¼ãƒˆåæ›¸ãæ›ãˆã‚’追åŠ?
495                    int printRangeStart = headerStr.indexOf( PRINT_RANGE_START );
496                    if( printRangeStart >= 0 ) {
497                            int printRangeEnd = headerStr.indexOf( PRINT_RANGE_END, printRangeStart + PRINT_RANGE_START.length() );
498                            String rangeStr = headerStr.substring( printRangeStart, printRangeEnd );
499    //                      rangeStr = rangeStr.replace( sheet.getSheetName(), outputSheetName );
500                            rangeStr = rangeStr.replace( sheet.getOrigSheetName(), outputSheetName );
501                            headerStr = headerStr.substring( 0, printRangeStart ) + rangeStr + headerStr.substring( printRangeEnd );
502                    }
503    
504                    bw.write( headerStr );
505    
506                    // シートã?ボディ部åˆ?‚’書ãè¾¼ã¿
507                    String[] rows = sheet.getRows();
508                    for( int i = 0; i < rows.length; i++ ) {
509                            // 4.3.4.4 (2009/01/01)
510    //                      writeParsedRow( rows[i], bw, sheet.getSheetName(), outputSheetName );
511                            writeParsedRow( rows[i], bw, sheet.getOrigSheetName(), outputSheetName );
512                    }
513                    // {@XXXX}ãŒåŸ‹ã‚è¾¼ã¾ã‚Œã¦ã?ªã??åˆã?エラー
514                    // 5.2.0.0 (2010/09/01) 表紙ã?å ´åˆã?ã€BODY部åˆ??ãƒ??ã‚¿ãŒå«ã¾ã‚Œã¦ã?ªãã¦ã‚‚OK
515    //              if( currentBaseRow == currentMaxRow ) {
516    //              if( currentBaseRow == currentMaxRow && !sheet.getSheetName().startsWith( FIRST_PAGE_NAME ) ) {
517                    if( currentBaseRow == currentMaxRow && !sheet.getOrigSheetName().startsWith( FIRST_PAGE_NAME ) ) {
518                            queue.addMsg( "[ERROR]PARSE:No Data defined on Template ODS(" + queue.getListId() + ")" + HybsSystem.CR );
519                            throw new HybsSystemException();
520                    }
521                    currentBaseRow = currentMaxRow;
522    
523                    // シートã?フッター部åˆ?‚’書ãè¾¼ã¿
524                    bw.write( sheet.getFooter() );
525    
526                    pages++;
527    
528                    // 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
529                    pageNameMap.get( sheet.getOrigSheetName() ).add( outputSheetName );
530            }
531    
532            /**
533             * 行å˜ä½ã«ãƒ‘ã?スã•ã‚ŒãŸæ–‡æ›¸ãƒ??タを書ãè¾¼ã¿ã¾ã?
534             *
535             * @og.rev 4.2.3.1 (2008/06/19) 関数エラーを表示ã•ã›ãªã?Ÿã‚ã?ISERROR関数を埋ã‚è¾¼ã¿
536             * @og.rev 4.2.4.0 (2008/07/04) 行å˜ä½ã«ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ãè¾¼ã‚?‚ˆã?«å¤‰æ›´
537             * @og.rev 4.3.0.0 (2008/07/17) ?›ï¼?¨?ã?æ•´åˆæ?ãƒã‚§ãƒ?‚¯è¿½åŠ?
538             * @og.rev 4.3.0.0 (2008/07/22) 行最後ã??›ï¼?½æ•´åˆæ?エラーãƒãƒ³ãƒ‰ãƒªãƒ³ã‚°è¿½åŠ?
539             * @og.rev 4.3.3.5 (2008/11/08) ç”»åƒã?å‹•çš„ãªå…¥ã‚Œæ›¿ãˆã«å¯¾å¿?
540             * @og.rev 5.1.8.0 (2010/07/01) パã?ス方法ã?å†?ƒ¨å®Ÿè£?¤‰æ›´
541             * @og.rev 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
542             * @og.rev 5.4.2.0 (2011/12/01) ペã?ジブレイクã€ã‚·ãƒ¼ãƒˆãƒ–レイク中ã§ã‚‚ã?ージエンドカãƒ?ƒˆãŒé©ç”¨ã•れるよã?«ã™ã‚‹ã€?
543             * @og.rev 5.6.3.1 (2013/04/05) æ¡ä»¶ä»˜æ›¸å¼ã?属æ?終äº?–‡å­—対å¿?
544             *
545             * @param row
546             * @param bw
547             * @param sheetNameOrig
548             * @param sheetNameNew
549             * @throws IOException 書ãè¾¼ã¿ã«å¤±æ•—ã—ãŸå?å?
550             */
551            private void writeParsedRow( final String row, final BufferedWriter bw, final String sheetNameOrig, final String sheetNameNew ) throws IOException {
552                    isPageEndCut = false;
553    
554                    String rowStr = new TagParser() {
555                            @Override
556                            protected void exec( final String str, final StringBuilder buf, final int offset ) {
557                                    String key = TagParser.checkKey( str, buf );
558    
559                                    // 4.3.0.0 (2008/07/15) "<"ãŒå?ã£ã¦ã?Ÿå ´åˆã«ã¯{@䏿•´å?エラー
560                                    if( key.indexOf( '<' ) >= 0 ){
561                                            queue.addMsg( "[ERROR]PARSE:{@ã¨}ã®æ•´åˆæ?ãŒä¸æ­£ã§ã™ã?変数å†??特定ã?æ–?­—å?ã«æ›¸å¼è¨­å®šãŒã•れã¦ã?‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã?キー=" + key + HybsSystem.CR );
562                                            throw new HybsSystemException();
563                                    }
564    
565                                    // QRコードã?処ç??処ç?¾Œã?offsetãŒé?ã‚?Ÿã‚ã?offsetã‚’å?ã‚»ãƒ?ƒˆ
566                                    if( key.startsWith( QRCODE_PREFIX ) ) {
567                                            setOffset( makeQRImage( row, offset, key.substring( QRCODE_PREFIX.length() ), buf ) );
568                                    }
569                                    // ç”»åƒç½®ãæ›ãˆã?処ç??処ç?¾Œã?offsetãŒé?ã‚?Ÿã‚ã?offsetã‚’å?ã‚»ãƒ?ƒˆ
570                                    else if( key.startsWith( IMG_PREFIX  ) ) {
571                                            setOffset( changeImage( row, offset, key.substring( IMG_PREFIX.length() ), buf ) );
572                                    }
573                                    // コメンãƒ?アノテーション)ã«ã‚ˆã‚‹ç½®ãæ›ãˆå?ç??処ç?¾Œã?offsetãŒé?ã‚?Ÿã‚ã?offsetã‚’å?ã‚»ãƒ?ƒˆ
574                                    else if( key.startsWith( ANNOTATION_PREFIX ) ) {
575                                            setOffset( parseByAnnotation( row, offset, key.substring( ANNOTATION_PREFIX.length() ), buf ) );
576                                    }
577                                    else {
578                                            String val = getValue( key );
579                                            // 5.5.2.4 (2012/05/16) String key ã¯ä½¿ã‚れã¦ã?ªã??ã§ã€å‰Šé™¤ã—ã¾ã™ã?
580    //                                      changeType( row, offset, key, val, getNativeType( key, val ), buf );
581                                            changeType( row, offset, val, getNativeType( key, val ), buf );
582                                            buf.append( val );
583                                    }
584    
585                                    // 処ç?¡ŒãŒãƒšã?ジエンドカãƒ?ƒˆã®å¯¾è±¡ã?
586                                    if( queue.isFgcut() && PAGE_END_CUT.equals( key ) ) {
587                                            isPageEndCut = true;
588                                    }
589                            }
590                    }.doParse( row, VAR_START, VAR_END, false );
591    
592                    //==== ã“ã“ã‹ã‚‰ã¯å¾Œå?ç?=========================================================
593                    /*
594                     * ペã?ジエンドカãƒ?ƒˆã®åˆ¤å®šã?æœ?¾Œã§å‡¦ç?™ã‚‹ã?
595                     * {&#064;PAGEENDCUT}ãŒè¡Œã?æœ??ã«æ›¸ã‹ã‚Œã¦ã?‚‹å ´åˆã?ã€OVERFLOWã«ãªã£ã¦ã?ªã?¯èƒ½æ€§ã?
596                     * ã‚ã‚‹ãŸã‚行ã?途中ã§ã¯åˆ¤æ–­ã§ããªã?
597                     */
598                    // 5.4.2.0 (2011/12/01) シートブレイク中ã§ã‚‚ã?ージエンドカãƒ?ƒˆãŒé©ç”¨ã•れるよã?«ã™ã‚‹ã€?
599                    // (通常ã®ãƒšã?ジブレイクã¯å…ˆèª­ã¿åˆ¤å®šã?ãŸã‚ペã?ジエンドカãƒ?ƒˆã™ã‚‹ã¨ã€ãƒ–レイク発生行è?身ã?
600                    //  削除ã•れã¦ã—ã¾ã?Ÿã‚ç¾æ™‚点ã§ã¯æœªå¯¾å¿?
601    //              if( isPageEndCut && status == OVERFLOW ) {
602                    if( isPageEndCut && ( status == OVERFLOW || ( sheetBreakClm >= 0 && isPageBreak ) ) ) {
603                            // ペã?ジエンドカãƒ?ƒˆã®å ´åˆã?ã€?žè¡¨ç¤ºçŠ¶æ…‹ã«ã™ã‚‹ã€?
604                            rowStr = rowStr.replace( ROW_START_TAG, ROW_START_TAG_INVISIBLE ) ;
605                    }
606    
607                    /*
608                     * オブジェクトã§å®šç¾©ã•れã¦ã?‚‹ãƒ??ブルåを変更
609                     */
610                    if( rowStr.indexOf( OBJECT_SEARCH_STR ) >= 0 ) {
611                            rowStr = rowStr.replace( OBJECT_SEARCH_STR + sheetNameOrig, OBJECT_SEARCH_STR + sheetNameNew );
612                    }
613    
614                    /*
615                     * 関数エラーを表示ã•れãªã?Ÿã‚ã?ISERROR関数を埋ã‚込㿠4.2.3.1 (2008/06/19)
616                     */
617                    rowStr = replaceOoocError( rowStr );
618    
619                    /*
620                     * グラフをシート毎ã«ã‚³ãƒ”ã? 5.1.8.0 (2010/07/01)
621                     */
622                    rowStr = replaceGraphInfo( rowStr, sheetNameOrig, sheetNameNew );
623    
624                    /*
625                     * アノテーション(コメン�を削除 5.1.8.0 (2010/07/01)
626                     * (コメントãŒå­˜åœ¨ã™ã‚‹ã¨èµ·å‹•ãŒç•°å¸¸ã«é?ãªã‚?
627                     */
628                    if( rowStr.indexOf( ANNOTATION_START_TAG ) >= 0 ) {
629                            rowStr = new TagParser() {}.doParse( rowStr, ANNOTATION_START_TAG, ANNOTATION_END_TAG );
630                    }
631    
632                    /*
633                     * æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?5.2.2.0 (2010/11/01)
634                     * ãƒ??ブルå†?«å­˜åœ¨ã™ã‚‹ã‚¹ã‚¿ã‚¤ãƒ«åç§°ã‚’æ›¸ãæ›ã?
635                     */
636                    if( isNeedsReparse ) {
637                            for( String name : repStyleList ) {
638    //                              if( rowStr.indexOf( TABLE_STYLE_NAME_START_TAG + name ) >= 0 ) {
639    //                                      rowStr = rowStr.replace( TABLE_STYLE_NAME_START_TAG + name, TABLE_STYLE_NAME_START_TAG + name + "_" + sheetNameNew );
640    //                              }
641                                    // 5.6.3.1 (2013/04/05) 属æ?終äº?¿½åŠ?
642                                    if( rowStr.indexOf( TABLE_STYLE_NAME_START_TAG + name + TABLE_STYLE_NAME_END_TAG ) >= 0 ) {
643                                            rowStr = rowStr.replace( TABLE_STYLE_NAME_START_TAG + name + TABLE_STYLE_NAME_END_TAG, TABLE_STYLE_NAME_START_TAG + name + "_" + sheetNameNew + TABLE_STYLE_NAME_END_TAG );
644                                    }
645                            }
646    
647                    }
648                    //==============================================================================
649    
650                    bw.write( rowStr );
651            }
652    
653            /**
654             * 帳票ãƒ??ã‚¿ã«å¿œã˜ã¦ã€ã‚«ãƒ©ãƒ??属æ?を変更(æ–?­—型⇒数値åž?ã«å¤‰æ›´ã—ã¾ã™ã?
655             *
656             * @og.rev 5.1.8.0 (2010/07/01) æ–°è¦ä½œæ?
657             * @og.rev 5.5.2.4 (2012/05/16) String key ã¯ä½¿ã‚れã¦ã?ªã??ã§ã€å‰Šé™¤ã—ã¾ã™ã?
658             *
659             * @param row
660             * @param curOffset
661             * @param val
662             * @param type
663             * @param sb
664             */
665    //      private void changeType( final String row, final int curOffset, final String key
666            private void changeType( final String row, final int curOffset
667                                                            , final String val, final NativeType type, final StringBuilder sb ) {
668                    if( val == null || val.length() == 0 ) {
669                            return;
670                    }
671                    // æ›¸ãæ›ãˆå¯¾è±¡ã¯æ•°å€¤åž‹ã?ã¿
672                    if( type != NativeType.INT && type != NativeType.LONG && type != NativeType.DOUBLE ) {
673                            return;
674                    }
675                    // 処ç?¯¾è±¡ãŒã‚»ãƒ«ã§ãªã?オブジェクãƒ?ã¯æ›¸ãæ›ãˆã—ãªã?
676                    if( !isCell( row, curOffset ) ) {
677                            return;
678                    }
679    
680                    // ã‚»ãƒ«ã®æ–?­—ãŒ{@xxxx_n}ã®ã¿ã§ã‚ã£ãŸå?åˆã ã‘ã?数値定義ã®åˆ¤å®šã‚’行ã†ã€?
681                    // (関数å†?«{@xxxx_n}ç­‰ãŒã‚ã£ãŸå?åˆã?ã€åˆ¤å®šã—ãªã?<text:p>{@xxxx_n}</text:p>ã®å ´åˆã?ã¿))
682                    if( sb.lastIndexOf( TEXT_START_TAG ) + TEXT_START_TAG.length() == sb.length()
683                            && row.indexOf( TEXT_END_TAG, curOffset ) == curOffset ) {
684                            int typeIdx = sb.lastIndexOf( TABLE_CELL_STRING_TYPE );
685                            int cellIdx = sb.lastIndexOf( TABLE_CELL_START_TAG );
686                            if( typeIdx >= 0 && cellIdx >= 0 && typeIdx > cellIdx ) {
687                                    // office:value-type="string" ã‚?office:value-type="float" office:value="xxx" ã«å¤‰æ›
688                                    sb.replace( typeIdx, typeIdx + TABLE_CELL_STRING_TYPE.length()
689                                            ,TABLE_CELL_FLOAT_TYPE + " " + TABLE_CELL_FLOAT_VAL_START + val + TABLE_CELL_FLOAT_VAL_END );
690                            }
691                    }
692            }
693    
694            /**
695             * å¼•æ•°ã«æŒ?®šã•ã‚ŒãŸæ–?­—å?ã®Nativeタイプを返ã—ã¾ã™ã?
696             *
697             * リソース使用時ã?ã€å„DBTypeã§å®šç¾©ã•れãŸNativeタイプをã€?
698             * 未使用時ã?ã€å?ã‹ã‚‰Nativeタイプをå–å¾—ã—ã¦è¿”ã—ã¾ã™ã?
699             *
700             * @og.rev 5.1.8.0 (2010/07/01) NativeType#getType(String) ã®ãƒ¡ã‚½ãƒ?ƒ‰ã‚’使用ã™ã‚‹ã‚ˆã†ã«å¤‰æ›´ã€?
701             *
702             * @param key
703             * @param val
704             *
705             * @return  NATIVEã®åž‹ã?識別コーãƒ?
706             * @see org.opengion.fukurou.model.NativeType
707             */
708            private NativeType getNativeType( final String key, final String val ) {
709                    if( val == null || val.length() == 0 ) {
710                            return NativeType.STRING;
711                    }
712    
713                    NativeType type = null;
714                    if( queue.isFglocal() ) {
715                            String name = key;
716                            int conOffset = key.lastIndexOf( VAR_CON );
717                            if( conOffset >= 0 ) {
718                                    int rownum = -1;
719                                    try {
720                                            rownum = Integer.valueOf( name.substring( conOffset + VAR_CON.length(), name.length() ) );
721                                    }
722                                    // '_'以é™ã?æ–?­—ãŒæ•°å­—ã§ãªã??åˆã?ã€?_'以é™ã?æ–?­—もカラãƒ?ã®ä¸?ƒ¨ã¨ã—ã¦æ‰±ã?
723                                    catch ( NumberFormatException ex ) {}
724                                    if( rownum >= 0 ) {
725                                            name = name.substring( 0, conOffset );
726                                    }
727                            }
728                            int col = queue.getBody().getColumnNo( name, false );
729                            if( col >= 0 ) {
730                                    type = queue.getBody().getDBColumn( col ).getNativeType();
731                            }
732                    }
733    
734                    if( type == null ) {
735                            // ,ã¯å‰Šé™¤ã—ãŸçŠ¶æ…‹ã§åˆ¤å®?
736                            String repVal = val.replace( ",", "" );
737    //                      type = StringUtil.getNativeType( repVal );
738                            type = NativeType.getType( repVal );                    // 5.1.8.0 (2010/07/01) NativeType#getType(String) ã®ãƒ¡ã‚½ãƒ?ƒ‰ã‚’使用
739                            // æ•´æ•°åž‹ã§ã€?nnnã¨ãªã£ã¦ã?‚‹å ´åˆã?ã€æ–‡å­—å?ã‚’ã—ã¦æ‰±ã?
740                            if( type == NativeType.INT && repVal.length() >= 2 && repVal.charAt(0) == '0' ) {
741                                    type = NativeType.STRING;
742                            }
743                    }
744    
745                    return type;
746            }
747    
748            /**
749             * コメンãƒ?アノテーションã«ã‚ˆã‚‹ç½®ãæ›ãˆå?ç?‚’行ã„ã¾ã?
750             * ã“ã?処ç?§ã¯ã€offsetã‚’é?ã‚ã‚‹ãŸã‚ã€æˆ»ã‚Šå?ã¨ã—ã¦å‡¦ç?¾Œã?offsetã‚’è¿”ã—ã¾ã™ã?
751             *
752             * @og.rev 5.1.8.0 (2010/07/01) æ–°è¦ä½œæ?
753             *
754             * @param row
755             * @param curOffset
756             * @param key
757             * @param sb
758             *
759             * @return 処ç?¾Œã?オフセãƒ?ƒˆ
760             */
761            private int parseByAnnotation( final String row, final int curOffset, final String key, final StringBuilder sb ) {
762                    int offset = curOffset;
763                    boolean isCell = isCell( row, offset );
764    
765                    // セルã®å ´åˆã?ã¿ç½®ãæ›ãˆã?判定を行ã†(オブジェクトã?å ´åˆã?判定ã—ãªã?
766                    if( isCell ) {
767                            int cellStrIdx = sb.lastIndexOf( TABLE_CELL_START_TAG, offset );
768                            // office:value-type="float" office:value="xxx" ã‚?office:value-type="string" ã«å¤‰æ›
769                            // 数値型ã?å ´åˆã?ã€å¾Œã§å†åº¦å¤‰æ›ã‚’行ã†ã€?
770                            // (æ–?­—åž‹ã«å¤‰æ›ã—ã¦ãŠã‹ãªã?¨ã€å?ãŒnullã®å ´åˆã§ã‚?0"ãŒè¡¨ç¤ºã•れã¦ã—ã¾ã?Ÿã‚?
771                            int floatIdx = sb.indexOf( TABLE_CELL_FLOAT_TYPE, cellStrIdx );
772                            if( floatIdx >= 0 ) {
773                                    sb.replace( floatIdx, floatIdx + TABLE_CELL_FLOAT_TYPE.length(), TABLE_CELL_STRING_TYPE );
774    
775                                    int floatStrIdx = sb.indexOf( TABLE_CELL_FLOAT_VAL_START, floatIdx );
776                                    if( floatStrIdx >= 0 ) {
777                                            int floatEndIdx = sb.indexOf( TABLE_CELL_FLOAT_VAL_END, floatStrIdx + TABLE_CELL_FLOAT_VAL_START.length() );
778                                            if( floatEndIdx >= 0 ) {
779                                                    sb.replace( floatStrIdx, floatEndIdx + TABLE_CELL_FLOAT_VAL_END.length(), "" );
780                                            }
781                                    }
782                            }
783                    }
784    
785                    // アノテーションã®å€¤ã‹ã‚‰ã€ã‚»ãƒ«ã®æ–?­—å?部åˆ?‚’ç½®ãæ›ã?
786                    int endIdx = isCell ? row.indexOf( TABLE_CELL_END_TAG, offset ) : row.indexOf( DRAW_END_KEY, offset );
787                    if( endIdx >= 0 ) {
788                            int textStrIdx = row.indexOf( TEXT_START_ANO_TAG, offset );
789                            // セルã®ã‚³ãƒ¡ãƒ³ãƒˆã?å ´åˆã?<text:pã§æ¤œç´¢ã™ã‚‹ã¨ã€ã‚ªãƒ–ジェクトã?ãƒ?‚­ã‚¹ãƒˆãŒæ¤œç´¢ã•れã¦ã?‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ã?
790                            // ã“ã?ãŸã‚ã€ã‚»ãƒ«ã®<text:pãŒè¦‹ã¤ã‹ã‚‹ã¾ã§æ¤œç´¢ã‚’繰り返ã™
791                            if( isCell ) {
792                                    while( !isCell( row, textStrIdx ) && textStrIdx >= 0 ) {
793                                            textStrIdx = row.indexOf( TEXT_START_ANO_TAG, textStrIdx + 1 );
794                                    }
795                            }
796                            if( textStrIdx >= 0 && textStrIdx < endIdx ) {
797                                    // セルã®ã‚³ãƒ¡ãƒ³ãƒˆã?å ´åˆã?</text:p>ã§æ¤œç´¢ã™ã‚‹ã¨ã€ã‚ªãƒ–ジェクトã?ãƒ?‚­ã‚¹ãƒˆãŒæ¤œç´¢ã•れã¦ã?‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ã?
798                                    // ã“ã?ãŸã‚ã€ã‚»ãƒ«ã®</text:p>ãŒè¦‹ã¤ã‹ã‚‹ã¾ã§æ¤œç´¢ã‚’繰り返ã™
799                                    int textEndIdx = row.lastIndexOf( TEXT_END_TAG, endIdx );
800                                    if( isCell ) {
801                                            while( !isCell( row, textEndIdx ) && textEndIdx >= 0  ) {
802                                                    textEndIdx = row.lastIndexOf( TEXT_END_TAG, textEndIdx - 1 );
803                                            }
804                                    }
805                                    if( textEndIdx >= 0 && textStrIdx < textEndIdx && textEndIdx < endIdx ) {
806                                            // <text:p xxxx> ã® xxxx> ã®éƒ¨åˆ?style定義ãªã©)を書ãè¾¼ã¿
807                                            int textStyleEnd = row.indexOf( TEXT_START_END_ANO_TAG, textStrIdx + TEXT_START_ANO_TAG.length() ) + TEXT_START_END_ANO_TAG.length();
808                                            sb.append( row.substring( offset, textStyleEnd ) );
809    
810                                            // <text:pã®ä¸­èº«(spanã‚¿ã‚°ãªã©ã‚’å–り除ã?ŸçŠ¶æ…‹ã?æ–?­—å?
811                                            String textVal = TagParser.checkKey( row.substring( textStyleEnd, textEndIdx ), sb );
812                                            // å–å¾—ã—ãŸãƒ†ã‚­ã‚¹ãƒˆå?ã«ã‚¿ã‚°æ–?­—ãŒå«ã¾ã‚Œã¦ã?‚‹å ´åˆã?ã€å?ç?—ãªã?
813    //                                      if( textVal.indexOf( "<" ) < 0 && textVal.indexOf( ">" ) < 0 ) {
814                                            if( textVal.indexOf( '<' ) < 0 && textVal.indexOf( '>' ) < 0 ) {
815                                                    // <text:p xxxx>を書ãå?ã?
816                                                    String val = getValue( key );
817                                                    // 5.5.2.4 (2012/05/16) String key ã¯ä½¿ã‚れã¦ã?ªã??ã§ã€å‰Šé™¤ã—ã¾ã™ã?
818    //                                              changeType( row, textEndIdx, key, val, getNativeType( key, textVal ), sb );
819                                                    changeType( row, textEndIdx, val, getNativeType( key, textVal ), sb );
820                                                    sb.append( val );
821                                            }
822                                            offset = textEndIdx;
823                                    }
824                            }
825                    }
826    
827                    return offset;
828            }
829    
830            /**
831             * ç¾åœ¨ã®ã‚ªãƒ•ã‚»ãƒ?ƒˆãŒã‚»ãƒ«ã‹ã©ã?‹ã‚’è¿”ã—ã¾ã™ã?
832             *
833             * trueã®å ´åˆã?セルをã?falseã®å ´åˆã?オブジェクトをæ„味ã—ã¾ã™ã?
834             *
835             * セルã¨ã—ã¦åˆ¤å®šã•れるãŸã‚ã®æ¡ä»¶ã¯ä»¥ä¸‹ã?通りã§ã™ã?
836             *  ç¾åœ¨ã®offsetを基準ã¨ã—ã¦ã€?
837             *  â‘?‰ã«<draw:(オブジェクトã?é–‹å§?ãŒè¦‹ã¤ã‹ã‚‰ãªã?
838             *  â‘¡å‰ã«<table:table-cell(セルã®å§‹ã¾ã‚?ã?draw:(オブジェクトã?å§‹ã¾ã‚?より後方ã«ã‚ã‚‹
839             *  ③後ã«</draw:(オブジェクトã?終ã‚ã‚?ãŒè¦‹ã¤ã‹ã‚‰ãªã?
840             *  ④後ã«</draw:(オブジェクトã?終ã‚ã‚?ã?/table:table-cell>(セルã®çµ‚ã‚ã‚?より後方ã«ã‚ã‚‹
841             *
842             * @param row
843             * @param offset
844             *
845             * @return ç¾åœ¨ã®ã‚ªãƒ•ã‚»ãƒ?ƒˆãŒã‚»ãƒ«ã‹ã©ã?‹(falseã®å ´åˆã?オブジェクãƒ?
846             */
847            private boolean isCell( final String row, final int offset ) {
848                    int drawStartOffset = row.lastIndexOf( DRAW_START_KEY, offset );
849                    if( drawStartOffset < 0 ) {
850                            return true;
851                    }
852                    else {
853                            int cellStartOffset = row.lastIndexOf( TABLE_CELL_START_TAG, offset );
854                            if( drawStartOffset < cellStartOffset ) {
855                                    return true;
856                            }
857                            else {
858                                    int drawEndOffset = row.indexOf( DRAW_END_KEY, offset );
859                                    if( drawEndOffset < 0 ) {
860                                            return true;
861                                    }
862                                    else {
863                                            int cellEndOffset = row.indexOf( TABLE_CELL_END_TAG, offset );
864                                            // 5.1.8.0 (2010/07/01) Avoid unnecessary if..then..else statements when returning a boolean
865                                            return ( cellEndOffset >= 0 && cellEndOffset < drawEndOffset );
866    //                                      if( cellEndOffset >= 0 && cellEndOffset < drawEndOffset ) {
867    //                                              return true;
868    //                                      }
869    //                                      else {
870    //                                              return false;
871    //                                      }
872                                    }
873                            }
874                    }
875            }
876    
877            /**
878             * QRコードを作æ?ã—ã¾ã™ã?
879             * ã“ã?処ç?§ã¯ã€offsetã‚’é?ã‚ã‚‹ãŸã‚ã€æˆ»ã‚Šå?ã¨ã—ã¦å‡¦ç?¾Œã?offsetã‚’è¿”ã—ã¾ã™ã?
880             *
881             * @og.rev 4.3.1.1 (2008/08/23) mkdirs ã®æˆ»ã‚Šå?判å®?
882             * @og.rev 4.3.3.5 (2008/11/08) ↑ã?判定ã?存在ãƒã‚§ãƒ?‚¯ã‚’行ã£ã¦ã‹ã‚‰å‡¦ç?™ã‚‹ã?ファイルåã«å‡¦ç?¡Œã‚’付加
883             * @og.rev 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
884             *
885             * @param row
886             * @param curOffset
887             * @param key
888             * @param sb
889             *
890             * @return 処ç?¾Œã?オフセãƒ?ƒˆ
891             */
892            private int makeQRImage( final String row, final int curOffset, final String key, final StringBuilder sb ) {
893                    int offset = curOffset;
894    
895                    // {@QRCODE.XXXX}ã‹ã‚‰å®Ÿéš›ã«ç”»åƒã?ãƒ‘ã‚¹ãŒæ›¸ã‹ã‚Œã¦ã?‚‹éƒ¨åˆ?¾ã§ã‚’書ãè¾¼ã‚?
896                    offset = row.indexOf( DRAW_IMG_START_TAG, offset ) + DRAW_IMG_START_TAG.length();
897                    sb.append( row.substring( curOffset, offset ) );
898                    // ç”»åƒã?パスã®çµ‚äº?‚¤ãƒ³ãƒ?ƒƒã‚¯ã‚¹ã‚’求ã‚ã‚?
899                    offset = row.indexOf( DRAW_IMG_HREF_END, offset ) + DRAW_IMG_HREF_END.length();
900    
901                    // QRCODEã®ç”»åƒãƒ•ァイルåã‚’æ±‚ã‚æ›¸ãè¾¼ã‚?
902                    // 4.3.3.5 (2008/11/08) ファイルåã«å‡¦ç?¡Œã‚’付加
903                    String fileName = IMG_DIR + '/' + key + "_" + currentBaseRow + QRCODE_FILETYPE;
904                    sb.append( fileName ).append( DRAW_IMG_HREF_END );
905    
906                    // QRCODEã«æ›¸ãè¾¼ã‚??を求ã‚ã‚?
907                    String value = getValue( key );
908    
909                    // QRCODEã®ä½œæ?
910                    // 4.3.3.5 (2008/11/08) ファイルåã«å‡¦ç?¡Œã‚’付加
911                    String fileNameAbs =
912                            new File( path ).getAbsolutePath() + File.separator + IMG_DIR + File.separator + key + "_" + currentBaseRow + QRCODE_FILETYPE;
913    
914                    // ç”»åƒãƒªãƒ³ã‚¯ãŒç„¡åйã¨ãªã£ã¦ã?‚‹å ´åˆã?ã€Picturesã®ãƒ•ォルãƒ?Œä½œæ?ã•れã¦ã?ªã?¯èƒ½æ€§ãŒã‚ã‚?
915                    // 4.3.1.1 (2008/08/23) mkdirs ã®æˆ»ã‚Šå?判å®?
916                    // 4.3.3.5 (2008/11/08) 存在ãƒã‚§ãƒ?‚¯è¿½åŠ?
917                    if( !new File( fileNameAbs ).getParentFile().exists() ) {
918                            if( new File( fileNameAbs ).getParentFile().mkdirs() ) {
919                                    System.err.println( fileNameAbs + " ã® ãƒ?‚£ãƒ¬ã‚¯ãƒˆãƒªä½œæ?ã«å¤±æ•—ã—ã¾ã—ãŸã€? );
920                            }
921                    }
922    
923                    QrcodeImage qrImage = new QrcodeImage();
924                    qrImage.init( value, fileNameAbs );
925                    qrImage.saveImage();
926    
927                    // 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
928                    addObjs.put( fileName, QRCODE_FILETYPE.substring( 1 ) );
929    
930                    // 読ã¿è¾¼ã¿Offsetã‚’è¿”ã—ã¾ã?
931                    return offset;
932            }
933    
934            /**
935             * DBTableModelã«è¨­å®šã•れãŸãƒ‘スã‹ã‚‰ç”»åƒãƒ‡ãƒ¼ã‚¿ã‚’å–å¾—ã—ã€å?部ã«å–り込ã¿ã¾ã?
936             * ã“ã?処ç?§ã¯ã€offsetã‚’é?ã‚ã‚‹ãŸã‚ã€æˆ»ã‚Šå?ã¨ã—ã¦å‡¦ç?¾Œã?offsetã‚’è¿”ã—ã¾ã™ã?
937             *
938             * @og.rev 4.3.3.5 (2008/11/08) æ–°è¦è¿½åŠ?
939             * @og.rev 4.3.3.6 (2008/11/15) ç”»åƒãƒ‘スãŒå­˜åœ¨ã—ãªã??åˆã?ã€ãƒªãƒ³ã‚¯ã‚¿ã‚°(draw:image)自体を削除
940             * @og.rev 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
941             *
942             * @param row
943             * @param curOffset
944             * @param key
945             * @param sb
946             *
947             * @return 処ç?¾Œã?オフセãƒ?ƒˆ
948             */
949            private int changeImage( final String row, final int curOffset, final String key, final StringBuilder sb ) {
950                    int offset = curOffset;
951                    File imgFile = null;
952    
953                    // ç”»åƒãƒ•ァイルを読ã¿è¾¼ã‚?ƒ‘スを求ã‚ã‚?
954                    String value = getValue( key );
955    
956                    if( value != null && value.length() > 0 ) {
957                            imgFile = new File( HybsSystem.url2dir( value ) );
958                    }
959    
960                    // ç”»åƒãƒ•ァイルã®ãƒ‘スãŒå?ã£ã¦ã?¦ã€å®Ÿéš›ã«ç”»åƒãŒå­˜åœ¨ã™ã‚‹å ´å?
961                    if( imgFile != null && imgFile.exists() ) {
962                            // {@IMG.XXXX}ã‹ã‚‰å®Ÿéš›ã«ç”»åƒã?ãƒ‘ã‚¹ãŒæ›¸ã‹ã‚Œã¦ã?‚‹éƒ¨åˆ?¾ã§ã‚’書ãè¾¼ã‚?
963                            offset = row.indexOf( DRAW_IMG_START_TAG, offset ) + DRAW_IMG_START_TAG.length();
964                            sb.append( row.substring( curOffset, offset ) );
965    
966                            // ç”»åƒã?パスã®çµ‚äº?‚¤ãƒ³ãƒ?ƒƒã‚¯ã‚¹ã‚’求ã‚ã‚?
967                            offset = row.indexOf( DRAW_IMG_HREF_END, offset ) + DRAW_IMG_HREF_END.length();
968    
969                            String fileNameOut = IMG_DIR + '/' + imgFile.getName();
970                            sb.append( fileNameOut ).append( DRAW_IMG_HREF_END );
971    
972                            String fileNameOutAbs =
973                                    new File( path ).getAbsolutePath() + File.separator + IMG_DIR + File.separator + imgFile.getName();
974                            if( !new File( fileNameOutAbs ).getParentFile().exists() ) {
975                                    if( new File( fileNameOutAbs ).getParentFile().mkdirs() ) {
976                                            System.err.println( fileNameOutAbs + " ã® ãƒ?‚£ãƒ¬ã‚¯ãƒˆãƒªä½œæ?ã«å¤±æ•—ã—ã¾ã—ãŸã€? );
977                                    }
978                            }
979                            FileUtil.copy( imgFile, new File( fileNameOutAbs ) );
980    
981                            // 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
982                            addObjs.put( fileNameOut, getSuffix( imgFile.getName() ) );
983                    }
984                    // ç”»åƒãƒ‘スãŒè¨­å®šã•れã¦ã?ªã??åˆã?ç”»åƒãŒå­˜åœ¨ã—ãªã??å?
985                    else {
986                            // {@IMG.XXXX}ã‹ã‚‰è¦‹ã¦ã€?draw:image> ... </draw:image>ã¾ã§ã‚’スキãƒ??ã™ã‚‹
987                            offset = row.indexOf( DRAW_IMG_START_TAG, offset );
988                            sb.append( row.substring( curOffset, offset ) );
989    
990                            offset = row.indexOf( DRAW_IMG_END_TAG, offset ) + DRAW_IMG_END_TAG.length();
991                    }
992    
993                    // 読ã¿è¾¼ã¿Offsetã‚’è¿”ã—ã¾ã?
994                    return offset;
995            }
996    
997            /**
998             * 変æ›å¾Œã?行データã§å®šç¾©ã•れã¦ã?‚‹é–¢æ•°ã«ISERROR関数を埋ã‚è¾¼ã¿ã¾ã™ã?
999             *
1000             * ã“れã¯ã€OOoã®é–¢æ•°ã®å‹•作ã¨ã—ã¦ã€ä¸æ­£ãªå¼•æ•°ç­‰ãŒå…¥åŠ›ã•れãŸå ´å?null値ãªã©)ã«ã€?
1001             * エラー:xxxã¨è¡¨ç¤ºã•れã¦ã—ã¾ã?Ÿã‚ã?ã“れを防ããŸã‚ã«é–¢æ•°ã‚¨ãƒ©ãƒ¼ã®ãƒãƒ³ãƒ‰ãƒªãƒ³ã‚°ã‚’行ã„ã€?
1002             * エラーã®å ´åˆã?ã€ç©ºç™½æ–?­—ã‚’è¿”ã™ã‚ˆã†ã«ã—ã¾ã™ã?
1003             *
1004             * @og.rev 4.3.7.2 (2009/06/15) 開始文字ãŒå¤‰æ›´ã«ãªã£ãŸãŸã‚対å¿?
1005             * @og.rev 5.0.2.0 (2009/11/01) 関数å†??"(quot)ã¯ã€ãƒ¡ã‚¿æ–?­—ã«å¤‰æ›ã™ã‚‹
1006             * @og.rev 5.1.7.0 (2010/06/01) 関数ã®çµ‚ã‚りãŒ)出ãªã??åˆã«ã‚¨ãƒ©ãƒ¼ã¨ãªã‚‹ãƒã‚°ã‚’修正
1007             * @og.rev 5.1.8.0 (2010/07/01) パã?ス方法ã?å†?ƒ¨å®Ÿè£?¤‰æ›´
1008             *
1009             * @param row
1010             *
1011             * @return 変æ›å¾Œã?行データ
1012             */
1013            private String replaceOoocError( final String row ) {
1014                    // 4.3.7.2 (2009/06/15) OOOC_FUNCTION_START3ã®æ¡ä»¶åˆ¤å®šè¿½åŠ??ã©ã¡ã‚‰ã‹åˆ?‹ã‚‰ãªã??ã§å¤‰æ•°ã§å—ã‘ã‚‹ã?
1015                    final String functionStart;
1016                    if( row.indexOf( OOOC_FUNCTION_START_3 ) >= 0 )              { functionStart = OOOC_FUNCTION_START_3; }
1017                    else if( row.indexOf( OOOC_FUNCTION_START ) >= 0 )   { functionStart = OOOC_FUNCTION_START; }
1018                    else { return row; }
1019    
1020                    String rowStr = new TagParser() {
1021                            @Override
1022                            protected boolean checkIgnore( final int strOffset, final int endOffset ) {
1023                                    // 5.1.7.0 (2010/06/01) 関数ã®çµ‚ã‚りãŒ)出ãªã??åˆã«ã‚¨ãƒ©ãƒ¼ã¨ãªã‚‹ãƒã‚°ã‚’修正
1024                                    // å˜ãªã‚‹è¡Œå‚ç…§ã§ã‚‚ã?of:=ã§å§‹ã¾ã‚‹ãŒã“ã?å ´åˆã?ã€?–¢æ•°ã§ãªã?Ÿã‚終ã‚りãŒ)ã§ãªã?
1025                                    // ã“ã?ãŸã‚ã€?ãŒè¦‹ã¤ã‹ã‚‰ãªã?¾ãŸã?ã€ã‚¿ã‚°ã®çµ‚ã‚ã‚?>)ãŒå?ã«è¦‹ã¤ã‹ã£ãŸå?åˆã?ã€ã‚¨ãƒ©ãƒ¼é–¢æ•°ã‚?
1026                                    // 埋ã‚è¾¼ã¾ãªã?‚ˆã?«ã™ã‚‹ã€?
1027                                    int tmpOffset = row.indexOf( ">", strOffset + 1 );
1028                                    return ( endOffset >= 0 && endOffset < tmpOffset );
1029                            }
1030    
1031                            @Override
1032                            protected void exec( final String str, final StringBuilder buf, final int offset ) {
1033                                    String key = str.substring( functionStart.length(), str.length() - OOOC_FUNCTION_END.length() ) + ")";
1034                                    key = key.replace( "\"", "&quot;&quot;" ).replace( OOO_CR, "" );
1035                                    buf.append( functionStart + "IF(ISERROR(" + key + ");&quot;&quot;;" + key + OOOC_FUNCTION_END );
1036                            }
1037                    }.doParse( row, functionStart, OOOC_FUNCTION_END );
1038    
1039                    return rowStr;
1040            }
1041    
1042            /**
1043             * グラフ表示ãƒ??タ部åˆ?‚’æ›´æ–°ã—ã¾ã™ã?
1044             *
1045             * @og.rev 5.1.8.0 (2010/07/01) æ–°è¦ä½œæ?
1046             * @og.rev 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
1047             *
1048             * @param row
1049             * @param sheetOrig
1050             * @param sheetNew
1051             *
1052             * @return 変æ›å¾Œã?行データ
1053             */
1054            private String replaceGraphInfo( final String row, final String sheetOrig, final String sheetNew  ) {
1055                    if( row.indexOf( GRAPH_START_TAG ) < 0 || row.indexOf( GRAPH_UPDATE_RANGE_START ) < 0 ) { return row; }
1056    
1057    //              final List<String> addObjs = new ArrayList<String>();
1058                    String rowStr = new TagParser() {
1059                            @Override
1060                            protected void exec( final String str, final StringBuilder buf, final int offset ) {
1061                                    // <draw:object ... /> ã®éƒ¨åˆ?
1062                                    String graphTag = str;
1063    
1064                                    if( graphTag.indexOf( GRAPH_UPDATE_RANGE_START ) >= 0 ) {
1065                                            String nameOrig = TagParser.getValueFromTag( graphTag, GRAPH_HREF_START, GRAPH_HREF_END );
1066                                            if( new File( path + nameOrig ).exists() ) {
1067                                                    String nameNew = nameOrig + "_" + pages;
1068    
1069                                                    // グラフオブジェクトã?定義ファイルをコピã?(./Object X/* -> ./Object X_n/*)
1070                                                    FileUtil.copyDirectry( path + nameOrig, path + nameNew );
1071                                                    graphTag = graphTag.replace( GRAPH_HREF_START + nameOrig, GRAPH_HREF_START + nameNew );
1072    
1073                                                    // グラフオブジェクトã?ç”»åƒã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’コピã?(./ObjectReplacements/Object X -> ./ObjectReplacements/Object X_n)
1074                                                    // ※実体ã?コピã?ã—ãªã?リンクã®å‚ç?を無効ã«ã—ã¦ãŠãã“ã¨ã§ã€æ¬¡å›žèµ·å‹•時ã«ã‚°ãƒ©ãƒ•ã?å†æç”»ãŒè¡Œã‚れる)
1075    //                                              FileUtil.copy( path + GRAPH_OBJREPL + File.separator + nameOrig, path + "ObjectReplacements" + File.separator + nameNew );
1076                                                    graphTag = graphTag.replace( GRAPH_HREF_START + GRAPH_OBJREPL + "/" + nameOrig, GRAPH_HREF_START + GRAPH_OBJREPL + "/" + nameNew );
1077    
1078                                                    // OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
1079    //                                              addObjs.add( nameNew );
1080                                                    addObjs.put( nameNew, "graph" );
1081    
1082                                                    // グラフオブジェクトã?定義ファイルã«è¨˜è¿°ã•れã¦ã?‚‹å®šç¾©ãƒ•ァイルをパースã—ã?シートåã¨{@XXXX}ã‚’ç½®ãæ›ã?
1083                                                    parseGraphContent( path + nameNew + File.separator + "content.xml", sheetOrig, sheetNew );
1084    
1085                                                    // グラフã?å‚ç?ç¯?›²ã®ã‚·ãƒ¼ãƒˆåã‚’ç½®ãæ›ã?
1086                                                    String range = TagParser.getValueFromTag( str, GRAPH_UPDATE_RANGE_START, GRAPH_UPDATE_RANGE_END );
1087                                                    graphTag = graphTag.replace( GRAPH_UPDATE_RANGE_START + range, GRAPH_UPDATE_RANGE_START + range.replace( sheetOrig, sheetNew ) );
1088                                            }
1089                                    }
1090    
1091                                    buf.append( graphTag );
1092                            }
1093                    }.doParse( row, GRAPH_START_TAG, GRAPH_END_TAG );
1094    
1095                    // 5.3.1.0 (2011/01/01) OpenOffice3.2対å¿?追åŠ?—ãŸç”»åƒã‚’manifest.xmlã«ç™»éŒ²ã™ã‚‹
1096    //              if( addObjs.size() > 0 ) {
1097    //                      parseManifest( path + "META-INF" + File.separator + "manifest.xml", addObjs.toArray( new String[0]  ) );
1098    //                      parseManifest( path + "META-INF" + File.separator + "manifest.xml", addObjs.toArray( new String[addObjs.size()]  ) );
1099    //                      parseManifest( path + "META-INF" + File.separator + "manifest.xml", addObjs.toArray( new String[addObjs.size()]  ) );
1100    //              }
1101    
1102                    return rowStr;
1103            }
1104    
1105            /**
1106             * グラフデータã®content.xmlをパースã—ã¾ã™ã?
1107             *
1108             * @og.rev 5.1.8.0 (2010/07/01) æ–°è¦ä½œæ?
1109             *
1110             * @param fileName
1111             * @param sheetOrig
1112             * @param sheetNew
1113             */
1114            private void parseGraphContent( final String fileName, final String sheetOrig, final String sheetNew  ) {
1115                    String graphContent = readOOoXml( fileName );
1116    
1117                    // シートåã®ç½®ãæ›ã?
1118                    if( graphContent.indexOf( GRAPH_CONTENT_START ) >= 0 ) {
1119                            graphContent = new TagParser() {
1120                                    @Override
1121                                    protected void exec( final String str, final StringBuilder buf, final int offset ) {
1122                                            buf.append( str.replace( sheetOrig, sheetNew ) );
1123                                    }
1124                            }.doParse( graphContent, GRAPH_CONTENT_START, GRAPH_CONTENT_END );
1125                    }
1126    
1127                    // {@XXXX}ã®ç½®ãæ›ã?
1128                    if( graphContent.indexOf( VAR_START ) >= 0 ) {
1129                            graphContent = new TagParser() {
1130                                    @Override
1131                                    public void exec( final String str, final StringBuilder buf, final int offset ) {
1132                                            buf.append( getHeaderFooterValue( str ) );
1133                                    }
1134                            }.doParse( graphContent, VAR_START, VAR_END, false );
1135                    }
1136    
1137                    writeOOoXml( fileName, graphContent );
1138            }
1139    
1140    //      /**
1141    //       * META-INF/manifest.xmlã«ã€è¿½åŠ?—ãŸã‚°ãƒ©ãƒ•オブジェクトを登録ã—ã¾ã™ã?
1142    //       *
1143    //       * @og.rev 5.1.8.0 (2010/07/01) æ–°è¦ä½œæ?
1144    //       *
1145    //       * @param fileName
1146    //       * @param obj
1147    //       */
1148    //      private void parseManifest( final String fileName, final String[] objs ) {
1149    //              String[] conArr = TagParser.tag2Array( readOOoXml( fileName ), MANIFEST_START_TAG, MANIFEST_END_TAG );
1150    //
1151    //              StringBuilder buf = new StringBuilder();
1152    //              buf.append( conArr[0] );
1153    //              for( int i=2; i<conArr.length; i++ ) {
1154    //                      buf.append( conArr[i] );
1155    //              }
1156    //              for( int i=0; i<objs.length; i++ ) {
1157    //                      buf.append( "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"" + objs[i] + "/content.xml\"/>" );
1158    //                      buf.append( "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"" + objs[i] + "/styles.xml\"/>" );
1159    //                      buf.append( "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"" + objs[i] + "/meta.xml\"/>" );
1160    //                      buf.append( "<manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.chart\" manifest:full-path=\"" + objs[i] + "/\"/>" );
1161    //              }
1162    //              buf.append( conArr[1] );
1163    //
1164    //              writeOOoXml( fileName, buf.toString() );
1165    //      }
1166    
1167            /**
1168             * æŒ?®šã•れãŸã‚­ãƒ¼ã®å€¤ã‚’è¿”ã—ã¾ã™ã?
1169             *
1170             * @og.rev 4.3.0.0 (2008/07/18) アンãƒ??スコアã®å‡¦ç?¤‰æ›´
1171             * @og.rev 4.3.5.0 (2008/02/01) カラãƒ?ã¨è¡Œç•ªå·æ–?­—ã?ä½ç½®ã¯æœ?¾Œã‹ã‚‰æ¤œç´¢ã™ã‚‹ 4.3.3.4 (2008/11/01) 修正åˆ?
1172             *
1173             * @param key
1174             *
1175             * @return 値
1176             */
1177            private String getValue( final String key ) {
1178    //              int conOffset = key.indexOf( VAR_CON );
1179                    int conOffset = key.lastIndexOf( VAR_CON );
1180    
1181                    String value = null;
1182    
1183                    if( conOffset < 0 ) {
1184                            value = getHeaderFooterValue( key );
1185                    }
1186                    else {
1187                            String name = key.substring( 0, conOffset );
1188                            int rownum = -1;
1189                            try {
1190                                    rownum = Integer.valueOf( key.substring( conOffset + VAR_CON.length(), key.length() ) ) + currentBaseRow;
1191                            }
1192                            catch ( NumberFormatException ex ) {
1193                                    // 4.3.0.0 (2008/07/18) エラーãŒèµ·ãã¦ã‚‚ãªã«ã‚‚ã—ãªã??
1194                                    // queue.addMsg( "[ERROR]雛形ã®å¤‰æ•°å®šç¾©ãŒèª¤ã£ã¦ã?¾ã™ã?カラãƒ?=" + name + HybsSystem.CR );
1195                                    // throw new Exception( ex );
1196                            }
1197    
1198                            // 4.3.0.0 (2008/07/18) アンãƒ??ã‚¹ã‚³ã‚¢å¾ŒãŒæ•°å­—ã«å¤‰æ›ã§ããªã??åˆã?ヘッãƒ?ƒ•ãƒ?‚¿ã¨ã—ã¦èªè­?
1199                            if( rownum < 0 ){
1200                                    value = getHeaderFooterValue( key );
1201                            }
1202                            else{
1203                                    value = getBodyValue( name, rownum );
1204                            }
1205                    }
1206    
1207                    return checkValue( value );
1208            }
1209    
1210            /**
1211             * æŒ?®šã•れãŸã‚­ãƒ¼ã®ãƒ˜ãƒƒãƒ??ã€ãƒ•ãƒ?‚¿ãƒ¼å€¤ã‚’è¿”ã—ã¾ã™ã?
1212             *
1213             * @og.rev 4.3.6.0 (2009/04/01) レンãƒ?ƒ©ãƒ¼é©ç”¨ã•れã¦ã?ªã?ƒã‚°ã‚’修正
1214             * @og.rev 5.0.2.0 (2009/11/01) ローカルリソースフラグを使用ã—ãªã??åˆã?ã€ãƒªã‚½ãƒ¼ã‚¹å¤‰æ›ã‚’行ã‚ãªã??
1215             * @og.rev 5.1.6.0 (2010/05/01) ペã?ジNO出力対å¿?
1216             *
1217             * @param key
1218             *
1219             * @return 値
1220             */
1221            private String getHeaderFooterValue( final String key ) {
1222                    String value = "";
1223    
1224                    // 5.1.6.0 (2010/05/01) ペã?ジNO出力対å¿?
1225                    if( PAGE_NO.equals( key ) ) {
1226                            value = String.valueOf( pages + 1 );
1227                    }
1228                    // æœ?¾Œã?行ã‹ã‚ªãƒ¼ãƒã?フロー時ã?フッター
1229                    else if( status >= LASTROW ) {
1230                            if( queue.getFooter() != null ) {
1231                                    int clmno = queue.getFooter().getColumnNo( key, false );
1232                                    if( clmno >= 0 ) {
1233                                            value = queue.getFooter().getValue( 0, clmno );
1234                                            // 5.0.2.0 (2009/11/01) ローカルリソースフラグを使用ã—ãªã??åˆã?ã€ãƒªã‚½ãƒ¼ã‚¹å¤‰æ›ã‚’行ã‚ãªã??
1235                                            if( queue.isFglocal() ) {
1236                                                    // 4.3.6.0 (2009/04/01)
1237                                                    value = queue.getFooter().getDBColumn( clmno ).getRendererValue( value );
1238                                            }
1239                                    }
1240                            }
1241                    }
1242                    // æœ?¾Œã?行ã«ãã¦ã?ªã??åˆã?ヘッãƒ??
1243                    else {
1244                            if( queue.getHeader() != null ) {
1245                                    int clmno = queue.getHeader().getColumnNo( key, false );
1246                                    if( clmno >= 0 ) {
1247                                            value = queue.getHeader().getValue( 0, clmno );
1248                                            // 5.0.2.0 (2009/11/01) ローカルリソースフラグを使用ã—ãªã??åˆã?ã€ãƒªã‚½ãƒ¼ã‚¹å¤‰æ›ã‚’行ã‚ãªã??
1249                                            if( queue.isFglocal() ) {
1250                                                    // 4.3.6.0 (2009/04/01)
1251                                                    value = queue.getHeader().getDBColumn( clmno ).getRendererValue( value );
1252                                            }
1253                                    }
1254                            }
1255                    }
1256    
1257                    return value;
1258            }
1259    
1260            /**
1261             * æŒ?®šã•れãŸè¡Œç•ªå·ã€ã‚­ãƒ¼ã®ãƒœãƒ‡ã‚£ãƒ¼å€¤ã‚’è¿”ã—ã¾ã™ã?
1262             *
1263             * @og.rev 4.3.6.0 (2009/04/01) レンãƒ?ƒ©ãƒ¼é©ç”¨ã•れã¦ã?ªã?ƒã‚°ã‚’修正
1264             * @og.rev 4.3.6.2 (2009/04/15) 行番å·ã®ã‚ˆã‚Šå°ã•ã?‚«ãƒ©ãƒ?®šç¾©ã‚’読んã éš›ã«ã€å?部カウンタãŒã‚¯ãƒªã‚¢ã•れã¦ã—ã¾ã?ƒã‚°ã‚’修正
1265             * @og.rev 4.3.6.2 (2009/04/15) ä¸?º¦ã‚ªãƒ¼ãƒã?フローã—ãŸå ´åˆã«ç§»è¡ŒãŒå…¨ã¦ç©ºæ–?­—ã§è¿”ã£ã¦ã—ã¾ã?ƒã‚°ã‚’修正
1266             * @og.rev 5.0.2.0 (2009/11/01) ローカルリソースフラグを使用ã—ãªã??åˆã?ã€ãƒªã‚½ãƒ¼ã‚¹å¤‰æ›ã‚’行ã‚ãªã??
1267             * @og.rev 5.1.6.0 (2010/05/01) 行番å·å‡ºåЛ坾å¿?
1268             * @og.rev 5.1.7.0 (2010/06/01) è¤?•°ã‚·ãƒ¼ãƒˆå¯¾å¿?
1269             * @og.rev 5.1.9.0 (2010/08/01) æœ?µ‚è¡Œã§æ­£ã—ãシートブレイクã•れãªã?ƒã‚°ã‚’修正
1270             *
1271             * @param key
1272             * @param rownum
1273             *
1274             * @return 値
1275             */
1276            private String getBodyValue( final String key, final int rownum ) {
1277                    // if( status == OVERFLOW || isPageBreak ) { return ""; }
1278                    if( isPageBreak ) { return ""; } // 4.3.6.2 (2009/04/15) OVERFLOW時ãƒã‚°ä¿®æ­£
1279    
1280                    int clmno = queue.getBody().getColumnNo( key, false );
1281                    if( clmno < 0 && !ROW_NO.equals( key ) ) { return ""; }
1282    
1283                    // ペã?ジブレイク判定ã?先読ã¿ã—ã¦åˆ¤æ–­
1284                    if( PAGE_BREAK.equals( key ) ) {
1285    //                      if( rownum <= queue.getBody().getRowCount() - 2 ) {
1286                            if( rownum < queue.getBody().getRowCount() - 1 ) {
1287                                    if( !( queue.getBody().getValue( rownum, clmno ).equals( queue.getBody().getValue( rownum + 1, clmno ) ) ) ) {
1288                                            isPageBreak = true;
1289                                    }
1290                            }
1291                            return "";
1292                    }
1293    
1294                    // 5.1.7.0 (2010/06/01) è¤?•°ã‚·ãƒ¼ãƒˆå¯¾å¿?
1295                    // シートブレイクã¯å¾Œèª­ã¿ã—ã¦åˆ¤æ–­(å‰ã?行ã¨ç•°ãªã£ã¦ã?Ÿå ´åˆã«ãƒ–レイク)
1296                    if( sheetBreakClm >= 0 ) {
1297                            // 5.1.9.0 (2010/08/01) æœ?µ‚è¡Œã§æ­£ã—ãシートブレイクã•れãªã?ƒã‚°ã‚’修正
1298    //                      if( rownum < queue.getBody().getRowCount() - 1 && currentBaseRow != rownum ) {
1299                            if( rownum < queue.getBody().getRowCount() && currentBaseRow != rownum ) {
1300                                    if( !( queue.getBody().getValue( currentBaseRow, sheetBreakClm ).equals( queue.getBody().getValue( rownum, sheetBreakClm ) ) ) ) {
1301                                            isPageBreak = true;
1302                                            return "";
1303                                    }
1304                            }
1305                    }
1306    
1307                    if( rownum >= queue.getBody().getRowCount() ) {
1308                            status = OVERFLOW;
1309                            return "";
1310                    }
1311    
1312                    if( rownum == queue.getBody().getRowCount() - 1 ) {
1313                            // status = LASTROW;
1314                            status = Math.max( LASTROW, status ); // 4.3.6.2 (2009/04/15) 自身ã®ã‚¹ãƒ??ã‚¿ã‚¹ã¨æ¯”ã¹ã¦å¤§ãã„æ–¹ã‚’è¿”ã™
1315                    }
1316    
1317                    String value = null;
1318                    // 5.1.6.0 (2010/05/01) ペã?ジNO出力対å¿?
1319                    if( ROW_NO.equals( key ) ) {
1320                            value = String.valueOf( rownum + 1 );
1321                    }
1322                    else {
1323                            value = queue.getBody().getValue( rownum, clmno );
1324                            // 5.0.2.0 (2009/11/01) ローカルリソースフラグを使用ã—ãªã??åˆã?ã€ãƒªã‚½ãƒ¼ã‚¹å¤‰æ›ã‚’行ã‚ãªã??
1325                            if( queue.isFglocal() ) {
1326                                    // 4.3.6.0 (2009/04/01)
1327                                    value = queue.getBody().getDBColumn( clmno ).getRendererValue( value );
1328                            }
1329                    }
1330    
1331                    // 4.3.6.2 (2009/04/15)
1332                    if( currentMaxRow < rownum + 1 ) {
1333                            currentMaxRow = rownum + 1;
1334                    }
1335    
1336                    return value;
1337            }
1338    
1339            /**
1340             * 値ã«'<'ã‚?>','&'ãŒå«ã¾ã‚Œã¦ã?Ÿå ´åˆã«ãƒ¡ã‚¿æ–?­—ã«å¤‰æ›ã—ã¾ã™ã?
1341             *
1342             * @og.rev 5.0.2.0 (2009/11/01) 改行Cã®å¤‰æ›ãƒ­ã‚¸ãƒ?‚¯ã‚’追åŠ?
1343             * @og.rev 5.0.2.0 (2009/11/01) ãƒªã‚½ãƒ¼ã‚¹å¤‰æ›æ™‚ã?spanタグを除去
1344             *
1345             * @param value
1346             *
1347             * @return 変æ›å¾Œã?値
1348             */
1349            private String checkValue( final String value ) {
1350                    String rtn = value;
1351    
1352                    // 5.0.2.0 (2009/11/01)
1353                    if( queue.isFglocal() ) {
1354                            int idx = -1;
1355                            if( ( idx = rtn.indexOf( "<span" ) ) >= 0 ) {
1356                                    String spanStart = rtn.substring( idx, rtn.indexOf( '>', idx ) + 1 );
1357                                    rtn = rtn.replace( spanStart, "" ).replace( "</span>", "" );
1358                            }
1359                    }
1360    
1361                    if( rtn.indexOf( '&' ) >= 0 ) {
1362                            rtn = rtn.replace( "&", "&amp;" );
1363                    }
1364                    if( rtn.indexOf( '<' ) >= 0 ) {
1365                            rtn = rtn.replace( "<", "&lt;" );
1366                    }
1367                    if( rtn.indexOf( '>' ) >= 0 ) {
1368                            rtn = rtn.replace( ">", "&gt;" );
1369                    }
1370                    if( rtn.indexOf( '\n' ) >= 0 ) {
1371                            rtn = rtn.replace( "\r\n", "\n" ).replace( "\n", OOO_CR );
1372                    }
1373    
1374                    return rtn;
1375            }
1376    
1377            /**
1378             * å¼•æ•°ã®æ–?­—å?を指定ã•れãŸé–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ã§è§£æžã—é…å?ã¨ã—ã¦è¿”ã—ã¾ã™ã?
1379             * 開始タグよりå‰ã?æ–?­—å?ã¯0番目ã«ã€çµ‚äº?‚¿ã‚°ã‚ˆã‚Šå¾Œã?æ–?­—å?ã¯1ç•ªç›®ã«æ ¼ç´ã•れã¾ã™ã?
1380             * 2番目以é™ã«ã€?–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ã®éƒ¨åˆ?Œæ ¼ç´ã•れã¾ã™ã?
1381             *
1382             * @param str
1383             * @param startTag
1384             * @param endTag
1385             *
1386             * @return è§£æžçµæžœã®é…å?
1387             */
1388            private static String[] tag2Array( final String str, final String startTag, final String endTag ) {
1389                    String header = null;
1390                    String footer = null;
1391                    List<String> body = new ArrayList<String>();
1392    
1393                    int preOffset = -1;
1394                    int curOffset = 0;
1395    
1396                    while( true ) {
1397                            curOffset = str.indexOf( startTag, preOffset + 1 );
1398                            if( curOffset < 0 ) {
1399                                    curOffset = str.lastIndexOf( endTag ) + endTag.length();
1400                                    body.add( str.substring( preOffset, curOffset ) );
1401    
1402                                    footer = str.substring( curOffset );
1403                                    break;
1404                            }
1405                            else if( preOffset == -1 ) {
1406                                    header = str.substring( 0, curOffset );
1407                            }
1408                            else {
1409                                    body.add( str.substring( preOffset, curOffset ) );
1410                            }
1411                            preOffset = curOffset;
1412                    }
1413    
1414                    String[] arr = new String[body.size()+2];
1415                    arr[0] = header;
1416                    arr[1] = footer;
1417                    for( int i=0; i<body.size(); i++ ) {
1418                            arr[i+2] = body.get(i);
1419                    }
1420    
1421                    return arr;
1422            }
1423    
1424            /**
1425             * 帳票処ç?‚­ãƒ¥ãƒ¼ã‚’å?ã«ã€style.xml(ヘッãƒ??ã€ãƒ•ãƒ?‚¿ãƒ¼)ã‚’æ›¸ãæ›ãˆã¾ã™ã?
1426             *
1427             * @og.rev 5.1.8.0 (2010/07/01) パã?ス方法ã?å†?ƒ¨å®Ÿè£?¤‰æ›´
1428             *
1429             * @throws Exception
1430             */
1431            private void execStyles() {
1432                    String fileName = path + "styles.xml";
1433                    String content = readOOoXml( fileName );
1434    
1435                    if( content.indexOf( VAR_START ) < 0 ) { return; }
1436                    content = new TagParser() {
1437                            @Override
1438                            public void exec( final String str, final StringBuilder buf, final int offset ) {
1439                                    buf.append( getHeaderFooterValue( str ) );
1440                            }
1441                    }.doParse( readOOoXml( fileName ), VAR_START, VAR_END, false );
1442    
1443                    writeOOoXml( fileName, content );
1444            }
1445    
1446            /**
1447             * 帳票処ç?‚­ãƒ¥ãƒ¼ã‚’å?ã«ã€meta.xmlã‚’æ›¸ãæ›ãˆã¾ã™ã?
1448             *
1449             * @og.rev 5.1.6.0 (2010/05/01) ç”»é¢å¸³ç¥¨ä½œæ?機è?対å¿?API経由ã§ã¯å‡ºåŠ›ã•れãªã?“ã¨ãŒã‚ã‚?
1450             *
1451             * @throws Exception
1452             */
1453            private void execMeta() {
1454                    String fileName = path + "meta.xml";
1455    
1456                    String meta = readOOoXml( fileName );
1457    
1458                    // ã‚·ãƒ¼ãƒˆæ•°æ›¸ãæ›ã?
1459                    // 5.1.6.0 (2010/05/01)
1460                    if( meta.indexOf( TABLE_COUNT_START_TAG ) >=0 ){
1461                            String tableCount = TagParser.getValueFromTag( meta, TABLE_COUNT_START_TAG, TABLE_COUNT_END_TAG );
1462    //                      meta = meta.replace( TABLE_COUNT_START_TAG + tableCount, TABLE_COUNT_START_TAG + String.valueOf( pages ) );
1463                            meta = meta.replace( TABLE_COUNT_START_TAG + tableCount, TABLE_COUNT_START_TAG + pages );
1464                    }
1465    
1466                    // ã‚»ãƒ«æ•°æ›¸ãæ›ã?
1467                    // 5.1.6.0 (2010/05/01)
1468                    if( meta.indexOf( CELL_COUNT_START_TAG ) >=0 ){
1469                            String cellCount = TagParser.getValueFromTag( meta, CELL_COUNT_START_TAG, CELL_COUNT_END_TAG );
1470    //                      meta = meta.replace( CELL_COUNT_START_TAG + cellCount, CELL_COUNT_START_TAG + String.valueOf( Integer.parseInt( cellCount ) * pages ) );
1471                            meta = meta.replace( CELL_COUNT_START_TAG + cellCount, CELL_COUNT_START_TAG + ( Integer.parseInt( cellCount ) * pages ) );
1472                    }
1473    
1474                    // ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæ•°æ›¸ãæ›ã?
1475                    // 5.1.6.0 (2010/05/01)
1476                    if( meta.indexOf( OBJECT_COUNT_START_TAG ) >= 0 ){
1477                            String objectCount = TagParser.getValueFromTag( meta, OBJECT_COUNT_START_TAG, OBJECT_COUNT_END_TAG );
1478                            //4.2.4.0 (2008/06/02) 存在ã—ãªã??åˆã?nullã§å¸°ã£ã¦ãã‚‹ã®ã§ç„¡è¦–ã™ã‚?
1479                            if( objectCount != null){
1480    //                              meta = meta.replace( OBJECT_COUNT_START_TAG + objectCount, OBJECT_COUNT_START_TAG + String.valueOf( Integer.parseInt( objectCount ) * pages ) );
1481                                    meta = meta.replace( OBJECT_COUNT_START_TAG + objectCount, OBJECT_COUNT_START_TAG + ( Integer.parseInt( objectCount ) * pages ) );
1482                            }
1483                    }
1484    
1485                    writeOOoXml( fileName, meta );
1486            }
1487    
1488            /**
1489             * æ›¸ãæ›ãˆå¯¾è±¡ã®ã‚¹ã‚¿ã‚¤ãƒ«ãƒªã‚¹ãƒˆã‚’å–å¾—ã—ã¾ã™ã?
1490             *
1491             * @og.rev 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
1492             *
1493             * @param header content.xmlã®ãƒ˜ãƒƒãƒ??
1494             */
1495            private void getRepStyleList( final String header ) {
1496                    String[] tags = tag2Array( header, STYLE_START_TAG, STYLE_END_TAG );
1497                    Set<String> origNameSet = pageNameMap.keySet();
1498                    for( int i=2; i<tags.length; i++ ) {
1499                            for( String origName : origNameSet ) {
1500                                    if( tags[i].indexOf( "=\"" + origName + "." ) >= 0 ) {
1501                                            String styleName = TagParser.getValueFromTag( tags[i], STYLE_NAME_START_TAG, STYLE_NAME_END_TAG );
1502                                            repStyleList.add( styleName );
1503                                            break;
1504                                    }
1505                            }
1506                    }
1507            }
1508    
1509            /**
1510             * 帳票処ç?‚­ãƒ¥ãƒ¼ã‚’å?ã«ã€content.xmlã‚’æ›¸ãæ›ãˆã¾ã™ã?
1511             * ã¾ãšã?XMLã‚’ä¸?—¦ãƒ¡ãƒ¢ãƒªä¸Šã«å±•é–‹ã—ãŸå¾Œã?シートå˜ä½ã«åˆ?§£ã—ã?ãƒ??ã‚¿ã®åŸ‹ã‚è¾¼ã¿ã‚’行ã„ã¾ã™ã?
1512             *
1513             * @og.rev 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
1514             */
1515            private void execContentHeader() {
1516                    String fileName = path + "content.xml";
1517                    String content = readOOoXml( fileName );
1518    
1519                    // ファイルã®è§£æžã—ã€ã‚·ãƒ¼ãƒ?行å˜ä½ã«åˆ?§£
1520                    String[] tags = tag2Array( content, STYLE_START_TAG, STYLE_END_TAG );
1521                    String header = tags[0];
1522                    String footer = tags[1];
1523    
1524                    BufferedWriter bw = null;
1525                    try {
1526                            bw = getWriter( fileName );
1527                            bw.write( xmlHeader );
1528                            bw.write( '\n' );
1529                            bw.write( header );
1530    
1531                            // スタイルæƒ??ã«ã‚·ãƒ¼ãƒˆä¾å­˜ã?æƒ??ãŒã‚ã‚‹å?åˆã?ã€ã?ージåˆ? ã‘コピã?ã™ã‚‹ã€?
1532                            Set<String> origNameSet = pageNameMap.keySet();
1533                            for( int i=2; i<tags.length; i++ ) {
1534                                    boolean isReplace = false;
1535                                    for( String origName : origNameSet ) {
1536                                            if( tags[i].indexOf( "=\"" + origName + "." ) >= 0 ) {
1537                                                    List<String> newNames = pageNameMap.get( origName );
1538                                                    for( String newName : newNames ) {
1539                                                            String styleStr = tags[i].replace( "=\"" + origName + "." , "=\"" + newName + "." );
1540                                                            // シートåã®æ›¸ãæ›ã?
1541                                                            String styleName = TagParser.getValueFromTag( styleStr, STYLE_NAME_START_TAG, STYLE_NAME_END_TAG );
1542                                                            styleStr = styleStr.replace( STYLE_NAME_START_TAG + styleName, STYLE_NAME_START_TAG + styleName + "_" + newName );
1543                                                            bw.write( styleStr );
1544                                                            isReplace = true;
1545                                                    }
1546                                                    break;
1547                                            }
1548                                    }
1549    
1550                                    if( !isReplace ) {
1551                                            bw.write( tags[i] );
1552                                    }
1553                            }
1554    
1555                            bw.write( footer );
1556                            bw.flush();
1557                    }
1558                    catch ( IOException ex ) {
1559                            queue.addMsg( "[ERROR]PARSE:error occurer while write ReParsed Sheet " + fileName + HybsSystem.CR );
1560                            throw new HybsSystemException( ex );
1561                    }
1562                    finally {
1563                            Closer.ioClose( bw );
1564                    }
1565            }
1566    
1567            /**
1568             * content.xmlã®ãƒ˜ãƒƒãƒ??部åˆ?‚’出力ã—ãŸcontent.xmlã«ã€ã?ãƒ?ƒ€ãƒ¼éƒ¨åˆ?»¥é™ã‚’出力ã—ã?
1569             * content.xml.bakã‚’ã?ージã—ã¾ã™ã?
1570             *
1571             * @og.rev 5.2.2.0 (2010/11/01) æ¡ä»¶ä»˜æ›¸å¼å¯¾å¿?
1572             */
1573            private void execMergeContent() {
1574                    FileChannel srcChannel = null;
1575                    FileChannel destChannel = null;
1576                    try {
1577                            srcChannel = new FileInputStream( path + "content.xml.tmp" ).getChannel();
1578                            destChannel = new FileOutputStream( path + "content.xml", true ).getChannel();
1579                            srcChannel.transferTo(0, srcChannel.size(), destChannel);
1580                    }
1581                    catch ( IOException ex ) {
1582                            queue.addMsg( "[ERROR]PARSE:error occurer while merge content.xml" + HybsSystem.CR );
1583                            throw new HybsSystemException( ex );
1584                    }
1585                    finally {
1586                            Closer.ioClose( srcChannel );
1587                            Closer.ioClose( destChannel );
1588                    }
1589                    FileUtil.deleteFiles( new File( path + "content.xml.tmp" ) );
1590            }
1591    
1592            /**
1593             * META-INF/manifest.xmlã«ã€è¿½åŠ?—ãŸã‚ªãƒ–ジェクãƒ?グラフã?ç”»åƒ?を登録ã—ã¾ã™ã?
1594             *
1595             * @og.rev 5.3.1.0 (2011/12/01) æ–°è¦ä½œæ?
1596             */
1597            private void execManifest() {
1598                    String fileName = path + "META-INF" + File.separator + "manifest.xml";
1599                    String[] conArr = TagParser.tag2Array( readOOoXml( fileName ), MANIFEST_START_TAG, MANIFEST_END_TAG );
1600    
1601                    StringBuilder buf = new StringBuilder();
1602                    buf.append( conArr[0] );
1603                    for( int i=2; i<conArr.length; i++ ) {
1604                            buf.append( conArr[i] );
1605                    }
1606                    for( Map.Entry<String,String> entry : addObjs.entrySet() ) {
1607                            if( "graph".equals( entry.getValue() ) ) {
1608                                    buf.append( "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"" + entry.getKey() + "/content.xml\"/>" );
1609                                    buf.append( "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"" + entry.getKey() + "/styles.xml\"/>" );
1610                                    buf.append( "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"" + entry.getKey() + "/meta.xml\"/>" );
1611                                    buf.append( "<manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.chart\" manifest:full-path=\"" + entry.getKey() + "/\"/>" );
1612                            }
1613                            else {
1614                                    buf.append( "<manifest:file-entry manifest:media-type=\"image/" + entry.getValue() + "\" manifest:full-path=\"" + entry.getKey() + "\"/>" );
1615                            }
1616                    }
1617                    buf.append( conArr[1] );
1618    
1619                    writeOOoXml( fileName, buf.toString() );
1620            }
1621    
1622            /**
1623             * XMLファイルを読ã¿å–りã€çµæžœã‚’è¿”ã—ã¾ã™ã?
1624             * OOoã®XMLファイルã¯å…¨ã¦1行ã‚ãŒxml宣è¨?§ã€?行目ãŒå?容全体ã¨ã?†å½¢å¼ã§ã‚ã‚‹ãŸã‚ã€?
1625             * ã“ã“ã§ã¯ã€?行目ã®å†?®¹éƒ¨åˆ?‚’è¿”ã—ã¾ã™ã?
1626             *
1627             * @og.rev 4.3.6.0 (2009/04/01) meta.xmlã§ã‚³ãƒ³ãƒ?ƒ³ãƒ??部åˆ?Œæ”¹è¡Œã•れã¦ã?‚‹å ´åˆãŒã‚ã‚‹ãŸã‚ã€ãƒ«ãƒ¼ãƒ—を回ã—ã¦èª­è¾¼ã¿
1628             *
1629             * @param fileName
1630             *
1631             * @return 読ã¿å–ã£ãŸæ–‡å­—å?
1632             */
1633            private String readOOoXml( final String fileName ) {
1634                    File file = new File ( fileName );
1635    
1636                    BufferedReader br = null;
1637                    String tmp = null;
1638                    StringBuilder buf = new StringBuilder();
1639                    try {
1640                            br = new BufferedReader( new InputStreamReader( new FileInputStream( file ), "UTF-8" ) );
1641                            xmlHeader = br.readLine();
1642    //                      str = br.readLine();
1643                            while( ( tmp = br.readLine() ) != null ) { // 4.3.6.0 (2009/04/01)
1644                                    buf.append( tmp );
1645                            }
1646                    }
1647                    catch( IOException ex ) {
1648                            queue.addMsg( "[ERROR]PARSE:Failed to read " + fileName + HybsSystem.CR );
1649                            throw new HybsSystemException( ex );
1650                    }
1651                    finally {
1652                            Closer.ioClose( br );
1653                    }
1654    
1655                    String str = buf.toString();
1656                    if( xmlHeader == null || xmlHeader.length() == 0 || str == null || str.length() == 0 ) {
1657                            queue.addMsg( "[ERROR]PARSE:Maybe " + fileName + " is Broken!" + HybsSystem.CR );
1658                            throw new HybsSystemException();
1659                    }
1660    
1661                    return str;
1662            }
1663    
1664            /**
1665             * XMLファイルを書ãè¾¼ã¿ã¾ã™ã?
1666             * OOoã®XMLファイルã¯å…¨ã¦1行ã‚ãŒxml宣è¨?§ã€?行目ãŒå?容全体ã¨ã?†å½¢å¼ã§ã‚ã‚‹ãŸã‚ã€?
1667             * ã“ã“ã§ã¯ã€?行目ã®å†?®¹éƒ¨åˆ?‚’渡ã™ã“ã¨ã§ã€XMLファイルを作æ?ã—ã¾ã™ã?
1668             *
1669             * @param fileName
1670             * @param str
1671             * @throws Exception
1672             */
1673            private void writeOOoXml( final String fileName, final String str ) {
1674                    BufferedWriter bw = null;
1675                    try {
1676                            bw = getWriter( fileName );
1677                            bw.write( xmlHeader );
1678                            bw.write( '\n' );
1679                            bw.write( str );
1680                            bw.flush();
1681                    }
1682                    catch( IOException ex  ) {
1683                            queue.addMsg( "[ERROR]PARSE:Failed to write " + fileName + HybsSystem.CR );
1684                            throw new HybsSystemException( ex );
1685                    }
1686                    finally {
1687                            Closer.ioClose( bw );
1688                    }
1689            }
1690    
1691            /**
1692             * XMLファイル書ãè¾¼ã¿ç”¨ã®ãƒ©ã‚¤ã‚¿ãƒ¼ã‚’è¿”ã—ã¾ã™ã?
1693             *
1694             * @param fileName ファイルå?
1695             *
1696             * @return ライター
1697             * @throws Exception
1698             */
1699            private BufferedWriter getWriter( final String fileName ) {
1700                    return getWriter( fileName, false );
1701            }
1702    
1703            /**
1704             * XMLファイル書ãè¾¼ã¿ç”¨ã®ãƒ©ã‚¤ã‚¿ãƒ¼ã‚’è¿”ã—ã¾ã™ã?
1705             *
1706             * @param fileName ファイルå?
1707             * @param append アベンドã™ã‚‹ã‹
1708             *
1709             * @return ライター
1710             * @throws Exception
1711             */
1712            private BufferedWriter getWriter( final String fileName, final boolean append ) {
1713                    File file = new File ( fileName );
1714                    BufferedWriter bw;
1715                    try {
1716                            bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file, append ), "UTF-8" ) );
1717                    }
1718                    catch ( UnsupportedEncodingException ex ) {
1719                            queue.addMsg( "[ERROR] Input File is written by Unsupported Encoding" );
1720                            throw new HybsSystemException( ex );
1721                    }
1722                    catch ( FileNotFoundException ex ) {
1723                            queue.addMsg( "[ERROR] File not Found" );
1724                            throw new HybsSystemException( ex );
1725                    }
1726                    return bw;
1727            }
1728    
1729            /**
1730             * ファイルåã‹ã‚‰æ‹¡å¼µå­?å°æ–‡å­?を求ã‚ã¾ã™ã?
1731             *
1732             * @param fileName
1733             *
1734             * @return æ‹¡å¼µå­?å°æ–‡å­?
1735             */
1736            public static String getSuffix( final String fileName ) {
1737                    String suffix = null;
1738                    if( fileName != null ) {
1739                            int sufIdx = fileName.lastIndexOf( '.' );
1740                            if( sufIdx >= 0 ) {
1741                                    suffix = fileName.substring( sufIdx + 1 ).toLowerCase( Locale.JAPAN );
1742                            }
1743                    }
1744                    return suffix;
1745            }
1746    }
1747