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 ã‚ーã®å¤–ã«å«ã¾ã‚Œã‚‹aタグを削除ã™ã‚‹ãŸã‚ã®ã€ãƒãƒ?ƒ•ã‚¡
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