1 2 3 4 5 6 7 8 9 10 11 12 |
public interface FormatProvider { /** * 把指定的值进行处理后返回 * * @param string * 要进行格式化的值 * @return 格式化好的值 * @throws FormatException */ String format(Context context, String string) throws FormatException; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
/** * 模式匹配处理接口 * * @author luoguo * */ public interface PatternDefine { /** * 返回正则匹配 * * @return */ Pattern getPattern(); /** * 设置前缀 * * @param prefixPatternString */ void setPrefixPatternString(String prefixPatternString); /** * 设置后缀 * * @param postfixPatternString */ void setPostfixPatternString(String postfixPatternString); /** * 设置正则表达式中间部分 * * @param patternString */ void setPatternString(String patternString); /** * 返回正文部分 * * @param string * @return */ String getPureMatchText(String string); /** * 根据正文返回完整部分 * * @param string * @return */ String getFullMatchText(String string); /** * 设置域分隔符 * * @return */ void setSplitChar(char splitChar); /** * 返回分隔符 * * @return */ char getSplitChar(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/** * 格式化的接口 * * @author luoguo * */ public interface Formater extends FormatProvider { /** * 设置正则表达式,如果不想用默认正则表达式,可以通过此方法自行定义 * * @param patternHandle */ void setPatternHandle(PatternDefine patternHandle); /** * 设置格式化提供者 * * @param formatProviders * Key为匹配范围符 */ void setFormatProviders(Map<String, FormatProvider> formatProviders); /** * 添加格式化提供者 * @param prefix 前缀 * @param formatProvider */ void addFormatProvider(String prefix, FormatProvider formatProvider); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
public class DefaultPatternDefine implements PatternDefine { private static final String DEFAULT_PATTERN_STRING = "([$]+[{]+[a-zA-Z0-9[.[_[:[/[#]]]]]]+[}])"; private static final String DEFAULT_POSTFIX_PATTERN_STRING = "}"; private static final String DEFAULT_PREFIX_PATTERN_STRING = "${"; private static final char DEFAULT_SPLIT_CHAR = ':'; private String prefixPatternString = DEFAULT_PREFIX_PATTERN_STRING;// 前缀 private String postfixPatternString = DEFAULT_POSTFIX_PATTERN_STRING;// 后缀 private String patternString = DEFAULT_PATTERN_STRING;// 中间部分 private Pattern pattern; private char splitChar = DEFAULT_SPLIT_CHAR;// 域分隔符 public Pattern getPattern() { if (pattern == null) { pattern = Pattern.compile(patternString); } return pattern; } public void setPrefixPatternString(String prefixPatternString) { this.prefixPatternString = prefixPatternString; } public void setPostfixPatternString(String postfixPatternString) { this.postfixPatternString = postfixPatternString; } public void setPatternString(String patternString) { this.patternString = patternString; } public String getPureMatchText(String string) { int startPos = prefixPatternString.length(); int endPos = string.length() - postfixPatternString.length(); return string.substring(startPos, endPos); } public String getFullMatchText(String string) { return String.format("%s%s%s", prefixPatternString, string, postfixPatternString); } public void setSplitChar(char splitChar) { this.splitChar = splitChar; } public char getSplitChar() { return splitChar; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class ContextFormater implements FormatProvider { public String format(Context context, String string) throws FormatException { Object obj = context.get(string); if (obj != null) { return obj.toString(); } int index = string.indexOf('.'); if (index > 0) { String name = string.substring(0, index); obj = context.get(name); if (obj != null) { String property = string.substring(index + 1); try { return BeanUtils.getProperty(obj, property).toString(); } catch (Exception e) { throw new FormatException(e); } } } return null; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
public class FormaterImpl implements Formater { private Map<String, FormatProvider> formatProviders; private PatternDefine patternDefine = new DefaultPatternDefine(); /** * 构造函数 使用默认的配置加载器 */ public FormaterImpl() { } /** * 格式化找到的内容,其余内容不变,如果找不到内容,则原样保留 * * @throws FormatException */ public String format(Context context, String source) throws FormatException { Matcher matcher = patternDefine.getPattern().matcher(source); StringBuffer buf = new StringBuffer(); int curpos = 0; while (matcher.find()) { String replaceStr = patternDefine.getPureMatchText(matcher.group()); buf.append(source.substring(curpos, matcher.start())); curpos = matcher.end(); String str = formatSingle(context, replaceStr); if (str != null) { buf.append(str); } continue; } buf.append(source.substring(curpos)); return buf.toString(); } /** * 格式化字符串 * * @param string * String * @return String * @throws FormatException * @throws Exception */ private String formatSingle(Context context, String string) throws FormatException { String s[] = string.split(patternDefine.getSplitChar() + ""); if (s.length >= 2) { FormatProvider o = (FormatProvider) formatProviders.get(s[0]); if (o != null) { return o.format(context, s[1]); } } else { FormatProvider o = (FormatProvider) formatProviders.get(""); if (o != null) { return o.format(context, string); } } return patternDefine.getFullMatchText(string); } public void setFormatProviders(Map<String, FormatProvider> formatProviders) { this.formatProviders = formatProviders; } public void setPatternHandle(PatternDefine patternHandle) { this.patternDefine = patternHandle; } public void addFormatProvider(String prefix, FormatProvider formatProvider) { if (formatProviders == null) { formatProviders = new HashMap<String, FormatProvider>(); } formatProviders.put(prefix, formatProvider); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class ConstFormatProvider implements FormatProvider { Map<String, String> constMap = new HashMap<String, String>(); public String format(Context context, String key) { return constMap.get(key); } public Map<String, String> getConstMap() { return constMap; } public void setConstMap(Map<String, String> constMap) { this.constMap = constMap; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class DateFormatProvider implements FormatProvider { Map<String, String> constMap = new HashMap<String, String>(); public String format(Context context, String key) { return constMap.get(key); } public Map<String, String> getConstMap() { return constMap; } public void setConstMap(Map<String, String> constMap) { this.constMap = constMap; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class User { String name; int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public User() { } public User(String name, int age) { this.name = name; this.age = age; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
/** * 测试不存在任何标记情况 * * @throws FormatException */ public void testFormatNotPlaceholder() throws FormatException { assertEquals("this is test", formater.format(context, "this is test")); } /** * 测试存在标记,且有处理提供者处理的情况 * * @throws FormatException */ public void testFormatExistPlaceholderProvider() throws FormatException { Context context = new ContextImpl(); assertEquals("this is v1 test", formater.format(context, "this is ${const:1} test")); } /** * 测试存在标记,且没有处理提供者处理的情况 * * @throws FormatException */ public void testFormatExistPlaceholderNoProvider() throws FormatException { assertEquals("this is ${abc:2} test", formater.format(context, "this is ${abc:2} test")); } /** * 测试存在标记,且是bean的情况 * * @throws FormatException */ public void testFormatBean() throws FormatException { User user = new User("aa", 123); context.put("user", user); assertEquals("this is aa test 123", formater.format(context, "this is ${context:user.name} test ${context:user.age}")); } |