Last active
June 8, 2017 02:17
-
-
Save lzxz1234/3984341 to your computer and use it in GitHub Desktop.
模版解析进行String字符串组装
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class StringTemplate { | |
private List<Element> list = new ArrayList<Element>(); | |
private StringTemplate(List<Element> list) { | |
this.list = list; | |
} | |
/** | |
* @param src 例:尊敬的${who}用户,您该月话费为${amount}元,谢谢${2}!! | |
* @return 解析生成的模版,调用 <code>replace</code> 方法即可生成结果 | |
*/ | |
public static StringTemplate compile(String src) { | |
List<Element> list = new ArrayList<Element>(); | |
final char[] cs = src.toCharArray(); | |
int index1 = 0, index2 = 0; | |
while(true) { | |
index2 = next(cs, index1, '$'); | |
if(index2 != -1 && index2 < cs.length - 1) { | |
if(cs[index2 + 1] == '{') { | |
list.add(new AppendElement(cs, index1, index2 - index1)); | |
index1 = index2 + 2; | |
index2 = next(cs, index1, '}'); | |
list.add(new ReplaceElement(new String(cs, index1, index2 - index1))); | |
index1 = index2 + 1; | |
} else { | |
list.add(new AppendElement(cs, index1, index2 - index1 + 1)); | |
index1 = index2 + 1; | |
} | |
} else { | |
break; | |
} | |
} | |
list.add(new AppendElement(cs, index1, cs.length - index1)); | |
return new StringTemplate(list); | |
} | |
/** | |
* @param replacements | |
* @return 根据模版生成字符串,变量均按replacements中同key值替换 | |
*/ | |
public String replace(ReplaceHolder replacements) { | |
StringBuilder sb = new StringBuilder(); | |
for(Element ele : list) { | |
ele.append(sb, replacements); | |
} | |
return sb.toString(); | |
} | |
public String replace(final Map<String, Object> map) { | |
return this.replace(new ReplaceHolder() { | |
@Override | |
public String get(String key) { | |
Object result = map.get(key); | |
if(result != null) { | |
if(result.getClass().isArray()) | |
return ArrayUtils.toString(result); | |
return result.toString(); | |
} | |
String[] keyPath = key.split("\\."); | |
result = map.get(keyPath[0]); | |
for(int i = 1; i < keyPath.length; i ++) | |
try { | |
if(result == null) return ""; | |
result = MethodUtils.getGetter(result.getClass(), keyPath[i]).invoke(result); | |
} catch (Exception e) { | |
throw new RuntimeException("路径错误" + key, e); | |
} | |
return result == null ? "" : result.toString(); | |
} | |
}); | |
} | |
private static int next(char[] cs, int begin, char dest) { | |
for(int i = begin; i < cs.length; i ++) { | |
if(cs[i] == dest) { | |
return i; | |
} | |
} | |
return -1; | |
} | |
private static abstract class Element { | |
abstract void append(StringBuilder sb, ReplaceHolder map); | |
} | |
private static class AppendElement extends Element { | |
private char[] cs; | |
private int index; | |
private int length; | |
AppendElement(char[] cs, int index, int length) { | |
this.cs = cs; | |
this.index = index; | |
this.length = length; | |
} | |
@Override | |
void append(StringBuilder sb, ReplaceHolder map) { | |
sb.append(cs, index, length); | |
} | |
} | |
private static class ReplaceElement extends Element { | |
private String key; | |
ReplaceElement(String key) { | |
this.key = key; | |
} | |
@Override | |
void append(StringBuilder sb, ReplaceHolder map) { | |
String replaceStr = map.get(key); | |
sb.append(replaceStr == null ? "" : replaceStr); | |
} | |
} | |
public static interface ReplaceHolder { | |
public String get(String key); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment