1. /**
  2. * Copyright: Copyright (c) 2002-2004
  3. * Company: JavaResearch(http://www.javaresearch.org)
  4. */
  5. package org.jr.java2html;
  6. import java.util.*;
  7. /**
  8. * 模版属性映射的抽象类。
  9. * 此类定义模版文件中的属性关键字的格式:<BR>
  10. * <b>##UPPCASE_STRING@@</b><BR>
  11. * 前面两个'#',接着是全部大写的字符串,单词之间建议使用下划线进行分隔。另外在##和@@之间不能再包含##或者@@。<BR>
  12. * 模版文件中具有以上形式的内容都将作为模版属性进行替换。
  13. * <br>最后更新日期:2003年5月23日
  14. * @author cherami@javaresearch.org
  15. * @version 0.9
  16. */
  17. public class TemplatePropertyMap
  18. extends HashMap {
  19. /**
  20. * 属性前缀。
  21. */
  22. public static final String PROPERTY_KEY_PREFIX = "##";
  23. /**
  24. * 属性后缀。
  25. */
  26. public static final String PROPERTY_KEY_SUFFIX = "@@";
  27. static final int KEY_LEAST_LENGTH = PROPERTY_KEY_PREFIX.length() +
  28. PROPERTY_KEY_SUFFIX.length() + 1;
  29. /**
  30. * 构造一个空的TemplatePropertyMap。
  31. */
  32. public TemplatePropertyMap() {
  33. }
  34. /**
  35. * 以初始容量构造一个空的TemplatePropertyMap。
  36. * @param initialCapacity 初始容量
  37. */
  38. public TemplatePropertyMap(int initialCapacity) {
  39. super(initialCapacity);
  40. }
  41. /**
  42. * 以初始容量和装载因子构造一个空的TemplatePropertyMap。
  43. * @param initialCapacity 初始容量
  44. * @param loadFactor 装载因子
  45. */
  46. public TemplatePropertyMap(int initialCapacity,
  47. float loadFactor) {
  48. super(initialCapacity, loadFactor);
  49. }
  50. /**
  51. * 向映射中增加元素。
  52. * 关键字会被转换为一个字符串,如果关键字不是字符串实例对象会抛出IllegalArgumentException异常。
  53. * @param key 关键字
  54. * @param value 值
  55. * @return 关键字对应的上一个值,如果没有则返回null
  56. * @see #put(String key,Object value) put(String key,Object value)
  57. */
  58. public Object put(Object key,
  59. Object value) {
  60. if (!(key instanceof String)) {
  61. throw new IllegalArgumentException(
  62. "Your key must be a string object!");
  63. }
  64. return put((String)key,value);
  65. }
  66. /**
  67. * 向映射中增加元素。
  68. * 此方法会自动将普通的没有属性前缀和后缀的关键字转换为符合属性格式的关键字。
  69. * 如果关键字已经是符合的格式则不再进行处理。
  70. * <BR><b>因此关键字不能是null。</b>
  71. * 如果关键字包含小写字母、不符合规则但是又包含属性属性格式的前缀或者后缀、关键字和值相等将不能作为属性加入映射,并且会抛出IllegalArgumentException异常。<br>
  72. * <b>注意值可以是任何类对象的,在进行替换的时候将使用值的toString()方法得到的内容进行替换。</b>
  73. * @param key 关键字
  74. * @param value 值
  75. * @return 关键字对应的上一个值,如果没有则返回null
  76. */
  77. public Object put(String key,
  78. Object value) {
  79. if (!Utility.isWholeUppercase(key)) {
  80. throw new IllegalArgumentException(
  81. "Your property key must be all UPPERCASE!");
  82. }
  83. if (isPropertyKey(key)) {
  84. return directPut(key, value);
  85. }
  86. else {
  87. if (key.indexOf(PROPERTY_KEY_PREFIX)>=0||key.indexOf(PROPERTY_KEY_SUFFIX)>=0) {
  88. throw new IllegalArgumentException(
  89. "Your property key contain special string "+PROPERTY_KEY_PREFIX+" or "+PROPERTY_KEY_SUFFIX+",can not be converted to a property key!");
  90. }
  91. }
  92. return directPut(PROPERTY_KEY_PREFIX + key + PROPERTY_KEY_SUFFIX, value);
  93. }
  94. /**
  95. * <b>本方法被禁用。</b>由于本类的关键字有特殊的要求,因此屏蔽了父类中的此方法的使用。可以使用本类的另外一个重载的方法。
  96. * @param t 映射
  97. */
  98. public void putAll(Map t) {
  99. throw new UnsupportedOperationException("This method have been forbbiden by special Key define");
  100. }
  101. /**
  102. * 将另外一个TemplatePropertyMap中的内容合并到此映射中。
  103. * @param t 模版属性映射
  104. */
  105. public void putAll(TemplatePropertyMap t) {
  106. if (t!=null) {
  107. super.putAll(t);
  108. }
  109. }
  110. /**
  111. * 将关键字和值加入映射。
  112. * @param key 关键字
  113. * @param value 值
  114. * @return 关键字对应的上一个值,如果没有则返回null
  115. */
  116. private Object directPut(String key,Object value) {
  117. if (key.equals(value)) {
  118. throw new IllegalArgumentException(
  119. "Your converted property key must not be same as value!"+"converted key:"+key+",value:"+value);
  120. }
  121. return super.put(key, value);
  122. }
  123. /**
  124. * 判断给定的关键字是否是一个合法的属性关键字。
  125. * @param key 要判断的关键字
  126. * @return 严格符合属性关键字的定义时返回true,否则返回false。
  127. */
  128. public static boolean isPropertyKey(String key) {
  129. if (key==null||key.length()<KEY_LEAST_LENGTH) {
  130. return false;
  131. }
  132. if (key.startsWith(PROPERTY_KEY_PREFIX)&&key.endsWith(PROPERTY_KEY_SUFFIX)) {
  133. int prefixIndex, suffixIndex;
  134. prefixIndex = key.indexOf(PROPERTY_KEY_PREFIX);
  135. suffixIndex = key.lastIndexOf(PROPERTY_KEY_SUFFIX);
  136. if (key.indexOf(PROPERTY_KEY_PREFIX,prefixIndex+1)>0||key.lastIndexOf(PROPERTY_KEY_SUFFIX,suffixIndex-1)>0) {
  137. return false;
  138. }
  139. String k = key.substring(prefixIndex + 2, suffixIndex);
  140. if (Utility.isWholeUppercase(k)) {
  141. return true;
  142. }
  143. else {
  144. return false;
  145. }
  146. }
  147. return false;
  148. }
  149. /**
  150. * 判断指定的字符串中是否包含符合规则的属性关键字。
  151. * @param source 字符串
  152. * @return 包含至少一个符合属性关键字要求的值时返回true,否则返回false
  153. */
  154. public static boolean containPropertyKey(String source) {
  155. if (source == null || source.length() < KEY_LEAST_LENGTH) {
  156. return false;
  157. }
  158. int prefixIndex, suffixIndex;
  159. prefixIndex = source.indexOf(PROPERTY_KEY_PREFIX);
  160. while (prefixIndex >= 0) {
  161. suffixIndex = source.indexOf(PROPERTY_KEY_SUFFIX, prefixIndex + 1);
  162. if (suffixIndex < 0) {
  163. prefixIndex = source.indexOf(PROPERTY_KEY_PREFIX, prefixIndex + 1);
  164. continue;
  165. }
  166. String key = source.substring(prefixIndex, suffixIndex + 2);
  167. if (!isPropertyKey(key)) {
  168. prefixIndex = source.indexOf(PROPERTY_KEY_PREFIX, prefixIndex + 1);
  169. continue;
  170. }
  171. return true;
  172. }
  173. return false;
  174. }
  175. /**
  176. * 将字符串中的全部属性替换为映射中的内容。
  177. * @param string 原字符串
  178. * @return 替换以后的字符串
  179. */
  180. public String replaceAllProperties(String string) {
  181. if (size() == 0||!containPropertyKey(string)) {
  182. return string;
  183. }
  184. return completeMatchReplace(string);
  185. }
  186. /**
  187. * 将字符串中的全部属性替换为映射中的内容。
  188. * @param string 原字符串
  189. * @return 替换以后的字符串
  190. */
  191. private String completeMatchReplace(String string) {
  192. String result = string;
  193. Iterator keys = keySet().iterator();
  194. while (keys.hasNext()) {
  195. String key = (String) keys.next();
  196. if (result.indexOf(key) < 0) {
  197. continue;
  198. }
  199. else {
  200. result = replace(result, key);
  201. }
  202. }
  203. return result;
  204. }
  205. /**
  206. * 将字符串中包含的指定属性全部进行替换。
  207. * @param source 字符串
  208. * @param key 属性关键字
  209. * @return 替换以后的内容
  210. */
  211. public String replace(String source, String key) {
  212. return repalce(source,key,get(key).toString());
  213. }
  214. /**
  215. * 将字符串中包含的指定属性全部进行替换,属性对应的是一个列表,将指定索引的值进行替换。
  216. * @param source 字符串
  217. * @param key 属性关键字
  218. * @param arrayIndex 列表下标
  219. * @return 替换以后的内容
  220. */
  221. public String replaceByList(String source, String key, int arrayIndex) {
  222. return repalce(source,key,( (List) get(key)).get(arrayIndex).toString());
  223. }
  224. /**
  225. * 将字符串中包含的指定属性全部以指定的内容进行替换。
  226. * @param source 字符串
  227. * @param key 关键字
  228. * @param replacement 替换内容
  229. * @return 替换以后的内容
  230. */
  231. private String repalce(String source, String key,String replacement) {
  232. String result = source;
  233. int index = result.indexOf(key);
  234. while (index >= 0) {
  235. result = result.substring(0, index) + replacement +
  236. result.substring(index + key.length());
  237. index = result.indexOf(key,index+replacement.length());
  238. }
  239. return result;
  240. }
  241. }