/* ================================================================== * Created [2009-4-27 下午11:32:55] by Jon.King * ================================================================== * TSS * ================================================================== * mailTo:jinpujun@hotmail.com * Copyright (c) Jon.King, 2009-2012 * ================================================================== */ package com.jinhe.tss.core.util; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * <p> * 宏代码编译器 * </p> */ public class MacrocodeCompiler { /** * 宏代码标志 */ public static char MACROCODE_SYMBOL = '$'; /** * 变量标志 */ public static char VARIABLE_SYMBOL = '#'; /** * 宏代码名称起始标记:必须跟在宏代码、变量标志后有效 */ public static char NAME_START_SYMBOL = '{'; /** * 宏代码名称结束标记:起始标记后第一个此符号为配对的结束标记 */ public static char NAME_END_SYMBOL = '}'; /** * 空格字符串,用于变量初始化 */ protected static char NULL = ' '; /** * <p> * 将包含宏代码、变量等的脚本字符串解析成字符串片段后放到segment列表中<br> * 以宏代码:${}、#{}分开,风别存放到List对象中<br> * 如下:<br> * 普通代码<br> * ${XXXX}<br> * 普通代码<br> * #{YYYY}<br> * 普通代码 * </p> * * @param code * String 包含宏代码、变量等的字符串 比如 123${xxx}456 * @return List * 代码片段列表 List{123, ${xxx}, 456} */ private static List<String> compile(String code) { if (code == null) { return null; } List<String> segment = new ArrayList<String>(); char curChar = NULL; char preChar = NULL; int startIndex = 0; int endIndex = 0; boolean isMacro = false; for (int curIndex = 0;curIndex < code.length(); curIndex++) { preChar = curChar; curChar = code.charAt(curIndex); if (isMacro) { // 检测宏代码结束标记 curChar = '}' if ( isEndSymbol(curChar) ) { isMacro = false; endIndex = curIndex + 1; // 连 “}” 一块截 if (endIndex > startIndex) { segment.add(code.substring(startIndex, endIndex)); // 将宏代码、变量截取出来 startIndex = endIndex; } } } else { // 检测宏代码起始标记 preChar + curChar = "&{" or "#{" if (isStartSymbol(curChar) && isMacroStartTag(preChar) ) { isMacro = true; endIndex = curIndex - 1; // 截取时回退两位,剔除 “${” 或 “#{” if (endIndex > startIndex) { segment.add(code.substring(startIndex, endIndex)); // 将非宏代码、变量截取出来 startIndex = endIndex; } } } } if (startIndex < code.length()) { segment.add(code.substring(startIndex, code.length())); } return segment; } /** * <p> * 将包含宏代码、变量代码的字符串解释其代码含义后,返回执行结果字符串 如下:<br> * ${portlet}:PortletNode对象<br> * #{title}:Portlet名称 * </p> * * @param code * String 包含宏代码、变量等的字符串 * @param macrocodes * Map 宏代码、值对应表 * @return String 宏代码、变量执行后的字符串 */ public static String run(String code, Map<String, ? extends Object> macrocodes) { List<String> segment = compile(code); if (segment == null) return ""; StringBuffer sb = new StringBuffer(); for(String item : segment) { if (item == null) continue; if (item.length() > 3 && isMacroStartTag(item.charAt(0)) && isStartSymbol(item.charAt(1)) && isEndSymbol(item.charAt(item.length() - 1)) && macrocodes != null) { Object macro = macrocodes.get(item); if (macro != null) { sb.append(macro); } } else { sb.append(item); } } return sb.toString(); } /** 是否宏代码标记 '$' or '#' */ private static boolean isMacroStartTag(char c){ return c == MACROCODE_SYMBOL || c == VARIABLE_SYMBOL; } /** 是否宏定义开始标记 '{' */ private static boolean isStartSymbol(char c){ return c == NAME_START_SYMBOL ; } /** 是否宏定义结束标记 '}' */ private static boolean isEndSymbol(char c){ return c == NAME_END_SYMBOL; } /** * 生成 ${key} * @param key * @return ${key} */ public static String createMacroCode(String key){ return MACROCODE_SYMBOL + NAME_START_SYMBOL + key + NAME_END_SYMBOL; } /** * 生成 #{key} * @param key * @return #{key} */ public static String createVariable(String key){ return VARIABLE_SYMBOL + NAME_START_SYMBOL + key + NAME_END_SYMBOL; } }