001    /*
002     * Copyright (c) 2009 The openGion Project.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013     * either express or implied. See the License for the specific language
014     * governing permissions and limitations under the License.
015     */
016    package org.opengion.hayabusa.report2;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    
021    import org.opengion.hayabusa.common.HybsSystemException;
022    
023    /**
024     * Calc帳票シスãƒ?ƒ ã§ã‚¿ã‚°ã®ãƒ‘ã?スを行ã†ãŸã‚ã®ã‚¯ãƒ©ã‚¹ã§ã™ã?
025     *
026     * 主ã«é–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ã‚’指定ã—ãŸãƒ‘ースã®ãƒ«ãƒ¼ãƒ—å?ç?‚’行ã†ãŸã‚ã®æ©Ÿè?ã‚’æä¾›ã—ã¾ã™ã?
027     * 具体的ã«ã¯ã€{@link #doParse(String, String, String)}ã«ã‚ˆã‚Šã€ãƒ‘ースæ–?­—å?ã€?–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ã‚?
028     * æŒ?®šã—ã€ãƒ‘ースを行ã„ã¾ã™ã?
029     * パã?ス後ã?æ–?­—å?ã¯ã€{@link #doParse(String, String, String)}ã®æˆ»ã‚Šå?ã«ãªã‚Šã¾ã™ã?
030     *
031     * パã?ス実行中ã«ã€ç™ºè¦‹ã•れãŸé–‹å§‹ã‚¿ã‚°ã‹ã‚‰çµ‚äº?‚¿ã‚°ã¾ã§ã®é–“ã?æ–?­—å?ã®å‡¦ç??ã€{@link #exec(String, StringBuilder, int)}ã‚?
032     * オーãƒã?ライドã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šå®šç¾©ã—ã¾ã™ã?
033     *
034     * ã¾ãŸã?ã“ã?クラスã§ã¯ã€ãƒ‘ースã«å¿?¦ãªå?¨®ãƒ¦ãƒ¼ãƒ?‚£ãƒªãƒ?‚£ãƒ¡ã‚½ãƒ?ƒ‰ã«ã¤ã?¦ã‚‚åŒæ§˜ã«å®šç¾©ã•れã¦ã?¾ã™ã?
035     *
036     * @og.group 帳票シスãƒ?ƒ 
037     *
038     * @version  4.0
039     * @author   Hiroki.Nakamura
040     * @since    JDK1.6
041     */
042    class TagParser {
043    
044            private int preOffset = 0;
045            private int curOffset = 0;
046    
047            /**
048             * パã?ス処ç?‚’行ã„ã¾ã™ã?
049             *
050             * パã?ス中ã«å–り出ã•れãŸé–‹å§‹ã‚¿ã‚°ã‹ã‚‰çµ‚äº?‚¿ã‚°ã¾ã§ã®æ–?­—å?ã®å‡¦ç??ã€?
051             * {@link #exec(String, StringBuilder, int)}ã§å®šç¾©ã—ã¾ã™ã?
052             *
053             * ã¾ãŸã?isAddTagã‚’trueã«ã—ãŸå ´åˆã?{@link #exec(String, StringBuilder, int)}ã«æ¸¡ã•れã‚?
054             * æ–?­—å?ã«ã€?–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ãŒå«ã¾ã‚Œã¾ã™ã?
055             * é€?«falseã«ã—ãŸå ´åˆã?ã€?–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ã‚’除ãã?{@link #exec(String, StringBuilder, int)}ã«æ¸¡ã•れã¾ã™ã?
056             *
057             * @og.rev 5.2.2.0 (2010/11/01) 読ã¿é£›ã?ã—ã‚’ã—ãŸå ´åˆã«ã€?–‹å§‹ã‚¿ã‚°ãŒæ›¸ãè¾¼ã¾ã‚Œãªã?ƒã‚°ã‚’修正
058             *
059             * @param content パã?ス対象æ–?­—å?
060             * @param startTag é–‹å§‹ã‚¿ã‚°
061             * @param endTag 終äº?‚¿ã‚°
062             * @param isAddTag 開始タグ・終äº?‚¿ã‚°ã‚’å«ã‚?‹
063             *
064             * @return パã?ス後ã?æ–?­—å?
065             * @see #exec(String, StringBuilder, int)
066             */
067            public String doParse( final String content, final String startTag, final String endTag, final boolean isAddTag ) {
068                    StringBuilder buf = new StringBuilder();
069                    String errMsg = null;
070    
071                    while( ( preOffset = content.indexOf( startTag, Math.max( preOffset, curOffset ) ) ) >= 0 ) {
072                            buf.append( content.substring( curOffset, preOffset ) );
073                            curOffset = content.indexOf( endTag, preOffset + startTag.length() );
074    
075                            if( checkIgnore( preOffset, curOffset ) ) {
076                                    if( curOffset < 0 ){
077                                            errMsg = "[ERROR]PARSE:開始タグを終äº?‚¿ã‚°ã®æ•´åˆæ?ãŒä¸æ­£ã§ã™ã?[é–‹å§‹ã‚¿ã‚°=" + startTag + ":終äº?‚¿ã‚°=" + endTag + "]";
078                                            throw new HybsSystemException( errMsg );
079                                    }
080                                    preOffset += startTag.length();
081                                    curOffset += endTag.length();
082    
083                                    String str = null;
084                                    if( isAddTag ) {
085                                            str = content.substring( preOffset - startTag.length(), curOffset );
086                                    }
087                                    else {
088                                            str = content.substring( preOffset, curOffset - endTag.length() );
089                                    }
090    
091                                    exec( str, buf, curOffset );
092                            }
093                            else {
094                                    // 5.2.2.0 (2010/11/01) é–‹å§‹ã‚¿ã‚°ãŒæ›¸ãè¾¼ã¾ã‚Œãªã?ƒã‚°ã‚’修正
095                                    buf.append( startTag );
096                                    preOffset += startTag.length();
097                                    curOffset = preOffset;
098                            }
099                    }
100                    buf.append( content.substring( curOffset, content.length() ) );
101    
102                    return buf.toString();
103            }
104    
105            /**
106             * パã?ス処ç?‚’行ã„ã¾ã™ã?
107             *
108             * 詳細ã¯ã€{@link #doParse(String, String, String, boolean)}ã®Javadocã‚’å‚ç…§ã—ã¦ä¸‹ã•ã??
109             *
110             * @param content パã?ス対象æ–?­—å?
111             * @param startTag é–‹å§‹ã‚¿ã‚°
112             * @param endTag 終äº?‚¿ã‚°
113             *
114             * @return パã?ス後ã?æ–?­—å?
115             * @see #doParse(String, String, String, boolean)
116             */
117            public String doParse( final String content, final String startTag, final String endTag ) {
118                    return doParse( content, startTag, endTag, true );
119            }
120    
121            /**
122             * é–‹å§‹ã‚¿ã‚°ã‹ã‚‰çµ‚äº?‚¿ã‚°ã¾ã§ã®æ–?­—å?ã®å‡¦ç?‚’定義ã—ã¾ã™ã?
123             *
124             * ã“ã?実è£?§ã¯ã€ä½•も処ç?‚’行ã„ã¾ã›ã‚“ã€?åˆ?‚Šå‡ºã—ãŸæ–?­—å?ã¯ã‚¢ãƒšãƒ³ãƒ‰ã•れã¾ã›ã‚“)
125             * サブクラスã§ã‚ªãƒ¼ãƒã?ライドã—ã¦å®Ÿéš›ã®å‡¦ç?‚’実è£?—ã¦ä¸‹ã•ã??
126             *
127             * @param str é–‹å§‹ã‚¿ã‚°ã‹ã‚‰çµ‚äº?‚¿ã‚°ã¾ã§ã®æ–?­—å?(開始タグ・終äº?‚¿ã‚°ã‚’å«ã‚?
128             * @param buf å‡ºåŠ›ã‚’è¡Œã†æ–?­—å?ãƒãƒƒãƒ•ã‚¡
129             * @param offset 終äº?‚¿ã‚°ã®ã‚ªãƒ•ã‚»ãƒ?ƒˆ
130             */
131            protected void exec( final String str, final StringBuilder buf, final int offset ) {
132                    // Document empty method 対�
133            }
134    
135            /**
136             * é–‹å§‹ã‚¿ã‚°ã‹ã‚‰çµ‚äº?‚¿ã‚°ã¾ã§ã®æ–?­—å?ã®å‡¦ç?‚’実行ã™ã‚‹ã‹ã©ã?‹ã‚’定義ã—ã¾ã™ã?
137             *
138             * falseãŒè¿”ã•れãŸå ´åˆã?何も処ç?•れãš({@link #exec(String, StringBuilder, int)}ãŒå®Ÿè¡Œã•れãªã?ã€?
139             * å…??æ–?­—å?ãŒãã®ã¾ã¾å‡ºåŠ›ã•れã¾ã™ã?
140             *
141             * @param strOffset é–‹å§‹ã‚¿ã‚°ã®ã‚ªãƒ•ã‚»ãƒ?ƒˆ
142             * @param endOffset 終äº?‚¿ã‚°ã®ã‚ªãƒ•ã‚»ãƒ?ƒˆ
143             *
144             * @return 処ç?‚’行ã†ã‹ã©ã?‹(true:処ç?‚’行ㆠfalse:処ç?‚’行ã‚ãªã?
145             */
146            protected boolean checkIgnore( final int strOffset, final int endOffset ) {
147                    return true;
148            }
149    
150            /**
151             * パã?ス実行中ã®offset値を外部ã‹ã‚‰ã‚»ãƒ?ƒˆã—ã¾ã™ã?
152             *
153             * ã“ã?メソãƒ?ƒ‰ã¯ã€{@link #exec(String, StringBuilder, int)}ã§ã€å?ç?µæžœã«ã‚ˆã‚Šã€offset値ã‚?
154             * 進ã‚ã¦ãŠãå¿?¦ãŒã‚ã‚‹å ´åˆã«åˆ©ç”¨ã•れã¾ã™ã?(ã¤ã¾ã‚Šé?常ã¯åˆ©ç”¨ã™ã‚‹å¿?¦ã?ã‚りã¾ã›ã‚“)
155             *
156             * @param offset オフセãƒ?ƒˆ
157             * @see #exec(String, StringBuilder, int)
158             */
159            public void setOffset( final int offset ) {
160                    curOffset = offset;
161            }
162    
163            /**
164             * å¼•æ•°ã®æ–?­—å?を指定ã•れãŸé–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ã§è§£æžã—é…å?ã¨ã—ã¦è¿”ã™ã€ãƒ¦ãƒ¼ãƒ?‚£ãƒªãƒ?‚£ãƒ¡ã‚½ãƒ?ƒ‰ã§ã™ã?
165             *
166             * 開始タグよりå‰ã?æ–?­—å?ã¯0番目ã«ã€çµ‚äº?‚¿ã‚°ã‚ˆã‚Šå¾Œã?æ–?­—å?ã¯1ç•ªç›®ã«æ ¼ç´ã•れã¾ã™ã?
167             * 2番目以é™ã«ã€?–‹å§‹ã‚¿ã‚°ã€çµ‚äº?‚¿ã‚°ã®éƒ¨åˆ?Œæ ¼ç´ã•れã¾ã™ã?
168             *
169             * @param str
170             * @param startTag
171             * @param endTag
172             *
173             * @return è§£æžçµæžœã®é…å?
174             */
175            public static String[] tag2Array( final String str, final String startTag, final String endTag ) {
176                    String header = null;
177                    String footer = null;
178                    List<String> body = new ArrayList<String>();
179    
180                    int preOffset = -1;
181                    int curOffset = 0;
182    
183                    while( true ) {
184                            curOffset = str.indexOf( startTag, preOffset + 1 );
185                            if( curOffset < 0 ) {
186                                    curOffset = str.lastIndexOf( endTag ) + endTag.length();
187                                    body.add( str.substring( preOffset, curOffset ) );
188    
189                                    footer = str.substring( curOffset );
190                                    break;
191                            }
192                            else if( preOffset == -1 ) {
193                                    header = str.substring( 0, curOffset );
194                            }
195                            else {
196                                    body.add( str.substring( preOffset, curOffset ) );
197                            }
198                            preOffset = curOffset;
199                    }
200    
201                    String[] arr = new String[body.size()+2];
202                    arr[0] = header;
203                    arr[1] = footer;
204                    for( int i=0; i<body.size(); i++ ) {
205                            arr[i+2] = body.get(i);
206                    }
207    
208                    return arr;
209            }
210    
211            /**
212             * å¼•æ•°ã®æ–?­—å?ã®é–‹å§‹æ–‡å­—ã¨çµ‚äº?–‡å­—ã?é–“ã?æ–?­—å?ã‚’å–りå?ã™ã?ユーãƒ?‚£ãƒªãƒ?‚£ãƒ¡ã‚½ãƒ?ƒ‰ã§ã™ã?
213             * ※返ã•れるæ–?­—å?ã«ã€?–‹å§‹æ–‡å­—ã?終äº?–‡å­—ã?å«ã¾ã‚Œã¾ã›ã‚“ã€?
214             *
215             * @param str
216             * @param start
217             * @param end
218             *
219             * @return è§£æžçµæžœã®æ–?­?
220             */
221            public static String getValueFromTag( final String str, final String start, final String end ) {
222                    int startOffset = str.indexOf( start );
223    //              int startOffset = str.indexOf( start ) + start.length();
224                    // 4.2.4.0 (2008/06/02) 存在ã—ãªã??åˆã?nullã§è¿”ã™
225                    if( startOffset == -1 ) {
226                            return null;
227                    }
228                    startOffset += start.length();
229    
230                    int endOffset = str.indexOf( end, startOffset );
231                    String value = str.substring( startOffset, endOffset );
232    
233                    return value;
234            }
235    
236            /**
237             * 引数ã®ã‚­ãƒ¼ã‹ã‚‰ä¸è¦ãªã‚­ãƒ¼ã‚’å–り除ãã?ユーãƒ?‚£ãƒªãƒ?‚£ãƒ¡ã‚½ãƒ?ƒ‰ã§ã™ã?
238             *
239             * @og.rev 5.1.8.0 (2010/07/01) spanタグを削除
240             *
241             * @param key
242             * @param sb
243             *
244             * @return 削除後ã?キー
245             */
246            public static String checkKey( final String key, final StringBuilder sb ) {
247                    if( key.indexOf( '<' ) < 0 && key.indexOf( '>' ) < 0 ) { return key; }
248    
249                    StringBuilder rtn = new StringBuilder( key );
250                    String tagEnd = ">";
251                    int rtnOffset = -1;
252    
253                    // <text:a ...>{@XXX</text:a>ã®ä¸è¦ã‚¿ã‚°ã‚’削除
254                    String delTagStart1 = "<text:a ";
255                    String delTagEnd1 = "</text:a>";
256                    while( ( rtnOffset = rtn.lastIndexOf( delTagEnd1 ) ) >= 0 ) {
257                            boolean isDel = false;
258                            // キー自身ã«å«ã¾ã‚Œã‚‹aタグを削除
259                            int startOffset = rtn.lastIndexOf( delTagStart1, rtnOffset );
260                            if( startOffset >= 0 ) {
261                                    int endOffset = rtn.indexOf( tagEnd, startOffset );
262                                    if( endOffset >= 0 ) {
263                                            rtn.delete( rtnOffset, rtnOffset + delTagEnd1.length() );
264                                            rtn.delete( startOffset, endOffset + tagEnd.length() );
265                                            isDel = true;
266                                    }
267                            }
268                            else {
269                                    // キーã®å¤–ã«å«ã¾ã‚Œã‚‹aタグを削除
270                                    startOffset = sb.lastIndexOf( delTagStart1 );
271                                    if( startOffset >= 0 ) {
272                                            int endOffset = sb.indexOf( tagEnd, startOffset );
273                                            if( endOffset >= 0 ) {
274                                                    rtn.delete( rtnOffset, rtnOffset + delTagEnd1.length() );
275                                                    sb.delete( startOffset, endOffset + tagEnd.length() );
276                                                    isDel = true;
277                                            }
278                                    }
279                            }
280                            if( !isDel ) { break; }
281                    }
282    
283                    // 5.1.8.0 (2010/07/01) spanタグを削除
284                    String delTagStart2 = "<text:span ";
285                    String delTagEnd2 = "</text:span>";
286                    while( ( rtnOffset = rtn.lastIndexOf( delTagEnd2 ) ) >= 0 ) {
287                            boolean isDel = false;
288                            // キー自身ã«å«ã¾ã‚Œã‚‹spanタグを削除
289                            int startOffset = rtn.lastIndexOf( delTagStart2, rtnOffset );
290                            if( startOffset >= 0 ) {
291                                    int endOffset = rtn.indexOf( tagEnd, startOffset );
292                                    if( endOffset >= 0 ) {
293                                            rtn.delete( rtnOffset, rtnOffset + delTagEnd2.length() );
294                                            rtn.delete( startOffset, endOffset + tagEnd.length() );
295                                            isDel = true;
296                                    }
297                            }
298                            else {
299                                    // キーã®å¤–ã«å«ã¾ã‚Œã‚‹spanタグを削除
300                                    startOffset = sb.lastIndexOf( delTagStart2 );
301                                    if( startOffset >= 0 ) {
302                                            int endOffset = sb.indexOf( tagEnd, startOffset );
303                                            if( endOffset >= 0 ) {
304                                                    rtn.delete( rtnOffset, rtnOffset + delTagEnd2.length() );
305                                                    sb.delete( startOffset, endOffset + tagEnd.length() );
306                                                    isDel = true;
307                                            }
308                                    }
309                            }
310                            if( !isDel ) { break; }
311                    }
312    
313                    return rtn.toString();
314            }
315    }
316