package message.utils; import org.apache.commons.lang.exception.NestableRuntimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Assert; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 处理字符串中的占位符. * * @author sunhao(sunhao.java@gmail.com) * @version V1.0, 14-9-3 下午10:37 */ public class PropertyPlaceholderHelper { private static final Logger logger = LoggerFactory.getLogger(PropertyPlaceholderHelper.class); /** * 占位符前缀 */ private static final String PLACEHOLDER_PREFIX = "${"; /** * 占位符后缀 */ private static final String PLACEHOLDER_SUFFIX = "}"; /** * 左括号 */ private final static String LEFT_BRACE = "{"; /** * 右括号 */ private final static String RIGTH_BRACE = "}"; /** * 私有化构造器,外部不可以实例化 */ private PropertyPlaceholderHelper() { } /** * 替换text中的占位符<br/> * eg:<br/> * 1.text值为:<br/> * ${hi},我是${user.name},英文名是${user.eglish.name}!<br/><br/> * 2.values值为:<br/> * <code> * Map<String, String> params = new HashMap<String, String>();<br/> * params.put("user.name", "孙昊");<br/> * params.put("user.eglish.name", "Hello World");<br/> * params.put("hi", "你好");<br/><br/> * </code> * 那么结果将是:<br/> * 你好,我是孙昊,英文名是Hello World! * * @param text 要替换的文本(包含${...}) * @param placeholderAsDefaultValue 如果一个占位符找不到值,是否使用占位符作为值 * @param values 值的map集合 * @return */ public static String replacePlaceholder(String text, boolean placeholderAsDefaultValue, Map<String, String> values) { Assert.hasText(text, "source text can't be null!"); if (!needReplace(text)) { return text; } Assert.notEmpty(values, "values can't be null!"); //1.根据前缀分组 String[] groups = StringUtils.split(text, PLACEHOLDER_PREFIX); //2.遍历分组,如果有后缀,则取出 int length = groups.length; //占位符在第一位 boolean placeholderInFirst = StringUtils.startsWith(text, PLACEHOLDER_PREFIX); Assert.isTrue(placeholderInFirst || length > 1, "given text has no placeholder!"); List<String> placeholders = new ArrayList<String>(); int start = placeholderInFirst ? 0 : 1; for (int i = start; i < length; i++) { if (i < length) { String t = groups[i]; //3.将所有的占位符取出 if (StringUtils.contains(t, PLACEHOLDER_SUFFIX)) { placeholders.add(StringUtils.substring(t, 0, StringUtils.indexOf(t, PLACEHOLDER_SUFFIX))); } } } //4.进行替换 String result = text; for (String ph : placeholders) { String placeholder = PLACEHOLDER_PREFIX + ph + PLACEHOLDER_SUFFIX; String value = values.get(ph); if (StringUtils.isEmpty(value) && !placeholderAsDefaultValue) { throw new NestableRuntimeException("process text '{" + text + "}' error! placeholder is '{" + placeholder + "}'!"); } value = (StringUtils.isNotEmpty(value) ? value : ph); //5.替换text result = StringUtils.replace(result, placeholder, value); } return result; } /** * 判断是否需要进行替换 * * @param text 待检查文字 * @return */ private static boolean needReplace(String text) { return StringUtils.hasExcerpt(text, "\\$\\{.*?\\}") > 0; } /** * 格式化字符串,替换{0}{1}...,如果不成功,则默认返回原字符串 * * @param formatString 需要格式化的字符串 * @param args 参数 * @return */ public static String replacePlaceholder(String formatString, Object... args){ String result = replacePlaceholder(formatString, StringUtils.EMPTY, args); return StringUtils.isEmpty(result) ? formatString : result; } /** * 格式化字符串,替换{0}{1}...,如果不成功,则返回defaultVlaue * * @param formatString 需要格式化的字符串 * @param defaultValue 如果不成功,返回的字符串 * @param args 参数 * @return */ public static String replacePlaceholder(String formatString, String defaultValue, Object... args){ if(StringUtils.isEmpty(formatString) || formatString.indexOf(LEFT_BRACE) == -1 || formatString.indexOf(RIGTH_BRACE) == -1 || args == null || args.length < 1){ logger.error("the formatString, args, defaultValue is required! please check given paramters are all right!"); return StringUtils.EMPTY; } /** * 第一个'{'的位置 */ int firstLeftBrace = formatString.indexOf(LEFT_BRACE); /** * 最后一个'}'的位置 */ int lastRightBrace = formatString.lastIndexOf(RIGTH_BRACE); /** * 第一个'{'后面的那个数字 */ String first = formatString.substring(firstLeftBrace + 1, firstLeftBrace + 2); /** * 最后一个'}'后面的那个数字 */ String last = formatString.substring(lastRightBrace - 1, lastRightBrace); /** * 第一个序号和最后一个序号 */ int firstSequence = Integer.parseInt(first); int lastSequence = Integer.parseInt(last); /** * {0}{1}...的个数与给定的值个数不一致,或者{0}{1}...不是按照这样递增的,那么返回错误, * 否则进行替换 */ if(!((lastSequence - firstSequence + 1) < 0 || (lastSequence - firstSequence + 1) != args.length)){ /** * 替换规则: * 给定值的第一个值替换{0},以此类推 */ for(int j = 0; j < args.length; j++){ formatString = formatString.replace("{" + j + "}", args[j] + ""); } } else { if(logger.isWarnEnabled()){ logger.warn("foramtString has '{}' barces, but you given '{}' paramters!", lastSequence - firstSequence + 1, args.length); } return defaultValue; } if(logger.isDebugEnabled()){ logger.debug("format successed! the result is '{}'", formatString); } return formatString; } }