xiejun
2024-11-01 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a
Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/utils/PlaceholderUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,152 @@
package org.springblade.core.tool.utils;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
import java.util.stream.Stream;
/**
 * å ä½ç¬¦è§£æžå™¨
 *
 * @author meilin.huang, chill
 */
public class PlaceholderUtil {
   /**
    * é»˜è®¤å‰ç¼€å ä½ç¬¦
    */
   public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
   /**
    * é»˜è®¤åŽç¼€å ä½ç¬¦
    */
   public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
   /**
    * é»˜è®¤å•例解析器
    */
   private static final PlaceholderUtil DEFAULT_RESOLVER = new PlaceholderUtil();
   /**
    * å ä½ç¬¦å‰ç¼€
    */
   private String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;
   /**
    * å ä½ç¬¦åŽç¼€
    */
   private String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;
   private PlaceholderUtil() {
   }
   private PlaceholderUtil(String placeholderPrefix, String placeholderSuffix) {
      this.placeholderPrefix = placeholderPrefix;
      this.placeholderSuffix = placeholderSuffix;
   }
   /**
    * èŽ·å–é»˜è®¤çš„å ä½ç¬¦è§£æžå™¨ï¼Œå³å ä½ç¬¦å‰ç¼€ä¸º"${", åŽç¼€ä¸º"}"
    *
    * @return PlaceholderUtil
    */
   public static PlaceholderUtil getDefaultResolver() {
      return DEFAULT_RESOLVER;
   }
   public static PlaceholderUtil getResolver(String placeholderPrefix, String placeholderSuffix) {
      return new PlaceholderUtil(placeholderPrefix, placeholderSuffix);
   }
   /**
    * è§£æžå¸¦æœ‰æŒ‡å®šå ä½ç¬¦çš„æ¨¡æ¿å­—符串,默认占位符为前缀:${  åŽç¼€ï¼š}<br/><br/>
    * å¦‚:template = category:${}:product:${}<br/>
    * values = {"1", "2"}<br/>
    * è¿”回 category:1:product:2<br/>
    *
    * @param content è¦è§£æžçš„带有占位符的模板字符串
    * @param values  æŒ‰ç…§æ¨¡æ¿å ä½ç¬¦ç´¢å¼•位置设置对应的值
    * @return {String}
    */
   public String resolve(String content, String... values) {
      int start = content.indexOf(this.placeholderPrefix);
      if (start == -1) {
         return content;
      }
      //值索引
      int valueIndex = 0;
      StringBuilder result = new StringBuilder(content);
      while (start != -1) {
         int end = result.indexOf(this.placeholderSuffix);
         String replaceContent = values[valueIndex++];
         result.replace(start, end + this.placeholderSuffix.length(), replaceContent);
         start = result.indexOf(this.placeholderPrefix, start + replaceContent.length());
      }
      return result.toString();
   }
   /**
    * è§£æžå¸¦æœ‰æŒ‡å®šå ä½ç¬¦çš„æ¨¡æ¿å­—符串,默认占位符为前缀:${  åŽç¼€ï¼š}<br/><br/>
    * å¦‚:template = category:${}:product:${}<br/>
    * values = {"1", "2"}<br/>
    * è¿”回 category:1:product:2<br/>
    *
    * @param content è¦è§£æžçš„带有占位符的模板字符串
    * @param values  æŒ‰ç…§æ¨¡æ¿å ä½ç¬¦ç´¢å¼•位置设置对应的值
    * @return {String}
    */
   public String resolve(String content, Object[] values) {
      return resolve(content, Stream.of(values).map(String::valueOf).toArray(String[]::new));
   }
   /**
    * æ ¹æ®æ›¿æ¢è§„则来替换指定模板中的占位符值
    *
    * @param content è¦è§£æžçš„字符串
    * @param rule    è§£æžè§„则回调
    * @return {String}
    */
   public String resolveByRule(String content, Function<String, String> rule) {
      int start = content.indexOf(this.placeholderPrefix);
      if (start == -1) {
         return content;
      }
      StringBuilder result = new StringBuilder(content);
      while (start != -1) {
         int end = result.indexOf(this.placeholderSuffix, start + 1);
         //获取占位符属性值,如${id}, å³èŽ·å–id
         String placeholder = result.substring(start + this.placeholderPrefix.length(), end);
         //替换整个占位符内容,即将${id}值替换为替换规则回调中的内容
         String replaceContent = placeholder.trim().isEmpty() ? "" : rule.apply(placeholder);
         result.replace(start, end + this.placeholderSuffix.length(), replaceContent);
         start = result.indexOf(this.placeholderPrefix, start + replaceContent.length());
      }
      return result.toString();
   }
   /**
    * æ›¿æ¢æ¨¡æ¿ä¸­å ä½ç¬¦å†…容,占位符的内容即为map key对应的值,key为占位符中的内容。<br/><br/>
    * å¦‚:content = product:${id}:detail:${did}<br/>
    * valueMap = id -> 1; pid -> 2<br/>
    * ç»è¿‡è§£æžè¿”回 product:1:detail:2<br/>
    *
    * @param content  æ¨¡æ¿å†…容
    * @param valueMap å€¼æ˜ å°„
    * @return æ›¿æ¢å®ŒæˆåŽçš„字符串
    */
   public String resolveByMap(String content, final Map<String, Object> valueMap) {
      return resolveByRule(content, placeholderValue -> String.valueOf(valueMap.get(placeholderValue)));
   }
   /**
    * æ ¹æ®properties文件替换占位符内容
    *
    * @param content    æ¨¡æ¿å†…容
    * @param properties é…ç½®
    * @return {String}
    */
   public String resolveByProperties(String content, final Properties properties) {
      return resolveByRule(content, properties::getProperty);
   }
}