• R/O
  • HTTP
  • SSH
  • HTTPS

jaxcel: 提交


Commit MetaInfo

修訂8941815bc2988c16c96eead6a3b03f45182e173a (tree)
時間2014-11-22 03:02:17
作者noboru saitoh <msnobosan@gmal...>
Commiternoboru saitoh

Log Message

#34479 対応中
テンプレートパーサのユーザー拡張対応中

Change Summary

差異

--- a/Jaxcel/build.xml
+++ b/Jaxcel/build.xml
@@ -1,6 +1,6 @@
11 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
22 <project basedir="." default="build" name="jaxcel">
3- <property name="varsion" value="1.00.00"/>
3+ <property name="varsion" value="1.01.00"/>
44 <property name="debuglevel" value="source,lines,vars"/>
55 <property name="target" value="1.7"/>
66 <property name="source" value="1.7"/>
--- a/Jaxcel/src/jaxcel.properties
+++ b/Jaxcel/src/jaxcel.properties
@@ -1,10 +1,10 @@
1-#EL\u5f0f\u5b9a\u7fa9
1+#EL\u5f0f\u5b9a\u7fa9 \u30ab\u30b9\u30bf\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u3067\u306e\u66f4\u65b0\u4e0d\u53ef
22 el.class = org.hanei.jaxcel.parser.ELParser
33 el.directive = $
44 el.bracket.start = {
55 el.bracket.end = }
66
7-#\u65e5\u4ed8\u30fb\u6642\u523b\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u5b9a\u7fa9
7+#\u65e5\u4ed8\u30fb\u6642\u523b\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u5b9a\u7fa9 \u30ab\u30b9\u30bf\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u3067\u306e\u62e1\u5f35\u53ef
88 format.date = yyyy-MM-dd'T'HH:mm:ss.SSSXXX
99 format.date = yyyy-MM-dd'T'HH:mm:ss.SSXXX
1010 format.date = yyyy-MM-dd'T'HH:mm:ss.SXXX
@@ -32,7 +32,9 @@ format.time = HH:mm:ss.S
3232 format.time = HH:mm:ss
3333 format.time = HH:mm
3434
35-#\u6307\u793a\u5b50\u5b9a\u7fa9
35+#\u6307\u793a\u5b50\u5b9a\u7fa9 \u30ab\u30b9\u30bf\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u3067\u306etl.directive\u62e1\u5f35\u53ef
36+#tl.directive\u3092\u62e1\u5f35\u3057\u305f\u5834\u5408\u3001\u5bfe\u3068\u306a\u308btl.[tl.directive].class \u30d7\u30ed\u30d1\u30c6\u30a3\u304c\u5fc5\u8981
37+tl.symbol = #
3638 tl.directive = foreach
3739 tl.directive = if
3840 tl.bracket.start = (
--- a/Jaxcel/src/org/hanei/jaxcel/parser/AbstractTLParser.java
+++ b/Jaxcel/src/org/hanei/jaxcel/parser/AbstractTLParser.java
@@ -31,8 +31,15 @@ import org.slf4j.LoggerFactory;
3131 */
3232 public abstract class AbstractTLParser implements TLParser {
3333
34- protected static final Logger log = LoggerFactory.getLogger(Thread.currentThread().getStackTrace()[1].getClassName());
35-
34+ protected final Logger log;
35+
36+ /**
37+ * コンストラクタ
38+ */
39+ AbstractTLParser() {
40+ log = LoggerFactory.getLogger(Thread.currentThread().getStackTrace()[2].getClassName());
41+ }
42+
3643 @Override
3744 public abstract void parse(JaxcelContext context);
3845
--- a/Jaxcel/src/org/hanei/jaxcel/parser/CellParser.java
+++ b/Jaxcel/src/org/hanei/jaxcel/parser/CellParser.java
@@ -18,11 +18,11 @@
1818 */
1919 package org.hanei.jaxcel.parser;
2020
21-import java.io.IOException;
2221 import java.io.InputStream;
2322 import java.text.CharacterIterator;
2423 import java.text.StringCharacterIterator;
2524 import java.util.ArrayDeque;
25+import java.util.Arrays;
2626 import java.util.Deque;
2727 import java.util.HashMap;
2828 import java.util.Map;
@@ -31,15 +31,15 @@ import java.util.regex.Pattern;
3131
3232 import org.apache.commons.collections.ExtendedProperties;
3333 import org.apache.poi.ss.usermodel.Cell;
34-import org.apache.poi.ss.util.CellReference;
3534 import org.hanei.jaxcel.exception.JaxcelInputException;
3635 import org.hanei.jaxcel.report.JaxcelContext;
3736 import org.hanei.jaxcel.util.ExcelUtil;
37+import static org.hanei.jaxcel.parser.Constants.*;
3838 import org.slf4j.LoggerFactory;
3939 import org.slf4j.Logger;
4040
4141 /**
42- * Excelテンプレートシートの指示子(Template Language)、EL式(Expression Language)の検索、パースを行う
42+ * Excelテンプレートシートのセルに記述された指示子(Template Language)、EL式(Expression Language)の検索、パースを行う
4343 *
4444 * @since 1.01.00
4545 * @author Noboru Saito
@@ -48,46 +48,26 @@ import org.slf4j.Logger;
4848 public class CellParser {
4949
5050 private static final Logger log = LoggerFactory.getLogger(CellParser.class);
51+
52+ private static final int PARSE_MAX = 10; // 同一セルパース最大回数
5153
52- // プロパティファイル キー定義
53- private static final String DEFAULT_PROPS_NAME = "/jaxcel.properties";
54- private static final String P_EL_CLASS = "el.class";
55- private static final String P_EL_DIRECTIVE = "el.directive";
56- private static final String P_EL_BRACKET_START = "el.bracket.start";
57- private static final String P_EL_BRACKET_END = "el.bracket.end";
58- private static final String P_TL_DIRECTIVE = "tl.directive";
59- private static final String P_TL_PREFIX = "tl.";
60- private static final String P_CLASS_SUFFIX = ".class";
61- private static final String P_TL_BRACKET_START = "tl.bracket.start";
62- private static final String P_TL_BRACKET_END = "tl.bracket.end";
63- private static final String P_DATE_FORMAT = "format.date";
64- private static final String P_TIME_FORMAT = "format.time";
65-
66- // 文字・文字列定義
67- private static final String TL_START_SYMBOL = "#";
68- private static final char VALUE_BRACKET = '"';
69- private static final char ATTR_DELIMITER = ':';
70- private static final char ESCAPE_CHAR = '\\';
71- private static final char EM_SPACE = ' ';
72-
73- private static final int PARSE_MAX = 10;
74-
75- private ExtendedProperties config = null;
54+ private ExtendedProperties config = new ExtendedProperties();
7655 private Map<String, TLParser> parserMap = null;
7756 private JaxcelContext context = null;
7857 private Cell cell = null;
79- private char elDirective;
8058
81- private boolean reParseFlg; // 同一セル再パース要否フラグ
82- private int parseCount; // 同一セルパース回数
59+ private boolean needReParse; // 同一セル再パース要否フラグ
60+ private int parseCount; // 同一セルパース回数
61+
62+ private char elDirective;
8363 private char elStartBracket;
8464 private char elEndBracket;
8565 private char tlEndBracket;
86- private String matchPattern = "";
66+ private char tlSymbol;
8767
8868 private StringCharacterIterator valueIterator = new StringCharacterIterator("");
89- private Pattern ptAll = null;
90- private Matcher mtAll = null;
69+ private Pattern parserPattern = null;
70+ private Matcher parserMatches = null;
9171
9272 /**
9373 * コンストラクタ
@@ -97,32 +77,36 @@ public class CellParser {
9777 * @throws JaxcelInputException デフォルトプロパティファイル入力例外発生時
9878 */
9979 public CellParser(JaxcelContext context) {
80+
81+ // コンテキスト設定
82+ this.context = context;
83+
10084 // デフォルトプロパティロード
10185 try(InputStream inStream = getClass().getResourceAsStream(DEFAULT_PROPS_NAME)) {
102- config = new ExtendedProperties();
10386 config.load(inStream);
10487 log.debug("default properties load");
105- } catch (IOException e) {
106- throw new JaxcelInputException("default properties load error");
88+ } catch (Exception e) {
89+ throw new JaxcelInputException("default properties load error", e);
10790 }
108-
109- // コンテキスト取得
110- this.context = context;
91+ // 外部プロパティロード
11192 if(this.context != null) {
112- //TODO: 外部プロパティロードを予定。デフォルトプロパティ上書く
93+ ExtendedProperties customProperties = this.context.getCustomProperties();
94+ if(customProperties != null) {
95+ // 日付・時刻書式
96+ if(customProperties.containsKey(P_DATE_FORMAT))
97+ config.addProperty(P_DATE_FORMAT, Arrays.asList(customProperties.getStringArray(P_DATE_FORMAT)));
98+ if(customProperties.containsKey(P_TIME_FORMAT))
99+ config.addProperty(P_TIME_FORMAT, Arrays.asList(customProperties.getStringArray(P_TIME_FORMAT)));
100+ // テンプレート指示子
101+ if(customProperties.containsKey(P_TL_DIRECTIVE)) {
102+ config.addProperty(P_TL_DIRECTIVE, Arrays.asList(customProperties.getStringArray(P_TL_DIRECTIVE)));
103+ for(String tlDirective : customProperties.getStringArray(P_TL_DIRECTIVE)) {
104+ config.addProperty(String.format(P_TL_CLASS, tlDirective), customProperties.getString(String.format(P_TL_CLASS, tlDirective)));
105+ }
106+ }
107+ }
113108 }
114109
115- // 初期処理
116- init();
117- }
118-
119-
120- /**
121- * 初期処理
122- */
123- private void init() {
124- log.trace("init start");
125-
126110 // パーサ ロード
127111 parserMap = new HashMap<>();
128112 try {
@@ -136,14 +120,16 @@ public class CellParser {
136120 elStartBracket = config.getString(P_EL_BRACKET_START).charAt(0);
137121 elEndBracket = config.getString(P_EL_BRACKET_END).charAt(0);
138122 parserMap.put(String.valueOf(elDirective) + String.valueOf(elStartBracket), parser);
139- log.debug("ELParser load");
123+ log.debug("parser load: {} ", cls.getSimpleName());
140124
125+ // テンプレート指示子パーサ
126+ tlSymbol = config.getString(P_TL_SYMBOL).charAt(0);
141127 tlEndBracket = config.getString(P_TL_BRACKET_END).charAt(0);
142128 for(String tlDirective : config.getStringArray(P_TL_DIRECTIVE)) {
143- cls = Class.forName(config.getString(P_TL_PREFIX + tlDirective + P_CLASS_SUFFIX));
129+ cls = Class.forName(config.getString(String.format(P_TL_CLASS, tlDirective)));
144130 parser = (TLParser) cls.newInstance();
145- parserMap.put(TL_START_SYMBOL + tlDirective + config.getString(P_TL_BRACKET_START), parser);
146- log.debug("{} load", cls.getSimpleName());
131+ parserMap.put(tlSymbol + tlDirective + config.getString(P_TL_BRACKET_START), parser);
132+ log.debug("parser load: {} ", cls.getSimpleName());
147133 }
148134 }
149135 catch(Exception e) {
@@ -151,13 +137,12 @@ public class CellParser {
151137 }
152138
153139 // 正規表現Pattern生成
140+ String matchPattern = "";
154141 for(String key : parserMap.keySet()) {
155142 matchPattern += (matchPattern.length() > 0 ? "|" : "") + Pattern.quote(key);
156143 }
157- log.debug("matchPattern: {}", matchPattern);
158- ptAll = Pattern.compile(matchPattern);
159-
160- log.trace("init end");
144+ log.debug("parser matchPattern: {}", matchPattern);
145+ parserPattern = Pattern.compile(matchPattern);
161146 }
162147
163148 /**
@@ -174,7 +159,7 @@ public class CellParser {
174159 if(cell == null) {
175160 // 再パースフラグクリア
176161 this.cell = null;
177- reParseFlg = false;
162+ needReParse = false;
178163 parseCount = 0;
179164 log.debug("cell is null");
180165 log.trace("parse end");
@@ -186,18 +171,16 @@ public class CellParser {
186171 log.debug("start new cell parse");
187172 this.cell = cell;
188173 // 再パースフラグ・カウントクリア
189- reParseFlg = false;
174+ needReParse = false;
190175 parseCount = 0;
191176 }
192177 // 保持しているセルと同一セルのパースの場合
193178 else if(ExcelUtil.equalsCellAddress(this.cell, cell, true)) {
194- // 再パースカウント加算
195- parseCount++;
196179 // 再パース回数チェック
197- if(parseCount >= PARSE_MAX) {
180+ if(++parseCount >= PARSE_MAX) {
198181 log.warn("parse repeat count over");
199182 // 再パースフラグクリア
200- reParseFlg = false;
183+ needReParse = false;
201184 log.trace("parse end");
202185 return;
203186 }
@@ -209,7 +192,7 @@ public class CellParser {
209192 // セルを保持
210193 this.cell = cell;
211194 // 再パースフラグ・カウントクリア
212- reParseFlg = false;
195+ needReParse = false;
213196 parseCount = 0;
214197 }
215198
@@ -218,16 +201,16 @@ public class CellParser {
218201 switch(cell.getCellType()){
219202 case Cell.CELL_TYPE_STRING:
220203 cellValue = cell.getStringCellValue();
221- log.debug("cell[{}] cellType: string value: {}", (new CellReference(cell)).formatAsString(), cellValue);
204+ log.debug("value: {}", cellValue);
222205 break;
223206 case Cell.CELL_TYPE_FORMULA:
224207 cellValue = cell.getCellFormula();
225- log.debug("cell[{}] cellType: formula value: {}", (new CellReference(cell)).formatAsString(), cellValue);
208+ log.debug("formula: {}", cellValue);
226209 break;
227210 default:
228- log.debug("cell type is not string or formula");
211+ log.debug("cell type is not string or )formula");
229212 // 再パースフラグクリア
230- reParseFlg = false;
213+ needReParse = false;
231214 log.trace("parse end");
232215 return;
233216 }
@@ -235,26 +218,26 @@ public class CellParser {
235218 // 解析開始
236219 TLParser parser = null;
237220 Map<String, Object> attributeMap = new HashMap<>();
238- String matchString = null;
239- String mapKey = null;
221+ String matchParser = null;
222+ String attrKey = null;
240223 StringBuilder strBuf = new StringBuilder(1024);
241- StringBuilder parseString = new StringBuilder(1024);
224+ StringBuilder templateString = new StringBuilder(1024);
242225 Deque<Character> bracketStack = new ArrayDeque<>();
243- boolean attrValueFlag, expressionFlag;
244- boolean findFlag = false;
245- boolean escapeFlag = false;
246- boolean keyParseFlag = false;
226+ boolean parserExist = false;
227+ boolean attrValueParsing;
228+ boolean expressionParsing;
229+ boolean attrKeyParsed;
230+ boolean escaping;
247231
248232 // 指示子(TL)の検索
249- mtAll = ptAll.matcher(cellValue);
233+ parserMatches = parserPattern.matcher(cellValue);
250234 // 指示子検索ループ
251- findLoop:
252- while(mtAll.find()) {
253- matchString = mtAll.group();
254- log.debug("match: {}", matchString);
235+ findLoop: while(parserMatches.find()) {
236+ matchParser = parserMatches.group();
237+ log.debug("match: {}", matchParser);
255238
256239 // パーサ取得
257- parser = parserMap.get(matchString);
240+ parser = parserMap.get(matchParser);
258241 if(parser == null) {
259242 log.warn("parser is null");
260243 continue;
@@ -262,33 +245,33 @@ public class CellParser {
262245 log.debug("parser: {}", parser.getClass().getSimpleName());
263246
264247 // クリア
265- parseString.setLength(0);
266- parseString.append(matchString);
248+ templateString.setLength(0);
249+ templateString.append(matchParser);
267250 strBuf.setLength(0);
268251 bracketStack.clear();
269252 attributeMap.clear();
270- expressionFlag = false;
271- attrValueFlag = false;
272- keyParseFlag = false;
273- escapeFlag = false;
253+ attrValueParsing = false;
254+ expressionParsing = false;
255+ attrKeyParsed = false;
256+ escaping = false;
274257
275258 // 指示子がEL式
276- if(matchString.equals(String.valueOf(elDirective) + String.valueOf(elStartBracket))) {
259+ if(matchParser.equals(String.valueOf(elDirective) + String.valueOf(elStartBracket))) {
277260 // elValueFlag ON
278- expressionFlag = true;
279- log.debug("expressionFlag: {}", expressionFlag);
261+ expressionParsing = true;
262+ log.debug("expressionParsing: {}", expressionParsing);
280263 // 括弧スタックに開始括弧push
281264 bracketStack.offerFirst(elStartBracket);
282265 }
283266
284267 // 開始括弧以降読込み
285268 valueIterator.setText(cellValue);
286- for(char c = valueIterator.setIndex(mtAll.start() + matchString.length()); c != CharacterIterator.DONE; c = valueIterator.next()) {
269+ for(char c = valueIterator.setIndex(parserMatches.start() + matchParser.length()); c != CharacterIterator.DONE; c = valueIterator.next()) {
287270 // カーソル文字抜出し
288- parseString.append(c);
271+ templateString.append(c);
289272 log.trace("current char: {}", c);
290273 // EL式解析中
291- if(expressionFlag) {
274+ if(expressionParsing) {
292275 log.trace("parsing EL");
293276 // カーソル文字がEL式終端括弧であれば
294277 if(elEndBracket == c) {
@@ -297,19 +280,19 @@ public class CellParser {
297280 // 括弧スタック空ならEL式解析終了
298281 if(bracketStack.size() == 0) {
299282 // Mapに登録
300- attributeMap.put(Constants.EXPRESSION, getTrimString(strBuf));
301- log.debug("attributeMap : {}", attributeMap);
283+ attributeMap.put(EXPRESSION, getTrimString(strBuf));
284+ log.debug("attributeMap: {}", attributeMap);
302285 // 指示子がEL式なら解析終了
303- if(matchString.equals(String.valueOf(elDirective) + String.valueOf(elStartBracket))) {
286+ if(matchParser.equals(String.valueOf(elDirective) + String.valueOf(elStartBracket))) {
304287 log.trace("parse end");
305- findFlag = true;
288+ parserExist = true;
306289 break findLoop;
307290 }
308291 // 指示子がEL式以外なら
309292 else {
310293 log.trace("EL parse end");
311294 // フラグクリア
312- expressionFlag = false;
295+ expressionParsing = false;
313296 // バッファクリア
314297 strBuf.setLength(0);
315298 }
@@ -334,43 +317,43 @@ public class CellParser {
334317 }
335318 }
336319 // 属性値解析中
337- else if(attrValueFlag) {
320+ else if(attrValueParsing) {
338321 log.trace("parsing attrValue");
339322 // カーソル文字がダブルクォートであれば
340323 if(VALUE_BRACKET == c) {
341- log.trace("escapeFlag : {}", escapeFlag);
324+ log.trace("escaping : {}", escaping);
342325 // エスケープ中なら
343- if(escapeFlag) {
326+ if(escaping) {
344327 // 括弧とはみなさずバッファに保持
345328 strBuf.append(c);
346329 // エスケープフラグクリア
347- escapeFlag = false;
330+ escaping = false;
348331 log.trace("parsing: {}", strBuf.toString());
349332 }
350333 // エスケープ中でないなら
351334 else {
352335 // Mapに登録
353- attributeMap.put(mapKey, strBuf.toString());
354- log.debug("attributeMap : {}", attributeMap);
336+ attributeMap.put(attrKey, strBuf.toString());
337+ log.trace("attributeMap: {}", attributeMap);
355338 // 属性値解析中フラグクリア
356- attrValueFlag = false;
339+ attrValueParsing = false;
357340 // バッファクリア
358341 strBuf.setLength(0);
359- mapKey = null;
342+ attrKey = null;
360343 }
361344 }
362345 // カーソル文字がダブルクォートでないなら
363346 else {
364- log.trace("escapeFlag : {}", escapeFlag);
347+ log.trace("escaping : {}", escaping);
365348 // エスケープ中なら
366- if(escapeFlag) {
349+ if(escaping) {
367350 // エスケープフラグクリア
368- escapeFlag = false;
351+ escaping = false;
369352 }
370353 // エスケープ中でなくエスケープ文字(\)なら
371354 else if(ESCAPE_CHAR == c) {
372355 // エスケープフラグON
373- escapeFlag = true;
356+ escaping = true;
374357 }
375358 // バッファに保持
376359 strBuf.append(c);
@@ -385,18 +368,18 @@ public class CellParser {
385368 log.trace("next char: {}", c);
386369 // 次の文字がEL式開始括弧であれば
387370 if(elStartBracket == c) {
388- parseString.append(c);
371+ templateString.append(c);
389372 // EL式解析中フラグセット
390- expressionFlag = true;
391- log.trace("expressionFlag : {}", expressionFlag);
373+ expressionParsing = true;
374+ log.trace("expressionParsing : {}", expressionParsing);
392375 // バッファ空でなければ
393376 if(strBuf.length() > 0) {
394377 // Mapに登録(値はnull)
395378 attributeMap.put(strBuf.toString(), null);
396- log.debug("attributeMap : {}", attributeMap);
379+ log.trace("attributeMap: {}", attributeMap);
397380 }
398381 // バッファクリア
399- mapKey = null;
382+ attrKey = null;
400383 strBuf.setLength(0);
401384 }
402385 // 次の文字がEL式開始括弧でなければ
@@ -413,26 +396,26 @@ public class CellParser {
413396 else if(ATTR_DELIMITER == c) {
414397 log.trace("parsing attr delimiter");
415398 // 属性文字列空でないなら
416- if(mapKey != null) {
399+ if(attrKey != null) {
417400 // 属性解析済みフラグセット
418- keyParseFlag = true;
419- log.trace("keyParseFlag: {}", keyParseFlag);
401+ attrKeyParsed = true;
402+ log.trace("attrKeyParsed: {}", attrKeyParsed);
420403 }
421404 // 属性文字列空なら
422405 else {
423406 // バッファ空でなければ
424407 if(strBuf.length() > 0) {
425408 // 属性文字列保持
426- mapKey = strBuf.toString();
427- log.trace("mapKey: {}", mapKey);
409+ attrKey = strBuf.toString();
410+ log.trace("mapKey: {}", attrKey);
428411 // Mapに登録(値はnull)
429- attributeMap.put(mapKey, null);
430- log.debug("attributeMap : {}", attributeMap);
412+ attributeMap.put(attrKey, null);
413+ log.trace("attributeMap: {}", attributeMap);
431414 // バッファクリア
432415 strBuf.setLength(0);
433416 // 属性解析済みフラグセット
434- keyParseFlag = true;
435- log.trace("keyParseFlag: {}", keyParseFlag);
417+ attrKeyParsed = true;
418+ log.trace("attrKeyParsed: {}", attrKeyParsed);
436419 }
437420 // 上記以外
438421 else {
@@ -446,12 +429,12 @@ public class CellParser {
446429 else if(VALUE_BRACKET == c) {
447430 log.trace("parsing attr value bracket");
448431 // 属性解析済みなら
449- if(keyParseFlag == true && mapKey != null) {
432+ if(attrKeyParsed == true && attrKey != null) {
450433 // 属性値解析中フラグセット
451- attrValueFlag = true;
452- keyParseFlag = false;
453- log.trace("attrValueFlag: {}", attrValueFlag);
454- log.trace("keyParseFlag: {}", keyParseFlag);
434+ attrValueParsing = true;
435+ attrKeyParsed = false;
436+ log.trace("attrValueParsing: {}", attrValueParsing);
437+ log.trace("attrKeyParsed: {}", attrKeyParsed);
455438 // バッファクリア
456439 strBuf.setLength(0);
457440 }
@@ -468,10 +451,10 @@ public class CellParser {
468451 // バッファ空でなければ
469452 if(strBuf.length() > 0) {
470453 // Mapに登録(値はnull)
471- mapKey = strBuf.toString();
472- log.trace("mapKey: {}", mapKey);
473- attributeMap.put(mapKey, null);
474- log.debug("attributeMap : {}", attributeMap);
454+ attrKey = strBuf.toString();
455+ log.trace("mapKey: {}", attrKey);
456+ attributeMap.put(attrKey, null);
457+ log.trace("attributeMap: {}", attributeMap);
475458 // バッファクリア
476459 strBuf.setLength(0);
477460 }
@@ -483,13 +466,13 @@ public class CellParser {
483466 if(strBuf.length() > 0) {
484467 // Mapに登録(値はnull)
485468 attributeMap.put(strBuf.toString(), null);
486- log.debug("attributeMap : {}", attributeMap);
469+ log.trace("attributeMap: {}", attributeMap);
487470 // バッファクリア
488- mapKey = null;
471+ attrKey = null;
489472 strBuf.setLength(0);
490473 }
491474 log.trace("parse end");
492- findFlag = true;
475+ parserExist = true;
493476 break findLoop;
494477 }
495478 // 上記以外
@@ -501,15 +484,15 @@ public class CellParser {
501484 }
502485 }
503486
504- log.trace("findFlag: {}", findFlag);
487+ log.trace("parser exist: {}", parserExist);
505488 // 指示子検索ヒット
506- if(findFlag) {
489+ if(parserExist) {
507490 // コンテキスト設定
508491 context.setCurrentCell(this.cell);
509- context.setParseString(parseString.toString());
492+ context.setTemplateString(templateString.toString());
510493 context.setAttributeMap(attributeMap);
511494 if(log.isDebugEnabled()) {
512- log.debug("parseString: {}", parseString);
495+ log.debug("templateString: {}", templateString.toString());
513496 log.debug("attributeMap: {}", attributeMap);
514497 }
515498 try {
@@ -521,27 +504,27 @@ public class CellParser {
521504 case Cell.CELL_TYPE_STRING:
522505 case Cell.CELL_TYPE_FORMULA:
523506 // セルタイプが文字列、数式の場合は再パースフラグ設定
524- reParseFlg = true;
507+ needReParse = true;
525508 break;
526509 default:
527510 // 上記以外は再パースフラグクリア
528- reParseFlg = false;
511+ needReParse = false;
529512 }
530513 }
531514 catch(Exception e) {
532515 log.error("parser.parse error. {}", e.getMessage(), e);
533516 // 再パースフラグクリア
534- reParseFlg = false;
517+ needReParse = false;
535518 }
536519 }
537520 // 検索ヒットせず
538521 else {
539522 log.debug("not found TL");
540523 // 再パースフラグクリア
541- reParseFlg = false;
524+ needReParse = false;
542525 }
543526
544- log.trace("parse end: reParseFlg: {} parseCount: {}", reParseFlg, parseCount);
527+ log.trace("parse end: needReParse: {} parseCount: {}", needReParse, parseCount);
545528 }
546529
547530 /**
@@ -550,7 +533,7 @@ public class CellParser {
550533 * @return 再パース必要であればはtrue。不要であればfalse
551534 */
552535 public boolean isReParseCell() {
553- return reParseFlg;
536+ return needReParse;
554537 }
555538
556539 /**
--- a/Jaxcel/src/org/hanei/jaxcel/parser/Constants.java
+++ b/Jaxcel/src/org/hanei/jaxcel/parser/Constants.java
@@ -19,12 +19,32 @@
1919 package org.hanei.jaxcel.parser;
2020
2121 /**
22- * テンプレートパーサー用定数クラス<br>
22+ * パーサー用定数クラス<br>
2323 *
2424 * @since 1.01.00
2525 * @author Noboru Saito
2626 */
2727 public class Constants {
28+ // プロパティファイル キー定義
29+ static final String DEFAULT_PROPS_NAME = "/jaxcel.properties";
30+ static final String P_EL_CLASS = "el.class";
31+ static final String P_EL_DIRECTIVE = "el.directive";
32+ static final String P_EL_BRACKET_START = "el.bracket.start";
33+ static final String P_EL_BRACKET_END = "el.bracket.end";
34+ static final String P_TL_DIRECTIVE = "tl.directive";
35+ static final String P_TL_CLASS = "tl.%s.class";
36+ static final String P_TL_BRACKET_START = "tl.bracket.start";
37+ static final String P_TL_BRACKET_END = "tl.bracket.end";
38+ static final String P_DATE_FORMAT = "format.date";
39+ static final String P_TIME_FORMAT = "format.time";
40+ static final String P_TL_SYMBOL = "tl.symbol";
41+
42+ // 文字・文字列定義
43+ static final char VALUE_BRACKET = '"';
44+ static final char ATTR_DELIMITER = ':';
45+ static final char ESCAPE_CHAR = '\\';
46+ static final char EM_SPACE = ' ';
47+
2848 public static final short FORMAT_GENERAL = 0;
2949 public static final short FORMAT_TEXT = 49;
3050 public static final String EXPRESSION = "_expression";
--- a/Jaxcel/src/org/hanei/jaxcel/parser/ELParser.java
+++ b/Jaxcel/src/org/hanei/jaxcel/parser/ELParser.java
@@ -35,6 +35,10 @@ import org.hanei.jaxcel.util.ExcelUtil;
3535 /**
3636 * EL式のパーサー実装<br>
3737 *
38+ * <h4>テンプレートの書式</h4>
39+ * <h5>${expression}</h5>
40+ * <p>expressionを解析し値を出力する。</p>
41+ *
3842 * @since 1.01.00
3943 * @author Noboru Saito
4044 */
@@ -44,14 +48,14 @@ public class ELParser extends AbstractTLParser {
4448 public void parse(JaxcelContext context) {
4549 log.trace("parse start");
4650
47- Object elResult; // パース結果保持用
51+ Object elResult;
4852 String newValue;
4953
5054 Cell cell = context.getCurrentCell();
5155 ELManager elMgr = context.getElManager();
5256
5357 // evaluate
54- elResult = elMgr.evaluate((String) context.getAttributeMap().get(Constants.EXPRESSION));
58+ elResult = elMgr.evaluate(StringUtils.defaultString((String) context.getAttributeMap().get(Constants.EXPRESSION)));
5559 if(elResult == null) {
5660 log.debug("evaluate result is null");
5761 }
@@ -60,7 +64,7 @@ public class ELParser extends AbstractTLParser {
6064 }
6165
6266 // マッチ1件目をevaluate結果で置換
63- newValue = ExcelUtil.replaceFirstCellValue(cell, context.getParseString(), (elResult == null ? "" : elResult.toString()));
67+ newValue = ExcelUtil.replaceFirstCellValue(cell, context.getTemplateString(), (elResult == null ? "" : elResult.toString()));
6468 log.debug("replace value: {}", newValue);
6569
6670 // newValueがnullの場合パース終了
--- a/Jaxcel/src/org/hanei/jaxcel/parser/ForeachParser.java
+++ b/Jaxcel/src/org/hanei/jaxcel/parser/ForeachParser.java
@@ -102,7 +102,7 @@ public class ForeachParser extends AbstractTLParser {
102102 // セルタイプのチェック、指示子をクリア
103103 switch(cell.getCellType()) {
104104 case Cell.CELL_TYPE_STRING:
105- cell.setCellValue(ExcelUtil.replaceFirstCellValue(cell, context.getParseString(), ""));
105+ cell.setCellValue(ExcelUtil.replaceFirstCellValue(cell, context.getTemplateString(), ""));
106106 break;
107107 default:
108108 // セルタイプが文字列でない場合パース終了
--- a/Jaxcel/src/org/hanei/jaxcel/parser/IfParser.java
+++ b/Jaxcel/src/org/hanei/jaxcel/parser/IfParser.java
@@ -66,7 +66,7 @@ public class IfParser extends AbstractTLParser {
6666 // セルタイプのチェック、指示子をクリア
6767 switch(cell.getCellType()) {
6868 case Cell.CELL_TYPE_STRING:
69- cell.setCellValue(ExcelUtil.replaceFirstCellValue(cell, context.getParseString(), ""));
69+ cell.setCellValue(ExcelUtil.replaceFirstCellValue(cell, context.getTemplateString(), ""));
7070 break;
7171 default:
7272 // セルタイプが文字列でない場合パース終了
--- a/Jaxcel/src/org/hanei/jaxcel/report/JaxcelContext.java
+++ b/Jaxcel/src/org/hanei/jaxcel/report/JaxcelContext.java
@@ -20,6 +20,7 @@ package org.hanei.jaxcel.report;
2020
2121 import java.util.Map;
2222
23+import org.apache.commons.collections.ExtendedProperties;
2324 import org.apache.poi.ss.usermodel.Cell;
2425 import org.apache.poi.ss.usermodel.Sheet;
2526
@@ -33,11 +34,12 @@ public class JaxcelContext {
3334
3435 private Sheet currentSheet = null;
3536 private Cell currentCell = null;
36- private String parseString = null;
37+ private String templateString = null;
3738 private Map<String, Object> attributeMap =null;
3839 private String[] dateFormat = null;
3940 private String[] timeFormat = null;
4041 private ELManager elManager = null;
42+ private ExtendedProperties customProperties = null;
4143
4244 /**
4345 * コンストラクタ
@@ -85,17 +87,17 @@ public class JaxcelContext {
8587 *
8688 * @return パース対象の文字列
8789 */
88- public String getParseString() {
89- return parseString;
90+ public String getTemplateString() {
91+ return templateString;
9092 }
9193
9294 /**
9395 * パース対象とする指示子文字列を設定
9496 *
95- * @param parseString パース対象の文字列
97+ * @param templateString パース対象の文字列
9698 */
97- public void setParseString(String parseString) {
98- this.parseString = parseString;
99+ public void setTemplateString(String parseString) {
100+ this.templateString = parseString;
99101 }
100102
101103 /**
@@ -169,5 +171,23 @@ public class JaxcelContext {
169171 public void setElManager(ELManager elManager) {
170172 this.elManager = elManager;
171173 }
174+
175+ /**
176+ * カスタムパーサー用のプロパティを返却
177+ *
178+ * @return customPropertiesオブジェクト
179+ */
180+ public ExtendedProperties getCustomProperties() {
181+ return customProperties;
182+ }
183+
184+ /**
185+ * カスタムパーサー用のプロパティを設定
186+ *
187+ * @param customProperties customPropertiesオブジェクト
188+ */
189+ public void setCustomProperties(ExtendedProperties customProperties) {
190+ this.customProperties = customProperties;
191+ }
172192
173193 }
--- a/Jaxcel/src/org/hanei/jaxcel/report/ReportMaker.java
+++ b/Jaxcel/src/org/hanei/jaxcel/report/ReportMaker.java
@@ -20,6 +20,7 @@ package org.hanei.jaxcel.report;
2020
2121 import java.io.BufferedInputStream;
2222 import java.io.File;
23+import java.io.FileInputStream;
2324 import java.io.FileOutputStream;
2425 import java.io.IOException;
2526 import java.io.InputStream;
@@ -27,6 +28,7 @@ import java.io.OutputStream;
2728 import java.util.Map;
2829
2930
31+import org.apache.commons.collections.ExtendedProperties;
3032 import org.apache.poi.hssf.usermodel.HSSFSheet;
3133 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
3234 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
@@ -197,14 +199,66 @@ public class ReportMaker {
197199 /**
198200 * テンプレート一時ファイル
199201 */
200- private File templateFile = null;
202+ private File tempFile = null;
203+
204+ /**
205+ * カスタムパーサ用ファイル
206+ */
207+ private ExtendedProperties customProperties = null;
201208
202209 /**
203- * コンストラクタ
210+ * デフォルトコンストラクタ
204211 */
205212 public ReportMaker() {}
206213
207214 /**
215+ * カスタムパーサ用のプロパティファイルを指定
216+ *
217+ * @param properties カスタムパーサ用プロパティファイル
218+ */
219+ public ReportMaker(File properties) {
220+ setCustomProperties(properties);
221+ }
222+
223+ /**
224+ * カスタムパーサ用のプロパティファイルを指定
225+ *
226+ * @param properties カスタムパーサ用プロパティファイル
227+ */
228+ public ReportMaker(InputStream properties) {
229+ setCustomProperties(properties);
230+ }
231+
232+ /**
233+ * カスタムパーサ用のプロパティファイルセッター
234+ *
235+ * @param properties カスタムパーサ用プロパティファイル
236+ */
237+ public void setCustomProperties(File properties) {
238+ if(properties != null) {
239+ try(InputStream stream = new FileInputStream(properties)) {
240+ setCustomProperties(stream);
241+ }
242+ catch(Exception e) {}
243+ }
244+ }
245+
246+ /**
247+ * カスタムパーサ用のプロパティファイルセッター
248+ *
249+ * @param properties カスタムパーサ用プロパティファイル
250+ */
251+ public void setCustomProperties(InputStream properties) {
252+ try {
253+ if(properties != null) {
254+ customProperties = new ExtendedProperties();
255+ customProperties.load(properties);
256+ }
257+ }
258+ catch(Exception e) {}
259+ }
260+
261+ /**
208262 * 入力ストリームのExcelテンプレートファイルにデータを挿入することでExcel帳票を生成、Workbookオブジェクトを返却する。<br>
209263 * 返却されたWorkbookオブジェクトはPOIを使用し、加工・出力が可能。<br>
210264 * 入力ストリームは別途クローズが必要。<br>
@@ -227,15 +281,15 @@ public class ReportMaker {
227281 }
228282
229283 // 一時ファイル作成
230- if (templateFile != null && templateFile.exists()) {
231- templateFile.delete();
232- log.debug("template file delete: {}", templateFile.getPath());
233- templateFile = null;
284+ if (tempFile != null && tempFile.exists()) {
285+ tempFile.delete();
286+ log.debug("template file delete: {}", tempFile.getPath());
287+ tempFile = null;
234288 }
235- templateFile = createTempFile(template);
289+ tempFile = createTempFile(template);
236290
237291 // Excel帳票生成
238- Workbook book = makeReport(templateFile, parameter);
292+ Workbook book = makeReport(tempFile, parameter);
239293
240294 log.trace("makeReport end");
241295 return book;
@@ -538,10 +592,10 @@ public class ReportMaker {
538592 log.debug("template file close.");
539593 pkg = null;
540594 }
541- if (templateFile != null && templateFile.exists()) {
542- templateFile.delete();
543- log.debug("template file delete: {}", templateFile.getPath());
544- templateFile = null;
595+ if (tempFile != null && tempFile.exists()) {
596+ tempFile.delete();
597+ log.debug("template file delete: {}", tempFile.getPath());
598+ tempFile = null;
545599 }
546600 } catch (IOException e) {
547601 log.error("template file close error: {}", e.getMessage(), e);
@@ -688,6 +742,9 @@ public class ReportMaker {
688742 // 文字列セル、計算式セル
689743 case Cell.CELL_TYPE_STRING:
690744 case Cell.CELL_TYPE_FORMULA:
745+ if(log.isDebugEnabled()) {
746+ log.debug("cell[{}] type is {}", (new CellReference(cell)).formatAsString(), (cell.getCellType() == Cell.CELL_TYPE_STRING ? "string" : "formula"));
747+ }
691748 // パース
692749 cellParser.parse(cell);
693750 // 再パースフラグONなら
@@ -698,7 +755,7 @@ public class ReportMaker {
698755 break;
699756 // 文字列セル、計算式セル以外
700757 default:
701- log.debug("cell type is not string or formula");
758+ log.debug("cell[{}] type is not string or formula", (new CellReference(cell)).formatAsString());
702759 continue;
703760 }
704761
Show on old repository browser