1. /**
  2. * Copyright: Copyright (c) 2002-2004
  3. * Company: JavaResearch(http://www.javaresearch.org)
  4. */
  5. package org.jr.java2html;
  6. import java.io.*;
  7. import java.util.*;
  8. /**
  9. * 模版文件的抽象类。
  10. * 根据相应的HTML文件模版以及参数生成html文件。
  11. * 此类定义了一些模版文件需要使用的特殊的属性关键字,包括:<Br>
  12. * <ul>
  13. * <li>时戳关键字:JTHSYSTEMTIMESTAMP
  14. * <li>循环开始标记(必须独占一行):<!--%LOOP%-->
  15. * <li>循环结束标记(必须独占一行):<!--%LOOP_END%-->
  16. * <li>循环名称关键字:JTHLOOP$,请注意‘$’应该是一个数字,从0开始
  17. * <li>循环次数关键字:JTHLOOPSIZE
  18. * </ul>
  19. * 请注意以上的关键字是保留给模版使用的,一般的属性关键字不能使用以上内容。
  20. * <br>最后更新日期:2003年5月23日
  21. * @author cherami@javaresearch.org
  22. * @version 0.9
  23. */
  24. public class TemplateFile {
  25. /**
  26. * 保留的时戳关键字。
  27. */
  28. public static final String TIMESTAMP = TemplatePropertyMap.
  29. PROPERTY_KEY_PREFIX + "JTHSYSTEMTIMESTAMP" +
  30. TemplatePropertyMap.PROPERTY_KEY_SUFFIX;
  31. /**
  32. * 循环开始标记。
  33. */
  34. public static final String LOOP_START = "<!--%LOOP%-->";
  35. /**
  36. * 循环结束标记。
  37. */
  38. public static final String LOOP_END = "<!--%LOOP_END%-->";
  39. /**
  40. * 保留的循环次数关键字。
  41. */
  42. public static final String SIZE = TemplatePropertyMap.PROPERTY_KEY_PREFIX +
  43. "JTHLOOPSIZE" + TemplatePropertyMap.PROPERTY_KEY_SUFFIX;
  44. int loopCount = 0;
  45. TemplatePropertyMap properties;
  46. File templateFile;
  47. File file;
  48. String[] templateBuffers;
  49. boolean bufferable = false;
  50. /**
  51. * 根据指定的模版文件构造一个TemplateFile。
  52. * @param templateFile 模版文件
  53. */
  54. public TemplateFile(File templateFile) {
  55. this.templateFile = templateFile;
  56. }
  57. /**
  58. * 根据指定的模版文件构造一个TemplateFile。
  59. * @param templateFileName 模版文件名
  60. */
  61. public TemplateFile(String templateFileName) {
  62. templateFile = new File(templateFileName);
  63. }
  64. /**
  65. * 根据指定的参数构造一个TemplateFile。
  66. * @param templateFile 模版文件
  67. * @param file 生成的文件
  68. * @param properties 属性映射
  69. */
  70. public TemplateFile(File templateFile, File file,
  71. TemplatePropertyMap properties) {
  72. this.properties = properties;
  73. this.templateFile = templateFile;
  74. this.file = file;
  75. }
  76. /**
  77. * 设置生成的文件的文件名。
  78. * @param fileName 生成文件的文件名
  79. */
  80. public void setFile(String fileName) {
  81. file = new File(fileName);
  82. }
  83. /**
  84. * 设置生成的文件。
  85. * @param file 生成的文件
  86. */
  87. public void setFile(File file) {
  88. this.file = file;
  89. }
  90. /**
  91. * 设置属性映射。
  92. * @param properties 属性映射
  93. */
  94. public void setProperties(TemplatePropertyMap properties) {
  95. this.properties = properties;
  96. }
  97. /**
  98. * 设置是否使用缓存。
  99. * 在从一个模版文件生成大量文件是设置使用缓存可以很大的提高生成的效率。
  100. * @param bufferable 是否使用缓存
  101. */
  102. public void setBufferable(boolean bufferable) {
  103. this.bufferable = bufferable;
  104. }
  105. /**
  106. * 生成目标文件。
  107. * @return 成功生成时返回true,否则返回false
  108. */
  109. public boolean createFile() {
  110. loopCount = 0;
  111. BufferedWriter writer = null;
  112. if (properties == null) {
  113. properties = new TemplatePropertyMap();
  114. }
  115. try {
  116. if (templateBuffers == null || bufferable == false) {
  117. getTemplateContents();
  118. }
  119. file.getParentFile().mkdirs();
  120. properties.put(TIMESTAMP, new Date().toString());
  121. writer = new BufferedWriter(new FileWriter(file));
  122. for (int i = 0; i < templateBuffers.length; i++) {
  123. int loop=0;
  124. if ((loop=replaceLoop(i, writer))>0) {
  125. i += loop;
  126. continue;
  127. }
  128. String result = properties.replaceAllProperties(templateBuffers[i]);
  129. writer.write(result);
  130. writer.newLine();
  131. }
  132. Utility.debug("Successful create file:"+file.getAbsolutePath());
  133. return true;
  134. }
  135. catch (IOException e) {
  136. System.err.println(e.getMessage());
  137. return false;
  138. }
  139. finally {
  140. if (writer != null) {
  141. try {
  142. writer.close();
  143. return false;
  144. }
  145. catch (IOException ioe) {
  146. System.err.println(ioe.getMessage());
  147. return false;
  148. }
  149. }
  150. }
  151. }
  152. /**
  153. * 得到模版文件的内容并存入缓存。
  154. * @throws IOException
  155. */
  156. private void getTemplateContents() throws IOException {
  157. BufferedReader reader = null;
  158. try {
  159. reader = new BufferedReader(new FileReader(
  160. templateFile));
  161. ArrayList lines = new ArrayList();
  162. String line = reader.readLine();
  163. while (line != null) {
  164. lines.add(line);
  165. line = reader.readLine();
  166. }
  167. templateBuffers = (String[]) lines.toArray(new String[0]);
  168. }
  169. catch (IOException e) {
  170. throw e;
  171. }
  172. finally {
  173. if (reader != null) {
  174. reader.close();
  175. }
  176. }
  177. }
  178. /**
  179. * 替换循环的内容。
  180. * @param index 模版内容缓存的行数
  181. * @param writer 缓冲写入器
  182. * @return 循环部分的行数。
  183. * @throws IOException
  184. */
  185. private int replaceLoop(int index, BufferedWriter writer) throws
  186. IOException {
  187. int result = 0;
  188. String line = templateBuffers[index];
  189. if (line.equals(LOOP_START)) {
  190. result++;//增加循环开始标记应该占用的一行
  191. String loopName = getLoopName(loopCount);
  192. StringBuffer buffer =new StringBuffer(1024);
  193. int loopIndex=index+1;
  194. int loopLength=templateBuffers.length-1;
  195. String loopLine = templateBuffers[loopIndex];
  196. while ((!loopLine.equals(LOOP_END))&&loopIndex<loopLength) {
  197. buffer.append(loopLine);
  198. result++;
  199. loopIndex++;
  200. loopLine = templateBuffers[loopIndex];
  201. }
  202. result++;//增加循环结束标记应该占用的一行
  203. TemplatePropertyMap loopProperties = (TemplatePropertyMap) properties.get(
  204. loopName);
  205. int loopTimes = Integer.parseInt( (String) loopProperties.get(SIZE));
  206. loopLine=buffer.toString();
  207. for (int i = 0; i < loopTimes; i++) {
  208. createLoopLine(writer, loopLine, loopProperties, i);
  209. }
  210. loopCount++;
  211. }
  212. return result;
  213. }
  214. /**
  215. * 创建循环内容的一行。
  216. * @param writer 缓冲写入器
  217. * @param line 原始行的内容
  218. * @param loopProperties 循环的属性映射
  219. * @param index 循环的次数
  220. * @throws IOException
  221. */
  222. private void createLoopLine(BufferedWriter writer, String line,
  223. TemplatePropertyMap loopProperties, int index) throws
  224. IOException {
  225. Iterator keys = loopProperties.keySet().iterator();
  226. while (keys.hasNext()) {
  227. String key = (String) keys.next();
  228. if (line.indexOf(key) < 0) {
  229. continue;
  230. }
  231. else {
  232. line = loopProperties.replaceByList(line, key, index);
  233. }
  234. }
  235. line = properties.replaceAllProperties(line);
  236. writer.write(line);
  237. writer.newLine();
  238. }
  239. /**
  240. * 得到循环的属性关键字。
  241. * 参数的值必须大于等于0,否则会抛出IllegalArgumentException异常。
  242. * @param loop 循环的顺序号,从0开始
  243. * @return ##JTHLOOP$@@,$为loop转换为字符串的结果
  244. */
  245. public static String getLoopName(int loop) {
  246. if (loop<0) {
  247. throw new IllegalArgumentException(
  248. "Loop must be equal or more than 0!Your loop value is:"+loop);
  249. }
  250. return TemplatePropertyMap.
  251. PROPERTY_KEY_PREFIX + "JTHLOOP" + loop + TemplatePropertyMap.PROPERTY_KEY_SUFFIX;
  252. }
  253. }