From 0ad2b9e25d20b3c1ed8dcd37dec9ed490a974356 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 12 Apr 2024 19:09:32 +0800 Subject: [PATCH] fix format --- .../template/NamedPlaceholderStrTemplate.java | 1078 +++++++-------- .../hutool/core/text/StrTemplateTest.java | 1166 ++++++++--------- 2 files changed, 1122 insertions(+), 1122 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/NamedPlaceholderStrTemplate.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/NamedPlaceholderStrTemplate.java index 75d780c10..102246eaa 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/NamedPlaceholderStrTemplate.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/NamedPlaceholderStrTemplate.java @@ -39,601 +39,601 @@ import java.util.function.*; * @since 6.0.0 */ public class NamedPlaceholderStrTemplate extends StrTemplate { - /** - * 默认前缀 - */ - public static final String DEFAULT_PREFIX = StrPool.DELIM_START; - /** - * 默认后缀 - */ - public static final String DEFAULT_SUFFIX = StrPool.DELIM_END; + /** + * 默认前缀 + */ + public static final String DEFAULT_PREFIX = StrPool.DELIM_START; + /** + * 默认后缀 + */ + public static final String DEFAULT_SUFFIX = StrPool.DELIM_END; - /** - * 占位符前缀,默认为: {@link #DEFAULT_PREFIX} - */ - protected String prefix; - /** - * 占位符后缀,默认为: {@link #DEFAULT_SUFFIX} - */ - protected String suffix; - /** - * 在 下标占位符中,最大的下标值 - */ - protected int indexedSegmentMaxIdx = 0; + /** + * 占位符前缀,默认为: {@link #DEFAULT_PREFIX} + */ + protected String prefix; + /** + * 占位符后缀,默认为: {@link #DEFAULT_SUFFIX} + */ + protected String suffix; + /** + * 在 下标占位符中,最大的下标值 + */ + protected int indexedSegmentMaxIdx = 0; - protected NamedPlaceholderStrTemplate(final String template, final int features, final String prefix, - final String suffix, final char escape, final String defaultValue, - final UnaryOperator defaultValueHandler) { - super(template, escape, defaultValue, defaultValueHandler, features); + protected NamedPlaceholderStrTemplate(final String template, final int features, final String prefix, + final String suffix, final char escape, final String defaultValue, + final UnaryOperator defaultValueHandler) { + super(template, escape, defaultValue, defaultValueHandler, features); - Assert.notEmpty(prefix); - Assert.notEmpty(suffix); - this.prefix = prefix; - this.suffix = suffix; + Assert.notEmpty(prefix); + Assert.notEmpty(suffix); + this.prefix = prefix; + this.suffix = suffix; - // 一些初始化后续操作 - afterInit(); + // 一些初始化后续操作 + afterInit(); - // 记录 下标占位符 最大的 下标值 - if (!placeholderSegments.isEmpty()) { - for (final AbstractPlaceholderSegment segment : placeholderSegments) { - if (segment instanceof IndexedPlaceholderSegment) { - this.indexedSegmentMaxIdx = Math.max(this.indexedSegmentMaxIdx, ((IndexedPlaceholderSegment) segment).getIndex()); - } - } - } - } + // 记录 下标占位符 最大的 下标值 + if (!placeholderSegments.isEmpty()) { + for (final AbstractPlaceholderSegment segment : placeholderSegments) { + if (segment instanceof IndexedPlaceholderSegment) { + this.indexedSegmentMaxIdx = Math.max(this.indexedSegmentMaxIdx, ((IndexedPlaceholderSegment) segment).getIndex()); + } + } + } + } - @Override - protected List parseSegments(final String template) { - // 寻找第一个前缀符号 - int openCursor = template.indexOf(prefix); - // 没有任何占位符 - if (openCursor == -1) { - return Collections.singletonList(new LiteralSegment(template)); - } + @Override + protected List parseSegments(final String template) { + // 寻找第一个前缀符号 + int openCursor = template.indexOf(prefix); + // 没有任何占位符 + if (openCursor == -1) { + return Collections.singletonList(new LiteralSegment(template)); + } - final int openLength = prefix.length(); - final int closeLength = suffix.length(); - final List segments = new ArrayList<>(); - int closeCursor = 0; - // 开始匹配 - final char[] src = template.toCharArray(); - final StringBuilder expression = new StringBuilder(16); - boolean hasDoubleEscape = false; - // 占位变量名称 - String variableName; - // 完整的占位符 - String wholePlaceholder; - // 上一个解析的segment是否是固定文本,如果是,则需要和当前新的文本部分合并 - boolean isLastLiteralSegment = false; - while (openCursor > -1) { - // 开始符号是否被转义,若是则跳过,并寻找下一个开始符号 - if (openCursor > 0 && src[openCursor - 1] == escape) { - // 存在 双转义符,转义符之前还有一个转义符,形如:"\\{",占位符依旧有效 - if (openCursor > 1 && src[openCursor - 2] == escape) { - hasDoubleEscape = true; - } else { - // 开始符号被转义,跳过,寻找下一个开始符号 - addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor, openCursor - 1) + prefix); - isLastLiteralSegment = true; - closeCursor = openCursor + openLength; - openCursor = template.indexOf(prefix, closeCursor); - continue; - } - } + final int openLength = prefix.length(); + final int closeLength = suffix.length(); + final List segments = new ArrayList<>(); + int closeCursor = 0; + // 开始匹配 + final char[] src = template.toCharArray(); + final StringBuilder expression = new StringBuilder(16); + boolean hasDoubleEscape = false; + // 占位变量名称 + String variableName; + // 完整的占位符 + String wholePlaceholder; + // 上一个解析的segment是否是固定文本,如果是,则需要和当前新的文本部分合并 + boolean isLastLiteralSegment = false; + while (openCursor > -1) { + // 开始符号是否被转义,若是则跳过,并寻找下一个开始符号 + if (openCursor > 0 && src[openCursor - 1] == escape) { + // 存在 双转义符,转义符之前还有一个转义符,形如:"\\{",占位符依旧有效 + if (openCursor > 1 && src[openCursor - 2] == escape) { + hasDoubleEscape = true; + } else { + // 开始符号被转义,跳过,寻找下一个开始符号 + addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor, openCursor - 1) + prefix); + isLastLiteralSegment = true; + closeCursor = openCursor + openLength; + openCursor = template.indexOf(prefix, closeCursor); + continue; + } + } - // 没有双转义符 - if (!hasDoubleEscape) { - if (closeCursor < openCursor) { - // 完整记录当前占位符的开始符号与上一占位符的结束符号间的字符串 - addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor, openCursor)); - } - } else { - // 存在双转义符,只能保留一个转义符 - hasDoubleEscape = false; - addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor, openCursor - 1)); - } + // 没有双转义符 + if (!hasDoubleEscape) { + if (closeCursor < openCursor) { + // 完整记录当前占位符的开始符号与上一占位符的结束符号间的字符串 + addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor, openCursor)); + } + } else { + // 存在双转义符,只能保留一个转义符 + hasDoubleEscape = false; + addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor, openCursor - 1)); + } - // 重置结束游标至当前占位符的开始处 - closeCursor = openCursor + openLength; + // 重置结束游标至当前占位符的开始处 + closeCursor = openCursor + openLength; - // 寻找结束符号下标 - int end = template.indexOf(suffix, closeCursor); - while (end > -1) { - // 结束符号被转义,寻找下一个结束符号 - if (end > closeCursor && src[end - 1] == escape) { - // 双转义符,保留一个转义符,并且找到了结束符 - if (end > 1 && src[end - 2] == escape) { - expression.append(src, closeCursor, end - closeCursor - 1); - break; - } else { - expression.append(src, closeCursor, end - closeCursor - 1).append(suffix); - closeCursor = end + closeLength; - end = template.indexOf(suffix, closeCursor); - } - } - // 找到结束符号 - else { - expression.append(src, closeCursor, end - closeCursor); - break; - } - } + // 寻找结束符号下标 + int end = template.indexOf(suffix, closeCursor); + while (end > -1) { + // 结束符号被转义,寻找下一个结束符号 + if (end > closeCursor && src[end - 1] == escape) { + // 双转义符,保留一个转义符,并且找到了结束符 + if (end > 1 && src[end - 2] == escape) { + expression.append(src, closeCursor, end - closeCursor - 1); + break; + } else { + expression.append(src, closeCursor, end - closeCursor - 1).append(suffix); + closeCursor = end + closeLength; + end = template.indexOf(suffix, closeCursor); + } + } + // 找到结束符号 + else { + expression.append(src, closeCursor, end - closeCursor); + break; + } + } - // 未能找到结束符号,说明匹配异常 - if (end == -1) { - throw new HutoolException("\"{}\" 中字符下标 {} 处的开始符没有找到对应的结束符", template, openCursor); - } - // 找到结束符号,开始到结束符号 之间的字符串 就是占位变量 - else { - // 占位变量名称 - variableName = expression.toString(); - expression.setLength(0); - // 完整的占位符 - wholePlaceholder = expression.append(prefix).append(variableName).append(suffix).toString(); - expression.setLength(0); - // 如果是整数,则当作下标处理 - if (NumberUtil.isInteger(variableName)) { - segments.add(new IndexedPlaceholderSegment(variableName, wholePlaceholder)); - } else { - // 当作变量名称处理 - segments.add(new NamedPlaceholderSegment(variableName, wholePlaceholder)); - } - isLastLiteralSegment = false; - // 完成当前占位符的处理匹配,寻找下一个 - closeCursor = end + closeLength; - } + // 未能找到结束符号,说明匹配异常 + if (end == -1) { + throw new HutoolException("\"{}\" 中字符下标 {} 处的开始符没有找到对应的结束符", template, openCursor); + } + // 找到结束符号,开始到结束符号 之间的字符串 就是占位变量 + else { + // 占位变量名称 + variableName = expression.toString(); + expression.setLength(0); + // 完整的占位符 + wholePlaceholder = expression.append(prefix).append(variableName).append(suffix).toString(); + expression.setLength(0); + // 如果是整数,则当作下标处理 + if (NumberUtil.isInteger(variableName)) { + segments.add(new IndexedPlaceholderSegment(variableName, wholePlaceholder)); + } else { + // 当作变量名称处理 + segments.add(new NamedPlaceholderSegment(variableName, wholePlaceholder)); + } + isLastLiteralSegment = false; + // 完成当前占位符的处理匹配,寻找下一个 + closeCursor = end + closeLength; + } - // 寻找下一个开始符号 - openCursor = template.indexOf(prefix, closeCursor); - } + // 寻找下一个开始符号 + openCursor = template.indexOf(prefix, closeCursor); + } - // 若匹配结束后仍有未处理的字符串,则直接将其拼接到表达式上 - if (closeCursor < src.length) { - addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor)); - } - return segments; - } + // 若匹配结束后仍有未处理的字符串,则直接将其拼接到表达式上 + if (closeCursor < src.length) { + addLiteralSegment(isLastLiteralSegment, segments, template.substring(closeCursor)); + } + return segments; + } - // region 格式化方法 - // ################################################## 格式化方法 ################################################## + // region 格式化方法 + // ################################################## 格式化方法 ################################################## - // region 基于顺序的格式化方法 - // ############################## 基于顺序的格式化方法 ############################## + // region 基于顺序的格式化方法 + // ############################## 基于顺序的格式化方法 ############################## - /** - * 按顺序使用 数组元素 替换 占位符 - * - * @param args 可变参数 - * @return 格式化字符串 - */ - public String formatSequence(final Object... args) { - return formatArraySequence(args); - } + /** + * 按顺序使用 数组元素 替换 占位符 + * + * @param args 可变参数 + * @return 格式化字符串 + */ + public String formatSequence(final Object... args) { + return formatArraySequence(args); + } - /** - * 按顺序使用 原始数组元素 替换 占位符 - * - * @param array 原始类型数组,例如: {@code int[]} - * @return 格式化字符串 - */ - public String formatArraySequence(final Object array) { - return formatArraySequence(ArrayUtil.wrap(array)); - } + /** + * 按顺序使用 原始数组元素 替换 占位符 + * + * @param array 原始类型数组,例如: {@code int[]} + * @return 格式化字符串 + */ + public String formatArraySequence(final Object array) { + return formatArraySequence(ArrayUtil.wrap(array)); + } - /** - * 按顺序使用 数组元素 替换 占位符 - * - * @param array 数组 - * @return 格式化字符串 - */ - public String formatArraySequence(final Object[] array) { - if (array == null) { - return getTemplate(); - } - return formatSequence(Arrays.asList(array)); - } + /** + * 按顺序使用 数组元素 替换 占位符 + * + * @param array 数组 + * @return 格式化字符串 + */ + public String formatArraySequence(final Object[] array) { + if (array == null) { + return getTemplate(); + } + return formatSequence(Arrays.asList(array)); + } - /** - * 按顺序使用 迭代器元素 替换 占位符 - * - * @param iterable iterable - * @return 格式化字符串 - */ - @Override - public String formatSequence(final Iterable iterable) { - return super.formatSequence(iterable); - } - // endregion + /** + * 按顺序使用 迭代器元素 替换 占位符 + * + * @param iterable iterable + * @return 格式化字符串 + */ + @Override + public String formatSequence(final Iterable iterable) { + return super.formatSequence(iterable); + } + // endregion - // region 基于下标的格式化方法 - // ############################## 基于下标的格式化方法 ############################## + // region 基于下标的格式化方法 + // ############################## 基于下标的格式化方法 ############################## - /** - * 按 下标 使用 数组元素 替换 占位符 - * - * @param args 可变参数 - * @return 格式化字符串 - */ - public String formatIndexed(final Object... args) { - return formatArrayIndexed(args); - } + /** + * 按 下标 使用 数组元素 替换 占位符 + * + * @param args 可变参数 + * @return 格式化字符串 + */ + public String formatIndexed(final Object... args) { + return formatArrayIndexed(args); + } - /** - * 按 下标 使用 原始数组元素 替换 占位符 - * - * @param array 原始类型数组 - * @return 格式化字符串 - */ - public String formatArrayIndexed(final Object array) { - return formatArrayIndexed(ArrayUtil.wrap(array)); - } + /** + * 按 下标 使用 原始数组元素 替换 占位符 + * + * @param array 原始类型数组 + * @return 格式化字符串 + */ + public String formatArrayIndexed(final Object array) { + return formatArrayIndexed(ArrayUtil.wrap(array)); + } - /** - * 按 下标 使用 数组元素 替换 占位符 - * - * @param array 数组 - * @return 格式化字符串 - */ - public String formatArrayIndexed(final Object[] array) { - if (array == null) { - return getTemplate(); - } - return formatIndexed(Arrays.asList(array)); - } + /** + * 按 下标 使用 数组元素 替换 占位符 + * + * @param array 数组 + * @return 格式化字符串 + */ + public String formatArrayIndexed(final Object[] array) { + if (array == null) { + return getTemplate(); + } + return formatIndexed(Arrays.asList(array)); + } - /** - * 按 下标 使用 集合元素 替换 占位符 - * - * @param collection 集合元素 - * @return 格式化字符串 - */ - public String formatIndexed(final Collection collection) { - return formatIndexed(collection, null); - } + /** + * 按 下标 使用 集合元素 替换 占位符 + * + * @param collection 集合元素 + * @return 格式化字符串 + */ + public String formatIndexed(final Collection collection) { + return formatIndexed(collection, null); + } - /** - * 按 下标 使用 集合元素 替换 占位符 - * - * @param collection 集合元素 - * @param missingIndexHandler 集合中不存在下标位置时的处理器,根据 下标 返回 代替值 - * @return 格式化字符串 - */ - public String formatIndexed(final Collection collection, final IntFunction missingIndexHandler) { - if (collection == null) { - return getTemplate(); - } + /** + * 按 下标 使用 集合元素 替换 占位符 + * + * @param collection 集合元素 + * @param missingIndexHandler 集合中不存在下标位置时的处理器,根据 下标 返回 代替值 + * @return 格式化字符串 + */ + public String formatIndexed(final Collection collection, final IntFunction missingIndexHandler) { + if (collection == null) { + return getTemplate(); + } - final int size = collection.size(); - final boolean isList = collection instanceof List; - return formatBySegment(segment -> { - int index = ((IndexedPlaceholderSegment) segment).getIndex(); - if (index < 0) { - index += size; - } - if (index >= 0 && index < size) { - if (isList) { - return ((List) collection).get(index); - } - return CollUtil.get(collection, index); - } - // 下标越界,代表 占位符 没有对应值,尝试获取代替值 - else if (missingIndexHandler != null) { - return missingIndexHandler.apply(index); - } else { - return formatMissingKey(segment); - } - }); - } - // endregion + final int size = collection.size(); + final boolean isList = collection instanceof List; + return formatBySegment(segment -> { + int index = ((IndexedPlaceholderSegment) segment).getIndex(); + if (index < 0) { + index += size; + } + if (index >= 0 && index < size) { + if (isList) { + return ((List) collection).get(index); + } + return CollUtil.get(collection, index); + } + // 下标越界,代表 占位符 没有对应值,尝试获取代替值 + else if (missingIndexHandler != null) { + return missingIndexHandler.apply(index); + } else { + return formatMissingKey(segment); + } + }); + } + // endregion - // region 基于键值的格式化方法 - // ############################## 基于键值的格式化方法 ############################## + // region 基于键值的格式化方法 + // ############################## 基于键值的格式化方法 ############################## - /** - * 使用 占位变量名称 从 Bean 或 Map 中查询值来 替换 占位符 - * - * @param beanOrMap Bean 或 Map 实例 - * @return 格式化字符串 - */ - @SuppressWarnings("unchecked") - public String format(final Object beanOrMap) { - if (beanOrMap == null) { - return getTemplate(); - } - if (beanOrMap instanceof Map) { - return format((Map) beanOrMap); - } else if (BeanUtil.isReadableBean(beanOrMap.getClass())) { - final BeanDesc beanDesc = BeanUtil.getBeanDesc(beanOrMap.getClass()); - return format(fieldName -> { - final Method getterMethod = beanDesc.getGetter(fieldName); - if (getterMethod == null) { - return null; - } - return LambdaUtil.buildGetter(getterMethod).apply(beanOrMap); - }); - } - return format(fieldName -> BeanUtil.getFieldValue(beanOrMap, fieldName)); - } + /** + * 使用 占位变量名称 从 Bean 或 Map 中查询值来 替换 占位符 + * + * @param beanOrMap Bean 或 Map 实例 + * @return 格式化字符串 + */ + @SuppressWarnings("unchecked") + public String format(final Object beanOrMap) { + if (beanOrMap == null) { + return getTemplate(); + } + if (beanOrMap instanceof Map) { + return format((Map) beanOrMap); + } else if (BeanUtil.isReadableBean(beanOrMap.getClass())) { + final BeanDesc beanDesc = BeanUtil.getBeanDesc(beanOrMap.getClass()); + return format(fieldName -> { + final Method getterMethod = beanDesc.getGetter(fieldName); + if (getterMethod == null) { + return null; + } + return LambdaUtil.buildGetter(getterMethod).apply(beanOrMap); + }); + } + return format(fieldName -> BeanUtil.getFieldValue(beanOrMap, fieldName)); + } - /** - * 使用 占位变量名称 从 Map 中查询值来 替换 占位符 - * - * @param map map - * @return 格式化字符串 - */ - public String format(final Map map) { - if (map == null) { - return getTemplate(); - } - return format(map::get, map::containsKey); - } + /** + * 使用 占位变量名称 从 Map 中查询值来 替换 占位符 + * + * @param map map + * @return 格式化字符串 + */ + public String format(final Map map) { + if (map == null) { + return getTemplate(); + } + return format(map::get, map::containsKey); + } - /** - * 使用 占位变量名称 从 valueSupplier 中查询值来 替换 占位符 - * - * @param valueSupplier 根据 占位变量名称 返回 值 - * @return 格式化字符串 - */ - public String format(final Function valueSupplier) { - if (valueSupplier == null) { - return getTemplate(); - } - return formatBySegment(segment -> valueSupplier.apply(segment.getPlaceholder())); - } + /** + * 使用 占位变量名称 从 valueSupplier 中查询值来 替换 占位符 + * + * @param valueSupplier 根据 占位变量名称 返回 值 + * @return 格式化字符串 + */ + public String format(final Function valueSupplier) { + if (valueSupplier == null) { + return getTemplate(); + } + return formatBySegment(segment -> valueSupplier.apply(segment.getPlaceholder())); + } - /** - * 使用 占位变量名称 从 valueSupplier 中查询值来 替换 占位符 - * - * @param valueSupplier 根据 占位变量名称 返回 值 - * @param containsKey 占位变量名称 是否存在,例如:{@code map.containsKey(key)} - * @return 格式化字符串 - */ - public String format(final Function valueSupplier, final Predicate containsKey) { - if (valueSupplier == null || containsKey == null) { - return getTemplate(); - } + /** + * 使用 占位变量名称 从 valueSupplier 中查询值来 替换 占位符 + * + * @param valueSupplier 根据 占位变量名称 返回 值 + * @param containsKey 占位变量名称 是否存在,例如:{@code map.containsKey(key)} + * @return 格式化字符串 + */ + public String format(final Function valueSupplier, final Predicate containsKey) { + if (valueSupplier == null || containsKey == null) { + return getTemplate(); + } - return formatBySegment(segment -> { - final String placeholder = segment.getPlaceholder(); - if (containsKey.test(placeholder)) { - return valueSupplier.apply(placeholder); - } - return formatMissingKey(segment); - }); - } - // endregion - // endregion + return formatBySegment(segment -> { + final String placeholder = segment.getPlaceholder(); + if (containsKey.test(placeholder)) { + return valueSupplier.apply(placeholder); + } + return formatMissingKey(segment); + }); + } + // endregion + // endregion - // region 解析方法 - // ################################################## 解析方法 ################################################## + // region 解析方法 + // ################################################## 解析方法 ################################################## - // region 基于顺序的解析方法 - // ############################## 基于顺序的解析方法 ############################## + // region 基于顺序的解析方法 + // ############################## 基于顺序的解析方法 ############################## - /** - * 将 占位符位置的值 按顺序解析为 字符串数组 - * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @return 字符串数组 - */ - public String[] matchesSequenceToArray(final String str) { - return matchesSequence(str).toArray(new String[0]); - } + /** + * 将 占位符位置的值 按顺序解析为 字符串数组 + * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @return 字符串数组 + */ + public String[] matchesSequenceToArray(final String str) { + return matchesSequence(str).toArray(new String[0]); + } - /** - * 将 占位符位置的值 按顺序解析为 字符串列表 - * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @return 字符串列表 - */ - @Override - public List matchesSequence(final String str) { - return super.matchesSequence(str); - } - // endregion + /** + * 将 占位符位置的值 按顺序解析为 字符串列表 + * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @return 字符串列表 + */ + @Override + public List matchesSequence(final String str) { + return super.matchesSequence(str); + } + // endregion - // region 基于下标的解析方法 - // ############################## 基于下标的解析方法 ############################## + // region 基于下标的解析方法 + // ############################## 基于下标的解析方法 ############################## - /** - * 将 占位符位置的值 按 占位符下标值 解析为 字符串数组 - * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @return 字符串数组 - * @see #matchesIndexed(String, IntFunction) - */ - public String[] matchesIndexedToArray(final String str) { - return matchesIndexed(str, null).toArray(new String[0]); - } + /** + * 将 占位符位置的值 按 占位符下标值 解析为 字符串数组 + * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @return 字符串数组 + * @see #matchesIndexed(String, IntFunction) + */ + public String[] matchesIndexedToArray(final String str) { + return matchesIndexed(str, null).toArray(new String[0]); + } - /** - * 将 占位符位置的值 按 占位符下标值 解析为 字符串数组 - * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @param missingIndexHandler 根据 下标 返回 默认值,该参数可以为 {@code null},仅在 {@link Feature#MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE} 策略时生效 - * @return 字符串数组 - * @see #matchesIndexed(String, IntFunction) - */ - public String[] matchesIndexedToArray(final String str, final IntFunction missingIndexHandler) { - return matchesIndexed(str, missingIndexHandler).toArray(new String[0]); - } + /** + * 将 占位符位置的值 按 占位符下标值 解析为 字符串数组 + * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @param missingIndexHandler 根据 下标 返回 默认值,该参数可以为 {@code null},仅在 {@link Feature#MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE} 策略时生效 + * @return 字符串数组 + * @see #matchesIndexed(String, IntFunction) + */ + public String[] matchesIndexedToArray(final String str, final IntFunction missingIndexHandler) { + return matchesIndexed(str, missingIndexHandler).toArray(new String[0]); + } - /** - * 将 占位符位置的值 按 占位符下标值 解析为 字符串列表 - * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @return 字符串列表 - * @see #matchesIndexed(String, IntFunction) - */ - public List matchesIndexed(final String str) { - return matchesIndexed(str, null); - } + /** + * 将 占位符位置的值 按 占位符下标值 解析为 字符串列表 + * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @return 字符串列表 + * @see #matchesIndexed(String, IntFunction) + */ + public List matchesIndexed(final String str) { + return matchesIndexed(str, null); + } - /** - * 将 占位符位置的值 按 占位符下标值 解析为 字符串列表 - * - *

例如,模板中为 {@literal "This is between {1} and {2}"},格式化结果为 {@literal "This is between 666 and 999"}, - * 由于其最大下标为 2, 则解析结果中固定有 3 个元素,解析结果为 {@code [null, "666", "999"]}

- * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @param missingIndexHandler 根据 下标 返回 默认值,该参数可以为 {@code null},仅在 {@link Feature#MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE} 策略时生效 - * @return 字符串列表 - */ - public List matchesIndexed(final String str, final IntFunction missingIndexHandler) { - if (str == null || placeholderSegments.isEmpty() || !isMatches(str)) { - return ListUtil.zero(); - } + /** + * 将 占位符位置的值 按 占位符下标值 解析为 字符串列表 + * + *

例如,模板中为 {@literal "This is between {1} and {2}"},格式化结果为 {@literal "This is between 666 and 999"}, + * 由于其最大下标为 2, 则解析结果中固定有 3 个元素,解析结果为 {@code [null, "666", "999"]}

+ * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @param missingIndexHandler 根据 下标 返回 默认值,该参数可以为 {@code null},仅在 {@link Feature#MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE} 策略时生效 + * @return 字符串列表 + */ + public List matchesIndexed(final String str, final IntFunction missingIndexHandler) { + if (str == null || placeholderSegments.isEmpty() || !isMatches(str)) { + return ListUtil.zero(); + } - final List params = new ArrayList<>(this.indexedSegmentMaxIdx + 1); - // 用null值填充所有位置 - ListUtil.setOrPadding(params, this.indexedSegmentMaxIdx, null, null); - matchesIndexed(str, params::set, missingIndexHandler); - return params; - } + final List params = new ArrayList<>(this.indexedSegmentMaxIdx + 1); + // 用null值填充所有位置 + ListUtil.setOrPadding(params, this.indexedSegmentMaxIdx, null, null); + matchesIndexed(str, params::set, missingIndexHandler); + return params; + } - /** - * 根据 下标 和 下标占位符位置的值,自行提取结果值 - * - *

例如,模板中为 {@literal "This is between {1} and {2}"},格式化结果为 {@literal "This is between 666 and 999"}, - * 由于其最大下标为 2, 则解析结果中固定有 3 个元素,解析结果为 {@code [null, "666", "999"]}

- * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @param idxValueConsumer 处理 下标 和 下标占位符位置的值 的消费者,例如:
{@code (idx, value) -> list.set(idx, value)} - * @param missingIndexHandler 根据 下标 返回 默认值,该参数可以为 {@code null},仅在 {@link Feature#MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE} 策略时生效 - */ - public void matchesIndexed(final String str, final BiConsumer idxValueConsumer, - final IntFunction missingIndexHandler) { - if (str == null || CollUtil.isEmpty(placeholderSegments) || !isMatches(str)) { - return; - } + /** + * 根据 下标 和 下标占位符位置的值,自行提取结果值 + * + *

例如,模板中为 {@literal "This is between {1} and {2}"},格式化结果为 {@literal "This is between 666 and 999"}, + * 由于其最大下标为 2, 则解析结果中固定有 3 个元素,解析结果为 {@code [null, "666", "999"]}

+ * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @param idxValueConsumer 处理 下标 和 下标占位符位置的值 的消费者,例如:
{@code (idx, value) -> list.set(idx, value)} + * @param missingIndexHandler 根据 下标 返回 默认值,该参数可以为 {@code null},仅在 {@link Feature#MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE} 策略时生效 + */ + public void matchesIndexed(final String str, final BiConsumer idxValueConsumer, + final IntFunction missingIndexHandler) { + if (str == null || CollUtil.isEmpty(placeholderSegments) || !isMatches(str)) { + return; + } - if (missingIndexHandler == null) { - matchesByKey(str, (key, value) -> idxValueConsumer.accept(Integer.parseInt(key), value)); - } else { - matchesByKey(str, (key, value) -> idxValueConsumer.accept(Integer.parseInt(key), value), true, segment -> { - if ((segment instanceof IndexedPlaceholderSegment)) { - return missingIndexHandler.apply(((IndexedPlaceholderSegment) segment).getIndex()); - } - return getDefaultValue(segment); - }); - } - } - // endregion + if (missingIndexHandler == null) { + matchesByKey(str, (key, value) -> idxValueConsumer.accept(Integer.parseInt(key), value)); + } else { + matchesByKey(str, (key, value) -> idxValueConsumer.accept(Integer.parseInt(key), value), true, segment -> { + if ((segment instanceof IndexedPlaceholderSegment)) { + return missingIndexHandler.apply(((IndexedPlaceholderSegment) segment).getIndex()); + } + return getDefaultValue(segment); + }); + } + } + // endregion - // region 基于键值的解析方法 - // ############################## 基于键值的解析方法 ############################## + // region 基于键值的解析方法 + // ############################## 基于键值的解析方法 ############################## - /** - * 根据 占位变量 和 对应位置解析值 构造 {@link Map} - * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @return {@link Map} - */ - public Map matches(final String str) { - return matches(str, HashMap::new); - } + /** + * 根据 占位变量 和 对应位置解析值 构造 {@link Map} + * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @return {@link Map} + */ + public Map matches(final String str) { + return matches(str, HashMap::new); + } - /** - * 根据 占位变量 和 对应位置解析值 构造 map 或者 bean 实例 - * - * @param str 待解析的字符串,一般是格式化方法的返回值 - * @param beanOrMapSupplier 提供一个 bean 或者 map,例如:{@code HashMap::new} - * @param 返回结果对象类型 - * @return map 或者 bean 实例 - */ - public T matches(final String str, final Supplier beanOrMapSupplier) { - Assert.notNull(beanOrMapSupplier, "beanOrMapSupplier cannot be null"); - final T obj = beanOrMapSupplier.get(); - if (str == null || obj == null || placeholderSegments.isEmpty() || !isMatches(str)) { - return obj; - } + /** + * 根据 占位变量 和 对应位置解析值 构造 map 或者 bean 实例 + * + * @param str 待解析的字符串,一般是格式化方法的返回值 + * @param beanOrMapSupplier 提供一个 bean 或者 map,例如:{@code HashMap::new} + * @param 返回结果对象类型 + * @return map 或者 bean 实例 + */ + public T matches(final String str, final Supplier beanOrMapSupplier) { + Assert.notNull(beanOrMapSupplier, "beanOrMapSupplier cannot be null"); + final T obj = beanOrMapSupplier.get(); + if (str == null || obj == null || placeholderSegments.isEmpty() || !isMatches(str)) { + return obj; + } - if (obj instanceof Map) { - @SuppressWarnings("unchecked") final Map map = (Map) obj; - matchesByKey(str, map::put); - } else if (BeanUtil.isReadableBean(obj.getClass())) { - final BeanDesc beanDesc = BeanUtil.getBeanDesc(obj.getClass()); - matchesByKey(str, (key, value) -> { - final Field field = beanDesc.getField(key); - final Method setterMethod = beanDesc.getSetter(key); - if (field == null || setterMethod == null) { - return; - } - final Object convert = Convert.convert(field.getType(), value); - LambdaUtil.buildSetter(setterMethod).accept(obj, convert); - }); - } - return obj; - } - // endregion - // endregion + if (obj instanceof Map) { + @SuppressWarnings("unchecked") final Map map = (Map) obj; + matchesByKey(str, map::put); + } else if (BeanUtil.isReadableBean(obj.getClass())) { + final BeanDesc beanDesc = BeanUtil.getBeanDesc(obj.getClass()); + matchesByKey(str, (key, value) -> { + final Field field = beanDesc.getField(key); + final Method setterMethod = beanDesc.getSetter(key); + if (field == null || setterMethod == null) { + return; + } + final Object convert = Convert.convert(field.getType(), value); + LambdaUtil.buildSetter(setterMethod).accept(obj, convert); + }); + } + return obj; + } + // endregion + // endregion - /** - * 创建 builder - * - * @param template 字符串模板,不能为 {@code null} - * @return builder实例 - */ - public static Builder builder(final String template) { - return new Builder(template); - } + /** + * 创建 builder + * + * @param template 字符串模板,不能为 {@code null} + * @return builder实例 + */ + public static Builder builder(final String template) { + return new Builder(template); + } /** * 构造器 */ - public static class Builder extends AbstractBuilder { - /** - * 占位符前缀,默认为 {@link NamedPlaceholderStrTemplate#DEFAULT_PREFIX} - *

不能为空字符串

- */ - protected String prefix; - /** - * 占位符后缀,默认为 {@link NamedPlaceholderStrTemplate#DEFAULT_SUFFIX} - *

不能为空字符串

- */ - protected String suffix; + public static class Builder extends AbstractBuilder { + /** + * 占位符前缀,默认为 {@link NamedPlaceholderStrTemplate#DEFAULT_PREFIX} + *

不能为空字符串

+ */ + protected String prefix; + /** + * 占位符后缀,默认为 {@link NamedPlaceholderStrTemplate#DEFAULT_SUFFIX} + *

不能为空字符串

+ */ + protected String suffix; - protected Builder(final String template) { - super(template); - } + protected Builder(final String template) { + super(template); + } - /** - * 设置 占位符前缀 - * - * @param prefix 占位符前缀,不能为空字符串 - * @return builder - */ - public Builder prefix(final String prefix) { - this.prefix = prefix; - return this; - } + /** + * 设置 占位符前缀 + * + * @param prefix 占位符前缀,不能为空字符串 + * @return builder + */ + public Builder prefix(final String prefix) { + this.prefix = prefix; + return this; + } - /** - * 设置 占位符后缀 - * - * @param suffix 占位符后缀,不能为空字符串 - * @return builder - */ - public Builder suffix(final String suffix) { - this.suffix = suffix; - return this; - } + /** + * 设置 占位符后缀 + * + * @param suffix 占位符后缀,不能为空字符串 + * @return builder + */ + public Builder suffix(final String suffix) { + this.suffix = suffix; + return this; + } - @Override - protected NamedPlaceholderStrTemplate buildInstance() { - if (this.prefix == null) { - this.prefix = DEFAULT_PREFIX; - } - if (this.suffix == null) { - this.suffix = DEFAULT_SUFFIX; - } - return new NamedPlaceholderStrTemplate(this.template, this.features, this.prefix, this.suffix, this.escape, this.defaultValue, this.defaultValueHandler); - } + @Override + protected NamedPlaceholderStrTemplate buildInstance() { + if (this.prefix == null) { + this.prefix = DEFAULT_PREFIX; + } + if (this.suffix == null) { + this.suffix = DEFAULT_SUFFIX; + } + return new NamedPlaceholderStrTemplate(this.template, this.features, this.prefix, this.suffix, this.escape, this.defaultValue, this.defaultValueHandler); + } - @Override - protected Builder self() { - return this; - } - } + @Override + protected Builder self() { + return this; + } + } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/text/StrTemplateTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/text/StrTemplateTest.java index 46242c1ed..f149cdfcd 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/text/StrTemplateTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/text/StrTemplateTest.java @@ -38,646 +38,646 @@ import java.util.function.Supplier; */ public class StrTemplateTest { - @Test - public void singlePlaceholderFormatTest() { - // 默认值 - testSinglePlaceholderFormat("{}", '\\'); + @Test + public void singlePlaceholderFormatTest() { + // 默认值 + testSinglePlaceholderFormat("{}", '\\'); - // 自定义占位符 - testSinglePlaceholderFormat("?", '\\'); + // 自定义占位符 + testSinglePlaceholderFormat("?", '\\'); - // 自定义多个占位符 - testSinglePlaceholderFormat("$$$", '\\'); + // 自定义多个占位符 + testSinglePlaceholderFormat("$$$", '\\'); - // 自定义多个占位符和转义符 - testSinglePlaceholderFormat("$$$", '/'); - } + // 自定义多个占位符和转义符 + testSinglePlaceholderFormat("$$$", '/'); + } - @Test - public void namedPlaceholderFormatSequenceTest() { - String text = "select * from #[tableName] where id = #[id]"; - NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.formatSequence("user", 1001) - ); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.formatArraySequence(new String[]{"user", "1001"}) - ); - Assertions.assertEquals( - "select * from 123 where id = 456", - strTemplate.formatArraySequence(new int[]{123, 456}) - ); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.formatSequence(ListUtil.of("user", 1001)) - ); - } + @Test + public void namedPlaceholderFormatSequenceTest() { + final String text = "select * from #[tableName] where id = #[id]"; + final NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.formatSequence("user", 1001) + ); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.formatArraySequence(new String[]{"user", "1001"}) + ); + Assertions.assertEquals( + "select * from 123 where id = 456", + strTemplate.formatArraySequence(new int[]{123, 456}) + ); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.formatSequence(ListUtil.of("user", 1001)) + ); + } - @Test - public void namedPlaceholderFormatIndexedTest() { - String text = "select * from #[1] where id = #[2]"; - NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + @Test + public void namedPlaceholderFormatIndexedTest() { + final String text = "select * from #[1] where id = #[2]"; + final NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.formatIndexed("hutool", "user", 1001) - ); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.formatArrayIndexed(new String[]{"hutool", "user", "1001"}) - ); - Assertions.assertEquals( - "select * from 123 where id = 456", - strTemplate.formatArrayIndexed(new int[]{666, 123, 456}) - ); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.formatIndexed(ListUtil.of("hutool", "user", 1001)) - ); - Assertions.assertEquals( - "select * from user where id = ?", - strTemplate.formatIndexed(ListUtil.of("hutool", "user"), idx -> "?") - ); - } + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.formatIndexed("hutool", "user", 1001) + ); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.formatArrayIndexed(new String[]{"hutool", "user", "1001"}) + ); + Assertions.assertEquals( + "select * from 123 where id = 456", + strTemplate.formatArrayIndexed(new int[]{666, 123, 456}) + ); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.formatIndexed(ListUtil.of("hutool", "user", 1001)) + ); + Assertions.assertEquals( + "select * from user where id = ?", + strTemplate.formatIndexed(ListUtil.of("hutool", "user"), idx -> "?") + ); + } - @Test - public void namedPlaceholderFormatTest() { - String text = "select * from #[tableName] where id = #[id]"; - NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + @Test + public void namedPlaceholderFormatTest() { + final String text = "select * from #[tableName] where id = #[id]"; + final NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Map map = MapUtil.builder().put("tableName", "user").put("id", 1001).build(); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.format(map) - ); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.format((Object) map) - ); + final Map map = MapUtil.builder().put("tableName", "user").put("id", 1001).build(); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.format(map) + ); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.format((Object) map) + ); - FormatEntity entity = new FormatEntity().setTableName("user").setId(1001); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.format(entity) - ); - entity = new FormatEntity().setTableName("user").setId(1001); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.format(entity) - ); - } + FormatEntity entity = new FormatEntity().setTableName("user").setId(1001); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.format(entity) + ); + entity = new FormatEntity().setTableName("user").setId(1001); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.format(entity) + ); + } - @Data - @Accessors(chain = true) - @NoArgsConstructor - @AllArgsConstructor - public static class FormatEntity { - private String tableName; - private Integer id; - } + @Data + @Accessors(chain = true) + @NoArgsConstructor + @AllArgsConstructor + public static class FormatEntity { + private String tableName; + private Integer id; + } - @Test - public void namedPlaceholderFormatDefaultValueTest() { - String text = "i {a}{m} a {jvav} programmer"; - NamedPlaceholderStrTemplate.Builder strTemplate = StrTemplate.ofNamed(text) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); - Assertions.assertEquals( - "i a programmer", - strTemplate.defaultValue(s -> "") - .build() - .formatSequence() - ); - Assertions.assertEquals( - "i ?? a ? programmer", - strTemplate.defaultValue(s -> "?") - .build() - .formatSequence() - ); - Assertions.assertEquals( - "i $$$$$$ a $$$ programmer", - strTemplate.defaultValue(s -> "$$$") - .build() - .formatSequence() - ); + @Test + public void namedPlaceholderFormatDefaultValueTest() { + String text = "i {a}{m} a {jvav} programmer"; + NamedPlaceholderStrTemplate.Builder strTemplate = StrTemplate.ofNamed(text) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); + Assertions.assertEquals( + "i a programmer", + strTemplate.defaultValue(s -> "") + .build() + .formatSequence() + ); + Assertions.assertEquals( + "i ?? a ? programmer", + strTemplate.defaultValue(s -> "?") + .build() + .formatSequence() + ); + Assertions.assertEquals( + "i $$$$$$ a $$$ programmer", + strTemplate.defaultValue(s -> "$$$") + .build() + .formatSequence() + ); - text = "select * from #[tableName] where id = #[id]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]"); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.defaultValue(s -> "?") - .build() - .formatSequence("user", 1001) - ); - Assertions.assertEquals( - "select * from user where id = ?", - strTemplate.defaultValue(s -> "?") - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE) - .build() - .formatSequence("user") - ); - Assertions.assertEquals( - "select * from user where id = ?", - strTemplate.defaultValue(s -> "?") - .build() - .formatArraySequence(new String[]{"user"}) - ); - Assertions.assertEquals( - "select * from user where id = ?", - strTemplate.defaultValue(s -> "?") - .build() - .formatSequence(ListUtil.of("user")) - ); + text = "select * from #[tableName] where id = #[id]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]"); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.defaultValue(s -> "?") + .build() + .formatSequence("user", 1001) + ); + Assertions.assertEquals( + "select * from user where id = ?", + strTemplate.defaultValue(s -> "?") + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE) + .build() + .formatSequence("user") + ); + Assertions.assertEquals( + "select * from user where id = ?", + strTemplate.defaultValue(s -> "?") + .build() + .formatArraySequence(new String[]{"user"}) + ); + Assertions.assertEquals( + "select * from user where id = ?", + strTemplate.defaultValue(s -> "?") + .build() + .formatSequence(ListUtil.of("user")) + ); - text = "select * from #[1] where id = #[2]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); - Assertions.assertEquals( - "select * from user where id = ?", - strTemplate.defaultValue(s -> "?") - .build() - .formatIndexed("hutool", "user") - ); - Assertions.assertEquals( - "select * from user where id = ?", - strTemplate.defaultValue(s -> "?") - .build() - .formatArrayIndexed(new String[]{"hutool", "user"}) - ); - Assertions.assertEquals( - "select * from user where id = ?", - strTemplate.defaultValue(s -> "?") - .build() - .formatIndexed(ListUtil.of("hutool", "user")) - ); - } + text = "select * from #[1] where id = #[2]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); + Assertions.assertEquals( + "select * from user where id = ?", + strTemplate.defaultValue(s -> "?") + .build() + .formatIndexed("hutool", "user") + ); + Assertions.assertEquals( + "select * from user where id = ?", + strTemplate.defaultValue(s -> "?") + .build() + .formatArrayIndexed(new String[]{"hutool", "user"}) + ); + Assertions.assertEquals( + "select * from user where id = ?", + strTemplate.defaultValue(s -> "?") + .build() + .formatIndexed(ListUtil.of("hutool", "user")) + ); + } - @Test - public void namedPlaceholderEscapeTest() { - Map map = MapUtil.builder().put("tableName", "user").put("id", 1001).build(); - // 转义符 - String text = "select * from \\#[tableName] where id = \\#[id]"; - NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from #[tableName] where id = #[id]", - strTemplate.format(map) - ); - text = "select * from \\#[tableName] where id = #[id\\]]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from #[tableName] where id = 1001", - strTemplate.format(MapUtil.builder().put("tableName", "user").put("id]", 1001).build()) - ); + @Test + public void namedPlaceholderEscapeTest() { + final Map map = MapUtil.builder().put("tableName", "user").put("id", 1001).build(); + // 转义符 + String text = "select * from \\#[tableName] where id = \\#[id]"; + NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + Assertions.assertEquals( + "select * from #[tableName] where id = #[id]", + strTemplate.format(map) + ); + text = "select * from \\#[tableName] where id = #[id\\]]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + Assertions.assertEquals( + "select * from #[tableName] where id = 1001", + strTemplate.format(MapUtil.builder().put("tableName", "user").put("id]", 1001).build()) + ); - // 转义 转义符 - text = "select * from \\\\#[tableName] where id = #[id]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from \\user where id = 1001", - strTemplate.format(map) - ); - text = "select * from \\\\#[tableName] where id = \\\\#[id]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from \\user where id = \\1001", - strTemplate.format(map) - ); - text = "select * from \\\\#[tableName] where id = #[id\\\\]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from \\user where id = 1001", - strTemplate.format(MapUtil.builder().put("tableName", "user").put("id\\", 1001).build()) - ); - text = "select * from #[tableName\\\\] where id = #[id\\\\]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); - Assertions.assertEquals( - "select * from user where id = 1001", - strTemplate.format(MapUtil.builder().put("tableName\\", "user").put("id\\", 1001).build()) - ); + // 转义 转义符 + text = "select * from \\\\#[tableName] where id = #[id]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + Assertions.assertEquals( + "select * from \\user where id = 1001", + strTemplate.format(map) + ); + text = "select * from \\\\#[tableName] where id = \\\\#[id]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + Assertions.assertEquals( + "select * from \\user where id = \\1001", + strTemplate.format(map) + ); + text = "select * from \\\\#[tableName] where id = #[id\\\\]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + Assertions.assertEquals( + "select * from \\user where id = 1001", + strTemplate.format(MapUtil.builder().put("tableName", "user").put("id\\", 1001).build()) + ); + text = "select * from #[tableName\\\\] where id = #[id\\\\]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").build(); + Assertions.assertEquals( + "select * from user where id = 1001", + strTemplate.format(MapUtil.builder().put("tableName\\", "user").put("id\\", 1001).build()) + ); - // 自定义 转义符 - text = "select * from /#[tableName] where id = /#[id]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").escape('/').build(); - Assertions.assertEquals( - "select * from #[tableName] where id = #[id]", - strTemplate.format(map) - ); - text = "select * from //#[tableName] where id = //#[id]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").escape('/').build(); - Assertions.assertEquals( - "select * from /user where id = /1001", - strTemplate.format(map) - ); - text = "select * from /#[tableName] where id = #[id/]]"; - strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").escape('/').build(); - Assertions.assertEquals( - "select * from #[tableName] where id = 1001", - strTemplate.format(MapUtil.builder().put("tableName", "user").put("id]", 1001).build()) - ); - } + // 自定义 转义符 + text = "select * from /#[tableName] where id = /#[id]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").escape('/').build(); + Assertions.assertEquals( + "select * from #[tableName] where id = #[id]", + strTemplate.format(map) + ); + text = "select * from //#[tableName] where id = //#[id]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").escape('/').build(); + Assertions.assertEquals( + "select * from /user where id = /1001", + strTemplate.format(map) + ); + text = "select * from /#[tableName] where id = #[id/]]"; + strTemplate = StrTemplate.ofNamed(text).prefix("#[").suffix("]").escape('/').build(); + Assertions.assertEquals( + "select * from #[tableName] where id = 1001", + strTemplate.format(MapUtil.builder().put("tableName", "user").put("id]", 1001).build()) + ); + } - private void testSinglePlaceholderFormat(String placeholder, char escape) { - // 通常使用 - String commonTemplate = "this is " + placeholder + " for " + placeholder; - SinglePlaceholderStrTemplate template = StrTemplate.of(commonTemplate) - .placeholder(placeholder) - .escape(escape) - .build(); + private void testSinglePlaceholderFormat(final String placeholder, final char escape) { + // 通常使用 + final String commonTemplate = "this is " + placeholder + " for " + placeholder; + final SinglePlaceholderStrTemplate template = StrTemplate.of(commonTemplate) + .placeholder(placeholder) + .escape(escape) + .build(); - // 普通使用 - Assertions.assertEquals("this is a for 666", - template.format("a", 666) - ); - Assertions.assertEquals("this is a for 666", - template.format(ListUtil.of("a", 666)) - ); - Assertions.assertEquals("this is 123 for 456", - template.formatArray(new int[]{123, 456}) - ); - Assertions.assertEquals("this is 123 for 456", - template.formatArray(new Integer[]{123, 456}) - ); + // 普通使用 + Assertions.assertEquals("this is a for 666", + template.format("a", 666) + ); + Assertions.assertEquals("this is a for 666", + template.format(ListUtil.of("a", 666)) + ); + Assertions.assertEquals("this is 123 for 456", + template.formatArray(new int[]{123, 456}) + ); + Assertions.assertEquals("this is 123 for 456", + template.formatArray(new Integer[]{123, 456}) + ); - // 转义占位符 - Assertions.assertEquals("this is " + placeholder + " for a", - StrTemplate.of("this is " + escape + placeholder + " for " + placeholder) - .placeholder(placeholder) - .escape(escape) - .build() - .format("a", "b") - ); - // 转义"转义符" - Assertions.assertEquals("this is " + escape + "a for b", - StrTemplate.of("this is " + escape + escape + placeholder + " for " + placeholder) - .placeholder(placeholder) - .escape(escape) - .build() - .format("a", "b") - ); - // 填充null值 - Assertions.assertEquals("this is " + null + " for b", - template.format(null, "b") - ); - Assertions.assertEquals("this is a for null", - template.format("a", null) - ); + // 转义占位符 + Assertions.assertEquals("this is " + placeholder + " for a", + StrTemplate.of("this is " + escape + placeholder + " for " + placeholder) + .placeholder(placeholder) + .escape(escape) + .build() + .format("a", "b") + ); + // 转义"转义符" + Assertions.assertEquals("this is " + escape + "a for b", + StrTemplate.of("this is " + escape + escape + placeholder + " for " + placeholder) + .placeholder(placeholder) + .escape(escape) + .build() + .format("a", "b") + ); + // 填充null值 + Assertions.assertEquals("this is " + null + " for b", + template.format(null, "b") + ); + Assertions.assertEquals("this is a for null", + template.format("a", null) + ); - // 序列化参数 小于 占位符数量 - Assertions.assertEquals("this is a for " + placeholder, - template.format("a") - ); + // 序列化参数 小于 占位符数量 + Assertions.assertEquals("this is a for " + placeholder, + template.format("a") + ); - SinglePlaceholderStrTemplate.Builder builder = StrTemplate.of(commonTemplate) - .placeholder(placeholder) - .escape(escape) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); + SinglePlaceholderStrTemplate.Builder builder = StrTemplate.of(commonTemplate) + .placeholder(placeholder) + .escape(escape) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); - Assertions.assertEquals("this is a for ", - builder.defaultValue("") - .build() - .format("a") - ); - Assertions.assertEquals("this is a for 666", - builder.defaultValue("666") - .build() - .format("a") - ); + Assertions.assertEquals("this is a for ", + builder.defaultValue("") + .build() + .format("a") + ); + Assertions.assertEquals("this is a for 666", + builder.defaultValue("666") + .build() + .format("a") + ); - builder = StrTemplate.of(commonTemplate) - .placeholder(placeholder) - .escape(escape) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); - Assertions.assertEquals("this is a for ", - builder.defaultValue(s -> "") - .build() - .format("a") - ); + builder = StrTemplate.of(commonTemplate) + .placeholder(placeholder) + .escape(escape) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE); + Assertions.assertEquals("this is a for ", + builder.defaultValue(s -> "") + .build() + .format("a") + ); - Assertions.assertEquals("this is a for 666", - builder.defaultValue(s -> "666") - .build() - .format("a") - ); + Assertions.assertEquals("this is a for 666", + builder.defaultValue(s -> "666") + .build() + .format("a") + ); - // 序列化参数 超过 占位符数量 - Assertions.assertEquals("this is a for b", - builder.build() - .format("a", "b", "c") - ); + // 序列化参数 超过 占位符数量 + Assertions.assertEquals("this is a for b", + builder.build() + .format("a", "b", "c") + ); - // 残缺的占位符 - if (placeholder.length() >= 2) { - Assertions.assertEquals("this is " + placeholder.charAt(0) + " for a", - StrTemplate.of("this is " + placeholder.charAt(0) + " for " + placeholder) - .placeholder(placeholder) - .escape(escape) - .build() - .format("a") - ); - Assertions.assertEquals("this is " + placeholder.charAt(1) + " for a", - StrTemplate.of("this is " + placeholder.charAt(1) + " for " + placeholder) - .placeholder(placeholder) - .escape(escape) - .build() - .format("a") - ); - Assertions.assertEquals("this is " + placeholder.charAt(0) + ' ' + placeholder.charAt(1) + " for a", - StrTemplate.of("this is " + placeholder.charAt(0) + ' ' + placeholder.charAt(1) + " for " + placeholder) - .placeholder(placeholder) - .escape(escape) - .build() - .format("a") - ); - } - } + // 残缺的占位符 + if (placeholder.length() >= 2) { + Assertions.assertEquals("this is " + placeholder.charAt(0) + " for a", + StrTemplate.of("this is " + placeholder.charAt(0) + " for " + placeholder) + .placeholder(placeholder) + .escape(escape) + .build() + .format("a") + ); + Assertions.assertEquals("this is " + placeholder.charAt(1) + " for a", + StrTemplate.of("this is " + placeholder.charAt(1) + " for " + placeholder) + .placeholder(placeholder) + .escape(escape) + .build() + .format("a") + ); + Assertions.assertEquals("this is " + placeholder.charAt(0) + ' ' + placeholder.charAt(1) + " for a", + StrTemplate.of("this is " + placeholder.charAt(0) + ' ' + placeholder.charAt(1) + " for " + placeholder) + .placeholder(placeholder) + .escape(escape) + .build() + .format("a") + ); + } + } - @Test - public void isMatchesTest() { - SinglePlaceholderStrTemplate strTemplate = StrTemplate.of("this is {} for {}").build(); - Assertions.assertTrue(strTemplate.isMatches("this is a for b")); - Assertions.assertTrue(strTemplate.isMatches("this is aaa for 666")); - Assertions.assertTrue(strTemplate.isMatches("this is a for b ")); - Assertions.assertTrue(strTemplate.isMatches("this is a x for b")); - Assertions.assertTrue(strTemplate.isMatches("this is {} for {}")); - Assertions.assertTrue(strTemplate.isMatches("this is { } for {}")); - Assertions.assertTrue(strTemplate.isMatches("this is { } for { }")); - Assertions.assertTrue(strTemplate.isMatches("this is a for b")); - Assertions.assertTrue(strTemplate.isMatches("this is a for b")); - Assertions.assertTrue(strTemplate.isMatches("this is a for b")); - Assertions.assertTrue(strTemplate.isMatches("this is a for ")); - Assertions.assertTrue(strTemplate.isMatches("this is for b")); - Assertions.assertTrue(strTemplate.isMatches("this is for ")); + @Test + public void isMatchesTest() { + SinglePlaceholderStrTemplate strTemplate = StrTemplate.of("this is {} for {}").build(); + Assertions.assertTrue(strTemplate.isMatches("this is a for b")); + Assertions.assertTrue(strTemplate.isMatches("this is aaa for 666")); + Assertions.assertTrue(strTemplate.isMatches("this is a for b ")); + Assertions.assertTrue(strTemplate.isMatches("this is a x for b")); + Assertions.assertTrue(strTemplate.isMatches("this is {} for {}")); + Assertions.assertTrue(strTemplate.isMatches("this is { } for {}")); + Assertions.assertTrue(strTemplate.isMatches("this is { } for { }")); + Assertions.assertTrue(strTemplate.isMatches("this is a for b")); + Assertions.assertTrue(strTemplate.isMatches("this is a for b")); + Assertions.assertTrue(strTemplate.isMatches("this is a for b")); + Assertions.assertTrue(strTemplate.isMatches("this is a for ")); + Assertions.assertTrue(strTemplate.isMatches("this is for b")); + Assertions.assertTrue(strTemplate.isMatches("this is for ")); - Assertions.assertFalse(strTemplate.isMatches("")); - Assertions.assertFalse(strTemplate.isMatches(" ")); - Assertions.assertFalse(strTemplate.isMatches(" \r\n \n ")); - Assertions.assertFalse(strTemplate.isMatches(" this is a for b")); - Assertions.assertFalse(strTemplate.isMatches("this is a forb")); - Assertions.assertFalse(strTemplate.isMatches("this is a for b")); - Assertions.assertFalse(strTemplate.isMatches("this are a for b")); - Assertions.assertFalse(strTemplate.isMatches("that is a for b")); + Assertions.assertFalse(strTemplate.isMatches("")); + Assertions.assertFalse(strTemplate.isMatches(" ")); + Assertions.assertFalse(strTemplate.isMatches(" \r\n \n ")); + Assertions.assertFalse(strTemplate.isMatches(" this is a for b")); + Assertions.assertFalse(strTemplate.isMatches("this is a forb")); + Assertions.assertFalse(strTemplate.isMatches("this is a for b")); + Assertions.assertFalse(strTemplate.isMatches("this are a for b")); + Assertions.assertFalse(strTemplate.isMatches("that is a for b")); - // 占位符在最前和最后 - strTemplate = StrTemplate.of("{}, this is for {}").build(); - Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you")); - Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you ")); - Assertions.assertTrue(strTemplate.isMatches(" Cleveland, this is for you")); - Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you ")); - Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you ?")); - Assertions.assertTrue(strTemplate.isMatches("Cleveland , this is for you")); - Assertions.assertTrue(strTemplate.isMatches(":)Cleveland, this is for you")); + // 占位符在最前和最后 + strTemplate = StrTemplate.of("{}, this is for {}").build(); + Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you")); + Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you ")); + Assertions.assertTrue(strTemplate.isMatches(" Cleveland, this is for you")); + Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you ")); + Assertions.assertTrue(strTemplate.isMatches("Cleveland, this is for you ?")); + Assertions.assertTrue(strTemplate.isMatches("Cleveland , this is for you")); + Assertions.assertTrue(strTemplate.isMatches(":)Cleveland, this is for you")); - Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is for you")); - Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is for you")); - Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is for you")); - Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is four you")); - Assertions.assertFalse(strTemplate.isMatches("Cleveland, this are for you")); - Assertions.assertFalse(strTemplate.isMatches("Cleveland, that is for you")); - } + Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is for you")); + Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is for you")); + Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is for you")); + Assertions.assertFalse(strTemplate.isMatches("Cleveland, this is four you")); + Assertions.assertFalse(strTemplate.isMatches("Cleveland, this are for you")); + Assertions.assertFalse(strTemplate.isMatches("Cleveland, that is for you")); + } - @Test - public void singlePlaceholderMatchesTest() { - SinglePlaceholderStrTemplate strTemplate = StrTemplate.of("this is {} for {}").build(); - Assertions.assertEquals(ListUtil.of("a", "b"), strTemplate.matches("this is a for b")); - Assertions.assertEquals(ListUtil.of("aaa", "666"), strTemplate.matches("this is aaa for 666")); - Assertions.assertEquals(ListUtil.of("a", "b "), strTemplate.matches("this is a for b ")); - Assertions.assertEquals(ListUtil.of("a x", "b"), strTemplate.matches("this is a x for b")); - Assertions.assertEquals(ListUtil.of("{}", "{}"), strTemplate.matches("this is {} for {}")); - Assertions.assertEquals(ListUtil.of("{ }", "{}"), strTemplate.matches("this is { } for {}")); - Assertions.assertEquals(ListUtil.of("{ }", "{ }"), strTemplate.matches("this is { } for { }")); - Assertions.assertEquals(ListUtil.of(" a", "b"), strTemplate.matches("this is a for b")); - Assertions.assertEquals(ListUtil.of(" a", " b"), strTemplate.matches("this is a for b")); - Assertions.assertEquals(ListUtil.of("a ", "b"), strTemplate.matches("this is a for b")); - Assertions.assertEquals(ListUtil.of("a", null), strTemplate.matches("this is a for ")); - Assertions.assertEquals(ListUtil.of(null, "b"), strTemplate.matches("this is for b")); - Assertions.assertEquals(ListUtil.of(null, null), strTemplate.matches("this is for ")); + @Test + public void singlePlaceholderMatchesTest() { + SinglePlaceholderStrTemplate strTemplate = StrTemplate.of("this is {} for {}").build(); + Assertions.assertEquals(ListUtil.of("a", "b"), strTemplate.matches("this is a for b")); + Assertions.assertEquals(ListUtil.of("aaa", "666"), strTemplate.matches("this is aaa for 666")); + Assertions.assertEquals(ListUtil.of("a", "b "), strTemplate.matches("this is a for b ")); + Assertions.assertEquals(ListUtil.of("a x", "b"), strTemplate.matches("this is a x for b")); + Assertions.assertEquals(ListUtil.of("{}", "{}"), strTemplate.matches("this is {} for {}")); + Assertions.assertEquals(ListUtil.of("{ }", "{}"), strTemplate.matches("this is { } for {}")); + Assertions.assertEquals(ListUtil.of("{ }", "{ }"), strTemplate.matches("this is { } for { }")); + Assertions.assertEquals(ListUtil.of(" a", "b"), strTemplate.matches("this is a for b")); + Assertions.assertEquals(ListUtil.of(" a", " b"), strTemplate.matches("this is a for b")); + Assertions.assertEquals(ListUtil.of("a ", "b"), strTemplate.matches("this is a for b")); + Assertions.assertEquals(ListUtil.of("a", null), strTemplate.matches("this is a for ")); + Assertions.assertEquals(ListUtil.of(null, "b"), strTemplate.matches("this is for b")); + Assertions.assertEquals(ListUtil.of(null, null), strTemplate.matches("this is for ")); - final List emptyList = Collections.emptyList(); - Assertions.assertEquals(emptyList, strTemplate.matches("")); - Assertions.assertEquals(emptyList, strTemplate.matches(" ")); - Assertions.assertEquals(emptyList, strTemplate.matches(" \r\n \n ")); - Assertions.assertEquals(emptyList, strTemplate.matches(" this is a for b")); - Assertions.assertEquals(emptyList, strTemplate.matches("this is a forb")); - Assertions.assertEquals(emptyList, strTemplate.matches("this is a for b")); - Assertions.assertEquals(emptyList, strTemplate.matches("this are a for b")); - Assertions.assertEquals(emptyList, strTemplate.matches("that is a for b")); + final List emptyList = Collections.emptyList(); + Assertions.assertEquals(emptyList, strTemplate.matches("")); + Assertions.assertEquals(emptyList, strTemplate.matches(" ")); + Assertions.assertEquals(emptyList, strTemplate.matches(" \r\n \n ")); + Assertions.assertEquals(emptyList, strTemplate.matches(" this is a for b")); + Assertions.assertEquals(emptyList, strTemplate.matches("this is a forb")); + Assertions.assertEquals(emptyList, strTemplate.matches("this is a for b")); + Assertions.assertEquals(emptyList, strTemplate.matches("this are a for b")); + Assertions.assertEquals(emptyList, strTemplate.matches("that is a for b")); - strTemplate = StrTemplate.of("{}, this is for {}").build(); - Assertions.assertEquals(ListUtil.of("Cleveland", "you"), strTemplate.matches("Cleveland, this is for you")); - Assertions.assertEquals(ListUtil.of(" Cleveland", "you"), strTemplate.matches(" Cleveland, this is for you")); - Assertions.assertEquals(ListUtil.of("Cleveland ", "you"), strTemplate.matches("Cleveland , this is for you")); - Assertions.assertEquals(ListUtil.of("Cleveland", "you "), strTemplate.matches("Cleveland, this is for you ")); - Assertions.assertEquals(ListUtil.of("Cleveland", " you"), strTemplate.matches("Cleveland, this is for you")); - Assertions.assertEquals(ListUtil.of("Cleveland", " you "), strTemplate.matches("Cleveland, this is for you ")); - Assertions.assertEquals(ListUtil.of("Cleveland", "you ?"), strTemplate.matches("Cleveland, this is for you ?")); - Assertions.assertEquals(ListUtil.of(":)Cleveland", "you:("), strTemplate.matches(":)Cleveland, this is for you:(")); + strTemplate = StrTemplate.of("{}, this is for {}").build(); + Assertions.assertEquals(ListUtil.of("Cleveland", "you"), strTemplate.matches("Cleveland, this is for you")); + Assertions.assertEquals(ListUtil.of(" Cleveland", "you"), strTemplate.matches(" Cleveland, this is for you")); + Assertions.assertEquals(ListUtil.of("Cleveland ", "you"), strTemplate.matches("Cleveland , this is for you")); + Assertions.assertEquals(ListUtil.of("Cleveland", "you "), strTemplate.matches("Cleveland, this is for you ")); + Assertions.assertEquals(ListUtil.of("Cleveland", " you"), strTemplate.matches("Cleveland, this is for you")); + Assertions.assertEquals(ListUtil.of("Cleveland", " you "), strTemplate.matches("Cleveland, this is for you ")); + Assertions.assertEquals(ListUtil.of("Cleveland", "you ?"), strTemplate.matches("Cleveland, this is for you ?")); + Assertions.assertEquals(ListUtil.of(":)Cleveland", "you:("), strTemplate.matches(":)Cleveland, this is for you:(")); - Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is for you")); - Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is for you")); - Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is for you")); - Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is four you")); - Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this are for you")); - Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, that is for you")); - } + Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is for you")); + Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is for you")); + Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is for you")); + Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this is four you")); + Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, this are for you")); + Assertions.assertEquals(emptyList, strTemplate.matches("Cleveland, that is for you")); + } - @Test - public void namedPlaceholderMatchesSequenceTest() { - NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed("this is {a} for {b}").build(); - Assertions.assertEquals(ListUtil.of("a", "b"), strTemplate.matchesSequence("this is a for b")); - Assertions.assertEquals(ListUtil.of("aaa", "666"), strTemplate.matchesSequence("this is aaa for 666")); - Assertions.assertEquals(ListUtil.of("a", "b "), strTemplate.matchesSequence("this is a for b ")); - Assertions.assertEquals(ListUtil.of("a x", "b"), strTemplate.matchesSequence("this is a x for b")); - Assertions.assertEquals(ListUtil.of("{}", "{}"), strTemplate.matchesSequence("this is {} for {}")); - Assertions.assertEquals(ListUtil.of("{ }", "{}"), strTemplate.matchesSequence("this is { } for {}")); - Assertions.assertEquals(ListUtil.of("{ }", "{ }"), strTemplate.matchesSequence("this is { } for { }")); - Assertions.assertEquals(ListUtil.of(" a", "b"), strTemplate.matchesSequence("this is a for b")); - Assertions.assertEquals(ListUtil.of(" a", " b"), strTemplate.matchesSequence("this is a for b")); - Assertions.assertEquals(ListUtil.of("a ", "b"), strTemplate.matchesSequence("this is a for b")); - Assertions.assertEquals(ListUtil.of("a", null), strTemplate.matchesSequence("this is a for ")); - Assertions.assertEquals(ListUtil.of(null, "b"), strTemplate.matchesSequence("this is for b")); - Assertions.assertEquals(ListUtil.of(null, null), strTemplate.matchesSequence("this is for ")); + @Test + public void namedPlaceholderMatchesSequenceTest() { + NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed("this is {a} for {b}").build(); + Assertions.assertEquals(ListUtil.of("a", "b"), strTemplate.matchesSequence("this is a for b")); + Assertions.assertEquals(ListUtil.of("aaa", "666"), strTemplate.matchesSequence("this is aaa for 666")); + Assertions.assertEquals(ListUtil.of("a", "b "), strTemplate.matchesSequence("this is a for b ")); + Assertions.assertEquals(ListUtil.of("a x", "b"), strTemplate.matchesSequence("this is a x for b")); + Assertions.assertEquals(ListUtil.of("{}", "{}"), strTemplate.matchesSequence("this is {} for {}")); + Assertions.assertEquals(ListUtil.of("{ }", "{}"), strTemplate.matchesSequence("this is { } for {}")); + Assertions.assertEquals(ListUtil.of("{ }", "{ }"), strTemplate.matchesSequence("this is { } for { }")); + Assertions.assertEquals(ListUtil.of(" a", "b"), strTemplate.matchesSequence("this is a for b")); + Assertions.assertEquals(ListUtil.of(" a", " b"), strTemplate.matchesSequence("this is a for b")); + Assertions.assertEquals(ListUtil.of("a ", "b"), strTemplate.matchesSequence("this is a for b")); + Assertions.assertEquals(ListUtil.of("a", null), strTemplate.matchesSequence("this is a for ")); + Assertions.assertEquals(ListUtil.of(null, "b"), strTemplate.matchesSequence("this is for b")); + Assertions.assertEquals(ListUtil.of(null, null), strTemplate.matchesSequence("this is for ")); - final List emptyList = Collections.emptyList(); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence(" ")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence(" \r\n \n ")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence(" this is a for b")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("this is a forb")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("this is a for b")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("this are a for b")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("that is a for b")); + final List emptyList = Collections.emptyList(); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence(" ")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence(" \r\n \n ")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence(" this is a for b")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("this is a forb")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("this is a for b")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("this are a for b")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("that is a for b")); - strTemplate = StrTemplate.ofNamed("{a}, this is for {b}").build(); - Assertions.assertEquals(ListUtil.of("Cleveland", "you"), strTemplate.matchesSequence("Cleveland, this is for you")); - Assertions.assertEquals(ListUtil.of(" Cleveland", "you"), strTemplate.matchesSequence(" Cleveland, this is for you")); - Assertions.assertEquals(ListUtil.of("Cleveland ", "you"), strTemplate.matchesSequence("Cleveland , this is for you")); - Assertions.assertEquals(ListUtil.of("Cleveland", "you "), strTemplate.matchesSequence("Cleveland, this is for you ")); - Assertions.assertEquals(ListUtil.of("Cleveland", " you"), strTemplate.matchesSequence("Cleveland, this is for you")); - Assertions.assertEquals(ListUtil.of("Cleveland", " you "), strTemplate.matchesSequence("Cleveland, this is for you ")); - Assertions.assertEquals(ListUtil.of("Cleveland", "you ?"), strTemplate.matchesSequence("Cleveland, this is for you ?")); - Assertions.assertEquals(ListUtil.of(":)Cleveland", "you:("), strTemplate.matchesSequence(":)Cleveland, this is for you:(")); + strTemplate = StrTemplate.ofNamed("{a}, this is for {b}").build(); + Assertions.assertEquals(ListUtil.of("Cleveland", "you"), strTemplate.matchesSequence("Cleveland, this is for you")); + Assertions.assertEquals(ListUtil.of(" Cleveland", "you"), strTemplate.matchesSequence(" Cleveland, this is for you")); + Assertions.assertEquals(ListUtil.of("Cleveland ", "you"), strTemplate.matchesSequence("Cleveland , this is for you")); + Assertions.assertEquals(ListUtil.of("Cleveland", "you "), strTemplate.matchesSequence("Cleveland, this is for you ")); + Assertions.assertEquals(ListUtil.of("Cleveland", " you"), strTemplate.matchesSequence("Cleveland, this is for you")); + Assertions.assertEquals(ListUtil.of("Cleveland", " you "), strTemplate.matchesSequence("Cleveland, this is for you ")); + Assertions.assertEquals(ListUtil.of("Cleveland", "you ?"), strTemplate.matchesSequence("Cleveland, this is for you ?")); + Assertions.assertEquals(ListUtil.of(":)Cleveland", "you:("), strTemplate.matchesSequence(":)Cleveland, this is for you:(")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is for you")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is for you")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is for you")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is four you")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this are for you")); - Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, that is for you")); - } + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is for you")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is for you")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is for you")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this is four you")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, this are for you")); + Assertions.assertEquals(emptyList, strTemplate.matchesSequence("Cleveland, that is for you")); + } - @Test - public void namedPlaceholderMatchesIndexedTest() { - NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed("this is {2} for {1}").build(); - Assertions.assertEquals(ListUtil.of(null, "b", "a"), strTemplate.matchesIndexed("this is a for b", null)); - Assertions.assertEquals(ListUtil.of(null, "666", "aaa"), strTemplate.matchesIndexed("this is aaa for 666", null)); - Assertions.assertEquals(ListUtil.of(null, "b", null), strTemplate.matchesIndexed("this is for b", null)); - Assertions.assertEquals(ListUtil.of(null, null, "aaa"), strTemplate.matchesIndexed("this is aaa for ", null)); - Assertions.assertEquals(ListUtil.of(null, null, null), strTemplate.matchesIndexed("this is for ", null)); + @Test + public void namedPlaceholderMatchesIndexedTest() { + NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed("this is {2} for {1}").build(); + Assertions.assertEquals(ListUtil.of(null, "b", "a"), strTemplate.matchesIndexed("this is a for b", null)); + Assertions.assertEquals(ListUtil.of(null, "666", "aaa"), strTemplate.matchesIndexed("this is aaa for 666", null)); + Assertions.assertEquals(ListUtil.of(null, "b", null), strTemplate.matchesIndexed("this is for b", null)); + Assertions.assertEquals(ListUtil.of(null, null, "aaa"), strTemplate.matchesIndexed("this is aaa for ", null)); + Assertions.assertEquals(ListUtil.of(null, null, null), strTemplate.matchesIndexed("this is for ", null)); - strTemplate = StrTemplate.ofNamed("this is {2} for {1}") - .addFeatures(StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE) - .build(); - Assertions.assertEquals(ListUtil.of(null, "b", "a"), strTemplate.matchesIndexed("this is a for b", idx -> "?")); - Assertions.assertEquals(ListUtil.of(null, "666", "aaa"), strTemplate.matchesIndexed("this is aaa for 666", idx -> "?")); - Assertions.assertEquals(ListUtil.of(null, "b", "?"), strTemplate.matchesIndexed("this is for b", idx -> "?")); - Assertions.assertEquals(ListUtil.of(null, "?", "aaa"), strTemplate.matchesIndexed("this is aaa for ", idx -> "?")); - Assertions.assertEquals(ListUtil.of(null, "?", "?"), strTemplate.matchesIndexed("this is for ", idx -> "?")); + strTemplate = StrTemplate.ofNamed("this is {2} for {1}") + .addFeatures(StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE) + .build(); + Assertions.assertEquals(ListUtil.of(null, "b", "a"), strTemplate.matchesIndexed("this is a for b", idx -> "?")); + Assertions.assertEquals(ListUtil.of(null, "666", "aaa"), strTemplate.matchesIndexed("this is aaa for 666", idx -> "?")); + Assertions.assertEquals(ListUtil.of(null, "b", "?"), strTemplate.matchesIndexed("this is for b", idx -> "?")); + Assertions.assertEquals(ListUtil.of(null, "?", "aaa"), strTemplate.matchesIndexed("this is aaa for ", idx -> "?")); + Assertions.assertEquals(ListUtil.of(null, "?", "?"), strTemplate.matchesIndexed("this is for ", idx -> "?")); - strTemplate = StrTemplate.ofNamed("this is {2} for {1}").build(); - final List emptyList = Collections.emptyList(); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" ", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" \r\n \n ", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" this is a for b", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a forb", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a for b", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this are a for b", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("that is a for b", null)); + strTemplate = StrTemplate.ofNamed("this is {2} for {1}").build(); + final List emptyList = Collections.emptyList(); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("", null)); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" ", null)); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" \r\n \n ", null)); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" this is a for b", null)); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a forb", null)); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a for b", null)); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this are a for b", null)); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("that is a for b", null)); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" this is a for b", idx -> "?")); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a forb", idx -> "?")); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a for b", idx -> "?")); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this are a for b", idx -> "?")); - Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("that is a for b", idx -> "?")); - } + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed(" this is a for b", idx -> "?")); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a forb", idx -> "?")); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this is a for b", idx -> "?")); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("this are a for b", idx -> "?")); + Assertions.assertEquals(emptyList, strTemplate.matchesIndexed("that is a for b", idx -> "?")); + } - @Test - public void namedPlaceholderMatchesTest() { - NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed("this is {tableName} for {id}").build(); - Supplier> mapSupplier = HashMap::new; - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "666").build(), strTemplate.matches("this is aaa for 666", mapSupplier)); - Assertions.assertEquals(MapUtil.builder("tableName", null).put("id", "666").build(), strTemplate.matches("this is for 666", mapSupplier)); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), strTemplate.matches("this is aaa for ", mapSupplier)); - Assertions.assertEquals(MapUtil.builder("tableName", null).put("id", null).build(), strTemplate.matches("this is for ", mapSupplier)); - Assertions.assertEquals(Collections.emptyMap(), strTemplate.matches("", mapSupplier)); + @Test + public void namedPlaceholderMatchesTest() { + final NamedPlaceholderStrTemplate strTemplate = StrTemplate.ofNamed("this is {tableName} for {id}").build(); + final Supplier> mapSupplier = HashMap::new; + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "666").build(), strTemplate.matches("this is aaa for 666", mapSupplier)); + Assertions.assertEquals(MapUtil.builder("tableName", null).put("id", "666").build(), strTemplate.matches("this is for 666", mapSupplier)); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), strTemplate.matches("this is aaa for ", mapSupplier)); + Assertions.assertEquals(MapUtil.builder("tableName", null).put("id", null).build(), strTemplate.matches("this is for ", mapSupplier)); + Assertions.assertEquals(Collections.emptyMap(), strTemplate.matches("", mapSupplier)); - Supplier beanSupplier = FormatEntity::new; - Assertions.assertEquals(new FormatEntity("aaa", 666), strTemplate.matches("this is aaa for 666", beanSupplier)); - Assertions.assertEquals(new FormatEntity(null, 666), strTemplate.matches("this is for 666", beanSupplier)); - Assertions.assertEquals(new FormatEntity("aaa", null), strTemplate.matches("this is aaa for ", beanSupplier)); - Assertions.assertEquals(new FormatEntity(null, null), strTemplate.matches("this is for ", beanSupplier)); - Assertions.assertEquals(new FormatEntity(), strTemplate.matches("", beanSupplier)); - } + final Supplier beanSupplier = FormatEntity::new; + Assertions.assertEquals(new FormatEntity("aaa", 666), strTemplate.matches("this is aaa for 666", beanSupplier)); + Assertions.assertEquals(new FormatEntity(null, 666), strTemplate.matches("this is for 666", beanSupplier)); + Assertions.assertEquals(new FormatEntity("aaa", null), strTemplate.matches("this is aaa for ", beanSupplier)); + Assertions.assertEquals(new FormatEntity(null, null), strTemplate.matches("this is for ", beanSupplier)); + Assertions.assertEquals(new FormatEntity(), strTemplate.matches("", beanSupplier)); + } - @Test - public void featureTest() { - // 通常使用 - String commonTemplate = "this is {tableName} for {id}"; - // ##### 使用新的策略 替换 默认策略 ##### - NamedPlaceholderStrTemplate template = StrTemplate.ofNamed(commonTemplate) - .features(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_IGNORE_EMPTY_VALUE) - .build(); - testFeature(template); + @Test + public void featureTest() { + // 通常使用 + final String commonTemplate = "this is {tableName} for {id}"; + // ##### 使用新的策略 替换 默认策略 ##### + NamedPlaceholderStrTemplate template = StrTemplate.ofNamed(commonTemplate) + .features(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_IGNORE_EMPTY_VALUE) + .build(); + testFeature(template); - // 添加新策略,互斥的策略则算作设置新策略,旧策略失效 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_IGNORE_DEFAULT_VALUE, StrTemplate.Feature.MATCH_IGNORE_EMPTY_VALUE) - .build(); - testFeature(template); + // 添加新策略,互斥的策略则算作设置新策略,旧策略失效 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_IGNORE_DEFAULT_VALUE, StrTemplate.Feature.MATCH_IGNORE_EMPTY_VALUE) + .build(); + testFeature(template); - // ##### 删除策略 ##### - NamedPlaceholderStrTemplate template2 = StrTemplate.ofNamed(commonTemplate) - .removeFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_WHOLE_PLACEHOLDER) - .build(); - Assertions.assertEquals("this is aaa for 666", template2.format(MapUtil.builder("tableName", "aaa").put("id", "666").build())); - Assertions.assertThrows(HutoolException.class, () -> template2.format(MapUtil.builder("tableName", "aaa").build())); + // ##### 删除策略 ##### + final NamedPlaceholderStrTemplate template2 = StrTemplate.ofNamed(commonTemplate) + .removeFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_WHOLE_PLACEHOLDER) + .build(); + Assertions.assertEquals("this is aaa for 666", template2.format(MapUtil.builder("tableName", "aaa").put("id", "666").build())); + Assertions.assertThrows(HutoolException.class, () -> template2.format(MapUtil.builder("tableName", "aaa").build())); - // ##### 空字符串策略 ##### - template = StrTemplate.ofNamed(commonTemplate) - // 解析时,空字符串 转为 null值 - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_NULL) - .build(); - Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), template.matches("this is aaa for null")); + // ##### 空字符串策略 ##### + template = StrTemplate.ofNamed(commonTemplate) + // 解析时,空字符串 转为 null值 + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_NULL) + .build(); + Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), template.matches("this is aaa for null")); - // 解析时,空字符串 转为 默认值 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE) - .defaultValue("?") - .build(); - Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "?").build(), template.matches("this is aaa for ")); + // 解析时,空字符串 转为 默认值 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE) + .defaultValue("?") + .build(); + Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "?").build(), template.matches("this is aaa for ")); - // 默认值 为 空字符串,解析时,空字符串 转为 默认值 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE) - .defaultValue("") - .build(); - Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "").build(), template.matches("this is aaa for ")); + // 默认值 为 空字符串,解析时,空字符串 转为 默认值 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_EMPTY, StrTemplate.Feature.MATCH_EMPTY_VALUE_TO_DEFAULT_VALUE) + .defaultValue("") + .build(); + Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "").build(), template.matches("this is aaa for ")); - // ##### null值策略 ##### - // 解析时,null字符串 转为 null值 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_NULL, StrTemplate.Feature.MATCH_NULL_STR_TO_NULL) - .build(); - Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), template.matches("this is aaa for null")); - // 格式化时,null值 转为 默认值 ;解析时,null字符串 转为 null值 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE, StrTemplate.Feature.MATCH_NULL_STR_TO_NULL) - .defaultValue("null") - .build(); - Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), template.matches("this is aaa for null")); + // ##### null值策略 ##### + // 解析时,null字符串 转为 null值 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_NULL, StrTemplate.Feature.MATCH_NULL_STR_TO_NULL) + .build(); + Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), template.matches("this is aaa for null")); + // 格式化时,null值 转为 默认值 ;解析时,null字符串 转为 null值 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE, StrTemplate.Feature.MATCH_NULL_STR_TO_NULL) + .defaultValue("null") + .build(); + Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", null).build(), template.matches("this is aaa for null")); - // 解析时,忽略 null字符串 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_NULL, StrTemplate.Feature.MATCH_IGNORE_NULL_STR) - .build(); - Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").build(), template.matches("this is aaa for null")); - // 格式化时,null值 转为 默认值 ;解析时,忽略 null字符串 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE, StrTemplate.Feature.MATCH_IGNORE_NULL_STR) - .defaultValue("null") - .build(); - Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").build(), template.matches("this is aaa for null")); + // 解析时,忽略 null字符串 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_NULL, StrTemplate.Feature.MATCH_IGNORE_NULL_STR) + .build(); + Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").build(), template.matches("this is aaa for null")); + // 格式化时,null值 转为 默认值 ;解析时,忽略 null字符串 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_DEFAULT_VALUE, StrTemplate.Feature.MATCH_IGNORE_NULL_STR) + .defaultValue("null") + .build(); + Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").build(), template.matches("this is aaa for null")); - // 解析时,null字符串 依然为 "null"字符串 - template = StrTemplate.ofNamed(commonTemplate) - .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_NULL, StrTemplate.Feature.MATCH_KEEP_NULL_STR) - .build(); - Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "null").build(), template.matches("this is aaa for null")); - } + // 解析时,null字符串 依然为 "null"字符串 + template = StrTemplate.ofNamed(commonTemplate) + .addFeatures(StrTemplate.Feature.FORMAT_MISSING_KEY_PRINT_NULL, StrTemplate.Feature.MATCH_KEEP_NULL_STR) + .build(); + Assertions.assertEquals("this is aaa for null", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "null").build(), template.matches("this is aaa for null")); + } - private void testFeature(NamedPlaceholderStrTemplate template) { - // 格式化 - Assertions.assertEquals("this is aaa for 666", template.format(MapUtil.builder("tableName", "aaa").put("id", "666").build())); - Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); - Assertions.assertEquals("this is for 666", template.format(MapUtil.builder("id", "666").build())); - Assertions.assertEquals("this is for ", template.format(MapUtil.builder().build())); + private void testFeature(final NamedPlaceholderStrTemplate template) { + // 格式化 + Assertions.assertEquals("this is aaa for 666", template.format(MapUtil.builder("tableName", "aaa").put("id", "666").build())); + Assertions.assertEquals("this is aaa for ", template.format(MapUtil.builder("tableName", "aaa").build())); + Assertions.assertEquals("this is for 666", template.format(MapUtil.builder("id", "666").build())); + Assertions.assertEquals("this is for ", template.format(MapUtil.builder().build())); - // 解析 - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "666").build(), template.matches("this is aaa for 666")); - Assertions.assertEquals(MapUtil.builder("tableName", "aaa").build(), template.matches("this is aaa for ")); - Assertions.assertEquals(MapUtil.builder("id", "666").build(), template.matches("this is for 666")); - Assertions.assertEquals(MapUtil.builder().build(), template.matches("this is for ")); - } + // 解析 + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").put("id", "666").build(), template.matches("this is aaa for 666")); + Assertions.assertEquals(MapUtil.builder("tableName", "aaa").build(), template.matches("this is aaa for ")); + Assertions.assertEquals(MapUtil.builder("id", "666").build(), template.matches("this is for 666")); + Assertions.assertEquals(MapUtil.builder().build(), template.matches("this is for ")); + } }