diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPath.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPathOld.java
similarity index 98%
rename from hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPath.java
rename to hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPathOld.java
index 336731462..42bd9f4aa 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPath.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPathOld.java
@@ -46,7 +46,7 @@ import java.util.*;
* @author Looly
* @since 4.0.6
*/
-public class BeanPath implements Serializable {
+public class BeanPathOld implements Serializable {
private static final long serialVersionUID = 1L;
/**
@@ -79,8 +79,8 @@ public class BeanPath implements Serializable {
* @param expression 表达式
* @return BeanPath
*/
- public static BeanPath of(final String expression) {
- return new BeanPath(expression);
+ public static BeanPathOld of(final String expression) {
+ return new BeanPathOld(expression);
}
/**
@@ -88,7 +88,7 @@ public class BeanPath implements Serializable {
*
* @param expression 表达式
*/
- public BeanPath(final String expression) {
+ public BeanPathOld(final String expression) {
init(expression);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java
index 9657a85de..b0e6edb90 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java
@@ -355,7 +355,7 @@ public class BeanUtil {
* @param bean Bean对象,支持Map、List、Collection、Array
* @param expression 表达式,例如:person.friend[5].name
* @return Bean属性值,bean为{@code null}或者express为空,返回{@code null}
- * @see BeanPath#get(Object)
+ * @see BeanPathOld#get(Object)
* @since 3.0.7
*/
@SuppressWarnings("unchecked")
@@ -363,7 +363,7 @@ public class BeanUtil {
if (null == bean || StrUtil.isBlank(expression)) {
return null;
}
- return (T) BeanPath.of(expression).get(bean);
+ return (T) BeanPathOld.of(expression).get(bean);
}
/**
@@ -372,11 +372,11 @@ public class BeanUtil {
* @param bean Bean对象,支持Map、List、Collection、Array
* @param expression 表达式,例如:person.friend[5].name
* @param value 属性值
- * @see BeanPath#get(Object)
+ * @see BeanPathOld#get(Object)
* @since 4.0.6
*/
public static void setProperty(final Object bean, final String expression, final Object value) {
- BeanPath.of(expression).set(bean, value);
+ BeanPathOld.of(expression).set(bean, value);
}
// --------------------------------------------------------------------------------------------- mapToBean
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java
index ac45105bc..7e5be41ec 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java
@@ -99,7 +99,7 @@ public class DynaBean implements Cloneable, Serializable {
return (T) CollUtil.get((Collection>) bean, Integer.parseInt(fieldName));
} catch (final NumberFormatException e) {
// 非数字,see pr#254@Gitee
- return (T) CollUtil.map((Collection>) bean, (beanEle) -> BeanUtil.getFieldValue(beanEle, fieldName), false);
+ return (T) CollUtil.map((Collection>) bean, (beanEle) -> DynaBean.of(beanEle).get(fieldName), false);
}
} else {
final PropDesc prop = BeanUtil.getBeanDesc(beanClass).getProp(fieldName);
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/BeanPath.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/BeanPath.java
new file mode 100644
index 000000000..0189639ba
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/BeanPath.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path;
+
+import org.dromara.hutool.core.array.ArrayUtil;
+import org.dromara.hutool.core.bean.path.node.NameNode;
+import org.dromara.hutool.core.bean.path.node.Node;
+import org.dromara.hutool.core.bean.path.node.NodeFactory;
+import org.dromara.hutool.core.lang.Console;
+import org.dromara.hutool.core.text.CharUtil;
+import org.dromara.hutool.core.text.StrUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Bean路径表达式,用于获取多层嵌套Bean中的字段值或Bean对象
+ * 根据给定的表达式,查找Bean中对应的属性值对象。 表达式分为两种:
+ *
+ * - .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值
+ * - []表达式,可以获取集合等对象中对应index的值
+ *
+ *
+ * 表达式栗子:
+ *
+ *
+ * persion
+ * persion.name
+ * persons[3]
+ * person.friends[5].name
+ * ['person']['friends'][5]['name']
+ *
+ *
+ * @author Looly
+ * @since 6.0.0
+ */
+public class BeanPath implements Node, Iterator {
+
+ /**
+ * 表达式边界符号数组
+ */
+ private static final char[] EXP_CHARS = {CharUtil.DOT, CharUtil.BRACKET_START, CharUtil.BRACKET_END};
+
+ /**
+ * 创建Bean路径
+ *
+ * @param expression 表达式
+ * @return BeanPath
+ */
+ public static BeanPath of(final String expression) {
+ return new BeanPath(expression);
+ }
+
+ private final Node node;
+ private final String child;
+
+ /**
+ * 构造
+ *
+ * @param expression 表达式
+ */
+ public BeanPath(final String expression) {
+ final int length = expression.length();
+ final StringBuilder builder = new StringBuilder();
+
+ char c;
+ boolean isNumStart = false;// 下标标识符开始
+ boolean isInWrap = false; //标识是否在引号内
+ for (int i = 0; i < length; i++) {
+ c = expression.charAt(i);
+ if ('\'' == c) {
+ // 结束
+ isInWrap = (!isInWrap);
+ continue;
+ }
+
+ if (!isInWrap && ArrayUtil.contains(EXP_CHARS, c)) {
+ // 处理边界符号
+ if (CharUtil.BRACKET_END == c) {
+ // 中括号(数字下标)结束
+ if (!isNumStart) {
+ throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find ']' but no '[' !", expression, i));
+ }
+ isNumStart = false;
+ // 中括号结束加入下标
+ } else {
+ if (isNumStart) {
+ // 非结束中括号情况下发现起始中括号报错(中括号未关闭)
+ throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, i));
+ } else if (CharUtil.BRACKET_START == c) {
+ // 数字下标开始
+ isNumStart = true;
+ }
+ // 每一个边界符之前的表达式是一个完整的KEY,开始处理KEY
+ }
+ if (builder.length() > 0) {
+ this.node = NodeFactory.createNode(builder.toString());
+ // 如果以[结束,表示后续还有表达式,需保留'[',如name[0]
+ this.child = StrUtil.nullIfEmpty(expression.substring(c == CharUtil.BRACKET_START ? i : i + 1));
+ return;
+ }
+ } else {
+ // 非边界符号,追加字符
+ builder.append(c);
+ }
+ }
+
+ // 最后的节点
+ if (isNumStart) {
+ throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, length - 1));
+ } else {
+ this.node = NodeFactory.createNode(builder.toString());
+ this.child = null;
+ }
+ }
+
+ /**
+ * 获取节点
+ *
+ * @return 节点
+ */
+ public Node getNode() {
+ return this.node;
+ }
+
+ /**
+ * 获取子表达式
+ *
+ * @return 子表达式
+ */
+ public String getChild() {
+ return this.child;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return null != this.child;
+ }
+
+ @Override
+ public BeanPath next() {
+ return new BeanPath(this.child);
+ }
+
+ @Override
+ public Object getValue(final Object bean) {
+ Object value = this.node.getValue(bean);
+ if (hasNext()) {
+ value = next().getValue(value);
+ }
+ return value;
+ }
+
+ @Override
+ public void setValue(Object bean, final Object value) {
+ Object parentBean;
+ BeanPath beanPath = this;
+ while (beanPath.hasNext()) {
+ parentBean = bean;
+ bean = beanPath.node.getValue(bean);
+ beanPath = beanPath.next();
+ if(null == bean && beanPath.hasNext()){
+ final Node node = beanPath.node;
+ if(node instanceof NameNode){
+ bean = ((NameNode) node).isNumber() ? new ArrayList<>() : new HashMap<>();
+ }else{
+ throw new IllegalArgumentException("Invalid node to create sub bean");
+ }
+ beanPath.node.setValue(parentBean, bean);
+ }
+ }
+
+ Console.log(beanPath, bean, value);
+ beanPath.node.setValue(bean, value);
+ }
+
+ @Override
+ public String toString() {
+ return "BeanPath{" +
+ "node=" + node +
+ ", child='" + child + '\'' +
+ '}';
+ }
+}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/EmptyNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/EmptyNode.java
new file mode 100644
index 000000000..56a4296e0
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/EmptyNode.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path.node;
+
+/**
+ * 空节点
+ *
+ * @author looly
+ */
+public class EmptyNode implements Node {
+
+ /**
+ * 单例
+ */
+ public static EmptyNode INSTANCE = new EmptyNode();
+
+ @Override
+ public Object getValue(final Object bean) {
+ return null;
+ }
+
+ @Override
+ public void setValue(final Object bean, final Object value) {
+ // do nothing
+ }
+}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/ListNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/ListNode.java
new file mode 100644
index 000000000..e042e83ed
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/ListNode.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path.node;
+
+import org.dromara.hutool.core.array.ArrayUtil;
+import org.dromara.hutool.core.bean.BeanUtil;
+import org.dromara.hutool.core.collection.CollUtil;
+import org.dromara.hutool.core.convert.Convert;
+import org.dromara.hutool.core.map.MapUtil;
+import org.dromara.hutool.core.text.CharUtil;
+import org.dromara.hutool.core.text.StrUtil;
+import org.dromara.hutool.core.text.split.SplitUtil;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 列表节点
+ * [num0,num1,num2...]模式或者['key0','key1']模式
+ *
+ * @author looly
+ */
+public class ListNode implements Node{
+
+ final List names;
+
+ /**
+ * 列表节点
+ * @param expression 表达式
+ */
+ public ListNode(final String expression) {
+ this.names = SplitUtil.splitTrim(expression, StrUtil.COMMA);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object getValue(final Object bean) {
+ final List names = this.names;
+
+ if (bean instanceof Collection) {
+ return CollUtil.getAny((Collection>) bean, Convert.convert(int[].class, names));
+ } else if (ArrayUtil.isArray(bean)) {
+ return ArrayUtil.getAny(bean, Convert.convert(int[].class, names));
+ } else {
+ final String[] unWrappedNames = getUnWrappedNames(names);
+ if (bean instanceof Map) {
+ // 只支持String为key的Map
+ return MapUtil.getAny((Map) bean, unWrappedNames);
+ } else {
+ final Map map = BeanUtil.beanToMap(bean);
+ return MapUtil.getAny(map, unWrappedNames);
+ }
+ }
+ }
+
+ @Override
+ public void setValue(final Object bean, final Object value) {
+ throw new UnsupportedOperationException("Can not set value to multi names.");
+ }
+
+ @Override
+ public String toString() {
+ return this.names.toString();
+ }
+
+ /**
+ * 将列表中的name,去除单引号
+ * @param names name列表
+ * @return 处理后的name列表
+ */
+ private String[] getUnWrappedNames(final List names){
+ final String[] unWrappedNames = new String[names.size()];
+ for (int i = 0; i < unWrappedNames.length; i++) {
+ unWrappedNames[i] = StrUtil.unWrap(names.get(i), CharUtil.SINGLE_QUOTE);
+ }
+
+ return unWrappedNames;
+ }
+}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NameNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NameNode.java
new file mode 100644
index 000000000..954ed8214
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NameNode.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path.node;
+
+import org.dromara.hutool.core.bean.DynaBean;
+import org.dromara.hutool.core.math.NumberUtil;
+
+/**
+ * 处理名称节点或序号节点,如:
+ *
+ *
+ * @author looly
+ */
+public class NameNode implements Node {
+
+ private final String name;
+
+ /**
+ * 构造
+ *
+ * @param name 节点名
+ */
+ public NameNode(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * 是否为数字节点
+ *
+ * @return 是否为数字节点
+ */
+ public boolean isNumber() {
+ return NumberUtil.isInteger(name);
+ }
+
+ @Override
+ public Object getValue(final Object bean) {
+ if ("$".equals(name)) {
+ return bean;
+ }
+ return DynaBean.of(bean).get(this.name);
+ }
+
+ @Override
+ public void setValue(final Object bean, final Object value) {
+ DynaBean.of(bean).set(this.name, value);
+ }
+
+ @Override
+ public String toString() {
+ return this.name;
+ }
+}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/Node.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/Node.java
new file mode 100644
index 000000000..86581480c
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/Node.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path.node;
+
+/**
+ * Bean路径节点接口
+ *
+ * @author looly
+ */
+public interface Node {
+ /**
+ * 获取Bean对应节点的值
+ *
+ * @param bean bean对象
+ * @return 节点值
+ */
+ Object getValue(Object bean);
+
+ /**
+ * 设置节点值
+ *
+ * @param bean bean对象
+ * @param value 节点值
+ */
+ void setValue(Object bean, Object value);
+}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NodeFactory.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NodeFactory.java
new file mode 100644
index 000000000..3080262a9
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NodeFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path.node;
+
+import org.dromara.hutool.core.text.CharUtil;
+import org.dromara.hutool.core.text.StrUtil;
+
+/**
+ * 节点简单工厂
+ *
+ * @author looly
+ * @since 6.0.0
+ */
+public class NodeFactory {
+
+ /**
+ * 根据表达式创建对应的节点
+ *
+ * @param expression 表达式
+ * @return 节点
+ */
+ public static Node createNode(final String expression) {
+ if (StrUtil.isEmpty(expression)) {
+ return EmptyNode.INSTANCE;
+ }
+
+ if (StrUtil.contains(expression, CharUtil.COLON)) {
+ return new RangeNode(expression);
+ }
+
+ if (StrUtil.contains(expression, CharUtil.COMMA)) {
+ return new ListNode(expression);
+ }
+
+ return new NameNode(expression);
+ }
+}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/RangeNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/RangeNode.java
new file mode 100644
index 000000000..ed0b7d843
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/RangeNode.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path.node;
+
+import org.dromara.hutool.core.array.ArrayUtil;
+import org.dromara.hutool.core.collection.CollUtil;
+import org.dromara.hutool.core.text.StrUtil;
+import org.dromara.hutool.core.text.split.SplitUtil;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * [start:end:step] 模式节点
+ *
+ * @author looly
+ */
+public class RangeNode implements Node {
+
+ private final int start;
+ private final int end;
+ private final int step;
+
+ /**
+ * 构造
+ *
+ * @param expression 表达式
+ */
+ public RangeNode(final String expression) {
+ final List parts = SplitUtil.splitTrim(expression, StrUtil.COLON);
+ this.start = Integer.parseInt(parts.get(0));
+ this.end = Integer.parseInt(parts.get(1));
+ int step = 1;
+ if (3 == parts.size()) {
+ step = Integer.parseInt(parts.get(2));
+ }
+ this.step = step;
+ }
+
+ @Override
+ public Object getValue(final Object bean) {
+ if (bean instanceof Collection) {
+ return CollUtil.sub((Collection>) bean, this.start, this.end, this.step);
+ } else if (ArrayUtil.isArray(bean)) {
+ return ArrayUtil.sub(bean, this.start, this.end, this.step);
+ }
+
+ throw new UnsupportedOperationException("Can not get range value for: " + bean.getClass());
+ }
+
+ @Override
+ public void setValue(final Object bean, final Object value) {
+ throw new UnsupportedOperationException("Can not set value with step name.");
+ }
+
+ @Override
+ public String toString() {
+ return StrUtil.format("[{}:{}:{}]", this.start, this.end, this.step);
+ }
+}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/package-info.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/package-info.java
new file mode 100644
index 000000000..a6ab876d2
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+/**
+ * Bean路径节点
+ *
+ * @author looly
+ */
+package org.dromara.hutool.core.bean.path.node;
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/package-info.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/package-info.java
new file mode 100644
index 000000000..4e76b0066
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+/**
+ * Bean路径,通过路径表达式查找或设置对象或子对象中的值
+ *
+ * @author looly
+ * @since 6.0.0
+ */
+package org.dromara.hutool.core.bean.path;
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java
index 2471f06eb..b0c7cdc1d 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java
@@ -12,7 +12,7 @@
package org.dromara.hutool.core.map;
-import org.dromara.hutool.core.bean.BeanPath;
+import org.dromara.hutool.core.bean.BeanPathOld;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.bean.copier.CopyOptions;
import org.dromara.hutool.core.collection.set.SetUtil;
@@ -423,12 +423,12 @@ public class Dict extends CustomKeyMap implements TypeGetter 目标类型
* @param expression 表达式
* @return 对象
- * @see BeanPath#get(Object)
+ * @see BeanPathOld#get(Object)
* @since 5.7.14
*/
@SuppressWarnings("unchecked")
public T getByPath(final String expression) {
- return (T) BeanPath.of(expression).get(this);
+ return (T) BeanPathOld.of(expression).get(this);
}
/**
@@ -453,7 +453,7 @@ public class Dict extends CustomKeyMap implements TypeGetter T getByPath(final String expression, final Type resultType) {
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrTemplate.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrTemplate.java
index ff5613ec1..aefb1537f 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrTemplate.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrTemplate.java
@@ -69,7 +69,7 @@ public abstract class StrTemplate {
* @param template 字符串模板
* @return 单占位符 模板对象的 Builder
*/
- public static SinglePlaceholderStrTemplate.Builder of(String template) {
+ public static SinglePlaceholderStrTemplate.Builder of(final String template) {
return SinglePlaceholderStrTemplate.builder(template);
}
@@ -80,7 +80,7 @@ public abstract class StrTemplate {
* @param template 字符串模板
* @return 有前缀和后缀的占位符模板对象的 Builder
*/
- public static NamedPlaceholderStrTemplate.Builder ofNamed(String template) {
+ public static NamedPlaceholderStrTemplate.Builder ofNamed(final String template) {
return NamedPlaceholderStrTemplate.builder(template);
}
@@ -192,7 +192,7 @@ public abstract class StrTemplate {
int startIdx = 0, findIdx;
boolean hasPlaceholder = false;
String text;
- for (StrTemplateSegment segment : segments) {
+ for (final StrTemplateSegment segment : segments) {
if (segment instanceof LiteralSegment) {
text = segment.getText();
findIdx = str.indexOf(text, startIdx);
@@ -274,7 +274,7 @@ public abstract class StrTemplate {
int totalTextLength = this.fixedTextTotalLength;
String valueStr;
- for (AbstractPlaceholderSegment segment : placeholderSegments) {
+ for (final AbstractPlaceholderSegment segment : placeholderSegments) {
// 根据 占位符 返回 需要序列化的值
valueStr = valueSupplier.apply(segment);
if (valueStr == null) {
@@ -287,7 +287,7 @@ public abstract class StrTemplate {
final StringBuilder sb = new StringBuilder(totalTextLength);
int index = 0;
// 构造格式化结果字符串
- for (StrTemplateSegment segment : segments) {
+ for (final StrTemplateSegment segment : segments) {
if (segment instanceof LiteralSegment) {
sb.append(segment.getText());
}
@@ -331,7 +331,7 @@ public abstract class StrTemplate {
protected String formatBySegment(final Function valueSupplier) {
return formatRawBySegment(segment -> {
// 根据 占位符 返回 需要序列化的值
- Object value = valueSupplier.apply(segment);
+ final Object value = valueSupplier.apply(segment);
if (value != null) {
if (value instanceof String) {
return (String) value;
@@ -428,7 +428,7 @@ public abstract class StrTemplate {
int startIdx = 0, findIdx;
AbstractPlaceholderSegment placeholderSegment = null;
String text;
- for (StrTemplateSegment segment : segments) {
+ for (final StrTemplateSegment segment : segments) {
if (segment instanceof LiteralSegment) {
text = segment.getText();
// 查找固定文本
@@ -616,7 +616,7 @@ public abstract class StrTemplate {
// 计算 固定文本segment 的 数量 和 文本总长度
int literalSegmentSize = 0, fixedTextTotalLength = 0;
- for (StrTemplateSegment segment : this.segments) {
+ for (final StrTemplateSegment segment : this.segments) {
if (segment instanceof LiteralSegment) {
++literalSegmentSize;
fixedTextTotalLength += segment.getText().length();
@@ -630,7 +630,7 @@ public abstract class StrTemplate {
this.placeholderSegments = Collections.emptyList();
} else {
final List placeholderSegments = new ArrayList<>(placeholderSegmentsSize);
- for (StrTemplateSegment segment : segments) {
+ for (final StrTemplateSegment segment : segments) {
if (segment instanceof AbstractPlaceholderSegment) {
placeholderSegments.add((AbstractPlaceholderSegment) segment);
}
@@ -646,14 +646,14 @@ public abstract class StrTemplate {
* @param list 已保存的segment列表
* @param newText 新的固定文本
*/
- protected void addLiteralSegment(boolean isLastLiteralSegment, List list, String newText) {
+ protected void addLiteralSegment(final boolean isLastLiteralSegment, final List list, final String newText) {
if (newText.isEmpty()) {
return;
}
if (isLastLiteralSegment) {
// 最后的固定文本segment 和 新固定文本 合并为一个
- int lastIdx = list.size() - 1;
- StrTemplateSegment lastLiteralSegment = list.get(lastIdx);
+ final int lastIdx = list.size() - 1;
+ final StrTemplateSegment lastLiteralSegment = list.get(lastIdx);
list.set(lastIdx, new LiteralSegment(lastLiteralSegment.getText() + newText));
} else {
list.add(new LiteralSegment(newText));
@@ -756,7 +756,7 @@ public abstract class StrTemplate {
*/
public BuilderChild addFeatures(final Feature... appendFeatures) {
if (ArrayUtil.isNotEmpty(appendFeatures)) {
- for (Feature feature : appendFeatures) {
+ for (final Feature feature : appendFeatures) {
this.features = feature.set(this.features);
}
}
@@ -772,7 +772,7 @@ public abstract class StrTemplate {
*/
public BuilderChild removeFeatures(final Feature... removeFeatures) {
if (ArrayUtil.isNotEmpty(removeFeatures)) {
- for (Feature feature : removeFeatures) {
+ for (final Feature feature : removeFeatures) {
this.features = feature.clear(this.features);
}
}
@@ -978,7 +978,7 @@ public abstract class StrTemplate {
* @param bitStart 同组第一个策略的掩码位数
* @param bitLen 同组策略数量
*/
- Feature(int bitPos, int bitStart, int bitLen) {
+ Feature(final int bitPos, final int bitStart, final int bitLen) {
this.mask = 1 << bitPos;
this.clearMask = (-1 << (bitStart + bitLen)) | ((1 << bitStart) - 1);
}
@@ -989,7 +989,7 @@ public abstract class StrTemplate {
* @param features 外部的策略值
* @return 是否为当前策略
*/
- public boolean contains(int features) {
+ public boolean contains(final int features) {
return (features & mask) != 0;
}
@@ -999,7 +999,7 @@ public abstract class StrTemplate {
* @param features 外部的策略值
* @return 添加后的策略值
*/
- public int set(int features) {
+ public int set(final int features) {
return (features & clearMask) | mask;
}
@@ -1009,7 +1009,7 @@ public abstract class StrTemplate {
* @param features 外部的策略值
* @return 移除后的策略值
*/
- public int clear(int features) {
+ public int clear(final int features) {
return (features & clearMask);
}
@@ -1019,13 +1019,13 @@ public abstract class StrTemplate {
* @param features 策略枚举数组
* @return 总的策略值
*/
- public static int of(Feature... features) {
+ public static int of(final Feature... features) {
if (features == null) {
return 0;
}
int value = 0;
- for (Feature feature : features) {
+ for (final Feature feature : features) {
value = feature.set(value);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/segment/package-info.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/segment/package-info.java
new file mode 100644
index 000000000..81cc4bbea
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/segment/package-info.java
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+/**
+ * 占位符节点
+ */
+package org.dromara.hutool.core.text.placeholder.segment;
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 f167b1d61..75d780c10 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
@@ -76,7 +76,7 @@ public class NamedPlaceholderStrTemplate extends StrTemplate {
// 记录 下标占位符 最大的 下标值
if (!placeholderSegments.isEmpty()) {
- for (AbstractPlaceholderSegment segment : placeholderSegments) {
+ for (final AbstractPlaceholderSegment segment : placeholderSegments) {
if (segment instanceof IndexedPlaceholderSegment) {
this.indexedSegmentMaxIdx = Math.max(this.indexedSegmentMaxIdx, ((IndexedPlaceholderSegment) segment).getIndex());
}
@@ -95,7 +95,7 @@ public class NamedPlaceholderStrTemplate extends StrTemplate {
final int openLength = prefix.length();
final int closeLength = suffix.length();
- List segments = new ArrayList<>();
+ final List segments = new ArrayList<>();
int closeCursor = 0;
// 开始匹配
final char[] src = template.toCharArray();
@@ -299,7 +299,7 @@ public class NamedPlaceholderStrTemplate extends StrTemplate {
* @param missingIndexHandler 集合中不存在下标位置时的处理器,根据 下标 返回 代替值
* @return 格式化字符串
*/
- public String formatIndexed(final Collection> collection, IntFunction missingIndexHandler) {
+ public String formatIndexed(final Collection> collection, final IntFunction missingIndexHandler) {
if (collection == null) {
return getTemplate();
}
@@ -579,6 +579,9 @@ public class NamedPlaceholderStrTemplate extends StrTemplate {
return new Builder(template);
}
+ /**
+ * 构造器
+ */
public static class Builder extends AbstractBuilder {
/**
* 占位符前缀,默认为 {@link NamedPlaceholderStrTemplate#DEFAULT_PREFIX}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/SinglePlaceholderStrTemplate.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/SinglePlaceholderStrTemplate.java
index e3b112140..bb5b11f89 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/SinglePlaceholderStrTemplate.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/SinglePlaceholderStrTemplate.java
@@ -34,196 +34,199 @@ import java.util.function.UnaryOperator;
* @since 6.0.0
*/
public class SinglePlaceholderStrTemplate extends StrTemplate {
- /**
- * 默认的占位符
- */
- public static final String DEFAULT_PLACEHOLDER = StrPool.EMPTY_JSON;
+ /**
+ * 默认的占位符
+ */
+ public static final String DEFAULT_PLACEHOLDER = StrPool.EMPTY_JSON;
- /**
- * 占位符,默认为: {@link StrPool#EMPTY_JSON}
- */
- protected String placeholder;
+ /**
+ * 占位符,默认为: {@link StrPool#EMPTY_JSON}
+ */
+ protected String placeholder;
- protected SinglePlaceholderStrTemplate(final String template, final int features, final String placeholder, final char escape,
- final String defaultValue, final UnaryOperator defaultValueHandler) {
- super(template, escape, defaultValue, defaultValueHandler, features);
+ protected SinglePlaceholderStrTemplate(final String template, final int features, final String placeholder, final char escape,
+ final String defaultValue, final UnaryOperator defaultValueHandler) {
+ super(template, escape, defaultValue, defaultValueHandler, features);
- Assert.notEmpty(placeholder);
- this.placeholder = placeholder;
+ Assert.notEmpty(placeholder);
+ this.placeholder = placeholder;
- // 初始化Segment列表
- afterInit();
- }
+ // 初始化Segment列表
+ afterInit();
+ }
- @Override
- protected List parseSegments(final String template) {
- final int placeholderLength = placeholder.length();
- final int strPatternLength = template.length();
- // 记录已经处理到的位置
- int handledPosition = 0;
- // 占位符所在位置
- int delimIndex;
- // 上一个解析的segment是否是固定文本,如果是,则需要和当前新的文本部分合并
- boolean lastIsLiteralSegment = false;
- // 复用的占位符变量
- final SinglePlaceholderSegment singlePlaceholderSegment = SinglePlaceholderSegment.newInstance(placeholder);
- List segments = null;
- while (true) {
- delimIndex = template.indexOf(placeholder, handledPosition);
- if (delimIndex == -1) {
- // 整个模板都不带占位符
- if (handledPosition == 0) {
- return Collections.singletonList(new LiteralSegment(template));
- }
- // 字符串模板剩余部分不再包含占位符
- if (handledPosition < strPatternLength) {
- addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition));
- }
- return segments;
- } else if (segments == null) {
- segments = new ArrayList<>();
- }
+ @Override
+ protected List parseSegments(final String template) {
+ final int placeholderLength = placeholder.length();
+ final int strPatternLength = template.length();
+ // 记录已经处理到的位置
+ int handledPosition = 0;
+ // 占位符所在位置
+ int delimIndex;
+ // 上一个解析的segment是否是固定文本,如果是,则需要和当前新的文本部分合并
+ boolean lastIsLiteralSegment = false;
+ // 复用的占位符变量
+ final SinglePlaceholderSegment singlePlaceholderSegment = SinglePlaceholderSegment.newInstance(placeholder);
+ List segments = null;
+ while (true) {
+ delimIndex = template.indexOf(placeholder, handledPosition);
+ if (delimIndex == -1) {
+ // 整个模板都不带占位符
+ if (handledPosition == 0) {
+ return Collections.singletonList(new LiteralSegment(template));
+ }
+ // 字符串模板剩余部分不再包含占位符
+ if (handledPosition < strPatternLength) {
+ addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition));
+ }
+ return segments;
+ } else if (segments == null) {
+ segments = new ArrayList<>();
+ }
- // 存在 转义符
- if (delimIndex > 0 && template.charAt(delimIndex - 1) == escape) {
- // 存在 双转义符
- if (delimIndex > 1 && template.charAt(delimIndex - 2) == escape) {
- // 转义符之前还有一个转义符,形如:"//{",占位符依旧有效
- addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition, delimIndex - 1));
- segments.add(singlePlaceholderSegment);
- lastIsLiteralSegment = false;
- handledPosition = delimIndex + placeholderLength;
- } else {
- // 占位符被转义,形如:"/{",当前字符并不是一个真正的占位符,而是普通字符串的一部分
- addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition, delimIndex - 1) + placeholder.charAt(0));
- lastIsLiteralSegment = true;
- handledPosition = delimIndex + 1;
- }
- } else {
- // 正常占位符
- addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition, delimIndex));
- segments.add(singlePlaceholderSegment);
- lastIsLiteralSegment = false;
- handledPosition = delimIndex + placeholderLength;
- }
- }
- }
- // region 格式化方法
- // ################################################## 格式化方法 ##################################################
+ // 存在 转义符
+ if (delimIndex > 0 && template.charAt(delimIndex - 1) == escape) {
+ // 存在 双转义符
+ if (delimIndex > 1 && template.charAt(delimIndex - 2) == escape) {
+ // 转义符之前还有一个转义符,形如:"//{",占位符依旧有效
+ addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition, delimIndex - 1));
+ segments.add(singlePlaceholderSegment);
+ lastIsLiteralSegment = false;
+ handledPosition = delimIndex + placeholderLength;
+ } else {
+ // 占位符被转义,形如:"/{",当前字符并不是一个真正的占位符,而是普通字符串的一部分
+ addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition, delimIndex - 1) + placeholder.charAt(0));
+ lastIsLiteralSegment = true;
+ handledPosition = delimIndex + 1;
+ }
+ } else {
+ // 正常占位符
+ addLiteralSegment(lastIsLiteralSegment, segments, template.substring(handledPosition, delimIndex));
+ segments.add(singlePlaceholderSegment);
+ lastIsLiteralSegment = false;
+ handledPosition = delimIndex + placeholderLength;
+ }
+ }
+ }
+ // region 格式化方法
+ // ################################################## 格式化方法 ##################################################
- /**
- * 按顺序使用 数组元素 替换 占位符
- *
- * @param args 可变参数
- * @return 格式化字符串
- */
- public String format(final Object... args) {
- return formatArray(args);
- }
+ /**
+ * 按顺序使用 数组元素 替换 占位符
+ *
+ * @param args 可变参数
+ * @return 格式化字符串
+ */
+ public String format(final Object... args) {
+ return formatArray(args);
+ }
- /**
- * 按顺序使用 原始数组元素 替换 占位符
- *
- * @param array 原始类型数组,例如: {@code int[]}
- * @return 格式化字符串
- */
- public String formatArray(final Object array) {
- return formatArray(ArrayUtil.wrap(array));
- }
+ /**
+ * 按顺序使用 原始数组元素 替换 占位符
+ *
+ * @param array 原始类型数组,例如: {@code int[]}
+ * @return 格式化字符串
+ */
+ public String formatArray(final Object array) {
+ return formatArray(ArrayUtil.wrap(array));
+ }
- /**
- * 按顺序使用 数组元素 替换 占位符
- *
- * @param array 数组
- * @return 格式化字符串
- */
- public String formatArray(final Object[] array) {
- if (array == null) {
- return getTemplate();
- }
- return format(Arrays.asList(array));
- }
+ /**
+ * 按顺序使用 数组元素 替换 占位符
+ *
+ * @param array 数组
+ * @return 格式化字符串
+ */
+ public String formatArray(final Object[] array) {
+ if (array == null) {
+ return getTemplate();
+ }
+ return format(Arrays.asList(array));
+ }
- /**
- * 按顺序使用 迭代器元素 替换 占位符
- *
- * @param iterable iterable
- * @return 格式化字符串
- */
- public String format(final Iterable> iterable) {
- return super.formatSequence(iterable);
- }
- // endregion
+ /**
+ * 按顺序使用 迭代器元素 替换 占位符
+ *
+ * @param iterable iterable
+ * @return 格式化字符串
+ */
+ public String format(final Iterable> iterable) {
+ return super.formatSequence(iterable);
+ }
+ // endregion
- // region 解析方法
- // ################################################## 解析方法 ##################################################
+ // region 解析方法
+ // ################################################## 解析方法 ##################################################
- /**
- * 将 占位符位置的值 按顺序解析为 字符串数组
- *
- * @param str 待解析的字符串,一般是格式化方法的返回值
- * @return 参数值数组
- */
- public String[] matchesToArray(final String str) {
- return matches(str).toArray(new String[0]);
- }
+ /**
+ * 将 占位符位置的值 按顺序解析为 字符串数组
+ *
+ * @param str 待解析的字符串,一般是格式化方法的返回值
+ * @return 参数值数组
+ */
+ public String[] matchesToArray(final String str) {
+ return matches(str).toArray(new String[0]);
+ }
- /**
- * 将 占位符位置的值 按顺序解析为 字符串列表
- *
- * @param str 待解析的字符串,一般是格式化方法的返回值
- * @return 参数值列表
- */
- public List matches(final String str) {
- return super.matchesSequence(str);
- }
- // endregion
+ /**
+ * 将 占位符位置的值 按顺序解析为 字符串列表
+ *
+ * @param str 待解析的字符串,一般是格式化方法的返回值
+ * @return 参数值列表
+ */
+ public List matches(final String str) {
+ return super.matchesSequence(str);
+ }
+ // 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 SinglePlaceholderStrTemplate#DEFAULT_PLACEHOLDER}
- */
- protected String placeholder;
+ /**
+ * 构造器
+ */
+ public static class Builder extends AbstractBuilder {
+ /**
+ * 单占位符
+ * 例如:"?"、"{}"
+ * 默认为 {@link SinglePlaceholderStrTemplate#DEFAULT_PLACEHOLDER}
+ */
+ protected String placeholder;
- protected Builder(final String template) {
- super(template);
- }
+ protected Builder(final String template) {
+ super(template);
+ }
- /**
- * 设置 占位符
- *
- * @param placeholder 占位符,不能为 {@code null} 和 {@code ""}
- * @return builder
- */
- public Builder placeholder(final String placeholder) {
- this.placeholder = placeholder;
- return this;
- }
+ /**
+ * 设置 占位符
+ *
+ * @param placeholder 占位符,不能为 {@code null} 和 {@code ""}
+ * @return builder
+ */
+ public Builder placeholder(final String placeholder) {
+ this.placeholder = placeholder;
+ return this;
+ }
- @Override
- protected SinglePlaceholderStrTemplate buildInstance() {
- if (this.placeholder == null) {
- this.placeholder = DEFAULT_PLACEHOLDER;
- }
- return new SinglePlaceholderStrTemplate(this.template, this.features, this.placeholder, this.escape,
- this.defaultValue, this.defaultValueHandler);
- }
+ @Override
+ protected SinglePlaceholderStrTemplate buildInstance() {
+ if (this.placeholder == null) {
+ this.placeholder = DEFAULT_PLACEHOLDER;
+ }
+ return new SinglePlaceholderStrTemplate(this.template, this.features, this.placeholder, this.escape,
+ this.defaultValue, this.defaultValueHandler);
+ }
- @Override
- protected Builder self() {
- return this;
- }
- }
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/package-info.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/package-info.java
new file mode 100644
index 000000000..f592a5bb6
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/template/package-info.java
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+/**
+ * 字符串模板
+ */
+package org.dromara.hutool.core.text.placeholder.template;
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanPathTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanPathTest.java
index 9d28e7733..668c3cdc9 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanPathTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanPathTest.java
@@ -27,7 +27,7 @@ import java.util.List;
import java.util.Map;
/**
- * {@link BeanPath} 单元测试
+ * {@link BeanPathOld} 单元测试
*
* @author looly
*
@@ -73,7 +73,7 @@ public class BeanPathTest {
@Test
public void beanPathTest1() {
- final BeanPath pattern = new BeanPath("userInfo.examInfoDict[0].id");
+ final BeanPathOld pattern = new BeanPathOld("userInfo.examInfoDict[0].id");
Assertions.assertEquals("userInfo", pattern.patternParts.get(0));
Assertions.assertEquals("examInfoDict", pattern.patternParts.get(1));
Assertions.assertEquals("0", pattern.patternParts.get(2));
@@ -83,7 +83,7 @@ public class BeanPathTest {
@Test
public void beanPathTest2() {
- final BeanPath pattern = new BeanPath("[userInfo][examInfoDict][0][id]");
+ final BeanPathOld pattern = new BeanPathOld("[userInfo][examInfoDict][0][id]");
Assertions.assertEquals("userInfo", pattern.patternParts.get(0));
Assertions.assertEquals("examInfoDict", pattern.patternParts.get(1));
Assertions.assertEquals("0", pattern.patternParts.get(2));
@@ -92,7 +92,7 @@ public class BeanPathTest {
@Test
public void beanPathTest3() {
- final BeanPath pattern = new BeanPath("['userInfo']['examInfoDict'][0]['id']");
+ final BeanPathOld pattern = new BeanPathOld("['userInfo']['examInfoDict'][0]['id']");
Assertions.assertEquals("userInfo", pattern.patternParts.get(0));
Assertions.assertEquals("examInfoDict", pattern.patternParts.get(1));
Assertions.assertEquals("0", pattern.patternParts.get(2));
@@ -101,14 +101,14 @@ public class BeanPathTest {
@Test
public void getTest() {
- final BeanPath pattern = BeanPath.of("userInfo.examInfoDict[0].id");
+ final BeanPathOld pattern = BeanPathOld.of("userInfo.examInfoDict[0].id");
final Object result = pattern.get(tempMap);
Assertions.assertEquals(1, result);
}
@Test
public void setTest() {
- final BeanPath pattern = BeanPath.of("userInfo.examInfoDict[0].id");
+ final BeanPathOld pattern = BeanPathOld.of("userInfo.examInfoDict[0].id");
pattern.set(tempMap, 2);
final Object result = pattern.get(tempMap);
Assertions.assertEquals(2, result);
@@ -116,7 +116,7 @@ public class BeanPathTest {
@Test
public void getMapTest () {
- final BeanPath pattern = BeanPath.of("userInfo[id, photoPath]");
+ final BeanPathOld pattern = BeanPathOld.of("userInfo[id, photoPath]");
@SuppressWarnings("unchecked")
final Map result = (Map)pattern.get(tempMap);
Assertions.assertEquals(1, result.get("id"));
@@ -129,13 +129,13 @@ public class BeanPathTest {
dataMap.put("aa", "value0");
dataMap.put("aa.bb.cc", "value111111");// key 是类名 格式 带 ' . '
- final BeanPath pattern = BeanPath.of("'aa.bb.cc'");
+ final BeanPathOld pattern = BeanPathOld.of("'aa.bb.cc'");
Assertions.assertEquals("value111111", pattern.get(dataMap));
}
@Test
public void compileTest(){
- final BeanPath of = BeanPath.of("'abc.dd'.ee.ff'.'");
+ final BeanPathOld of = BeanPathOld.of("'abc.dd'.ee.ff'.'");
Assertions.assertEquals("abc.dd", of.getPatternParts().get(0));
Assertions.assertEquals("ee", of.getPatternParts().get(1));
Assertions.assertEquals("ff.", of.getPatternParts().get(2));
@@ -145,17 +145,17 @@ public class BeanPathTest {
public void issue2362Test() {
final Map map = new HashMap<>();
- BeanPath beanPath = BeanPath.of("list[0].name");
+ BeanPathOld beanPath = BeanPathOld.of("list[0].name");
beanPath.set(map, "张三");
Assertions.assertEquals("{list=[{name=张三}]}", map.toString());
map.clear();
- beanPath = BeanPath.of("list[1].name");
+ beanPath = BeanPathOld.of("list[1].name");
beanPath.set(map, "张三");
Assertions.assertEquals("{list=[null, {name=张三}]}", map.toString());
map.clear();
- beanPath = BeanPath.of("list[0].1.name");
+ beanPath = BeanPathOld.of("list[0].1.name");
beanPath.set(map, "张三");
Assertions.assertEquals("{list=[[null, {name=张三}]]}", map.toString());
}
@@ -164,7 +164,7 @@ public class BeanPathTest {
public void putTest() {
final Map map = new HashMap<>();
- BeanPath beanPath = BeanPath.of("list[1].name");
+ final BeanPathOld beanPath = BeanPathOld.of("list[1].name");
beanPath.set(map, "张三");
Assertions.assertEquals("{list=[null, {name=张三}]}", map.toString());
}
@@ -172,7 +172,7 @@ public class BeanPathTest {
@Test
public void putByPathTest() {
final Dict dict = new Dict();
- BeanPath.of("aa.bb").set(dict, "BB");
+ BeanPathOld.of("aa.bb").set(dict, "BB");
Assertions.assertEquals("{aa={bb=BB}}", dict.toString());
}
@@ -180,9 +180,9 @@ public class BeanPathTest {
public void appendArrayTest(){
// issue#3008@Github
final MyUser myUser = new MyUser();
- BeanPath.of("hobby[0]").set(myUser, "LOL");
- BeanPath.of("hobby[1]").set(myUser, "KFC");
- BeanPath.of("hobby[2]").set(myUser, "COFFE");
+ BeanPathOld.of("hobby[0]").set(myUser, "LOL");
+ BeanPathOld.of("hobby[1]").set(myUser, "KFC");
+ BeanPathOld.of("hobby[2]").set(myUser, "COFFE");
Assertions.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getHobby()));
}
@@ -191,9 +191,9 @@ public class BeanPathTest {
public void appendArrayTest2(){
// issue#3008@Github
final MyUser2 myUser = new MyUser2();
- BeanPath.of("myUser.hobby[0]").set(myUser, "LOL");
- BeanPath.of("myUser.hobby[1]").set(myUser, "KFC");
- BeanPath.of("myUser.hobby[2]").set(myUser, "COFFE");
+ BeanPathOld.of("myUser.hobby[0]").set(myUser, "LOL");
+ BeanPathOld.of("myUser.hobby[1]").set(myUser, "KFC");
+ BeanPathOld.of("myUser.hobby[2]").set(myUser, "COFFE");
Assertions.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getMyUser().getHobby()));
}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java
index c7f38aa03..88b405f42 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java
@@ -767,7 +767,7 @@ public class BeanUtilTest {
testPojo.setTestPojo2List(new TestPojo2[]{testPojo2, testPojo3});
- final BeanPath beanPath = BeanPath.of("testPojo2List.age");
+ final BeanPathOld beanPath = BeanPathOld.of("testPojo2List.age");
final Object o = beanPath.get(testPojo);
Assertions.assertEquals(Integer.valueOf(2), ArrayUtil.get(o, 0));
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathGetOrSetValueTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathGetOrSetValueTest.java
new file mode 100644
index 000000000..26d16d9e9
--- /dev/null
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathGetOrSetValueTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path;
+
+import org.dromara.hutool.core.bean.BeanPathOld;
+import org.dromara.hutool.core.lang.test.bean.ExamInfoDict;
+import org.dromara.hutool.core.lang.test.bean.UserInfoDict;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class BeanPathGetOrSetValueTest {
+ Map tempMap;
+
+ @BeforeEach
+ public void init() {
+ // ------------------------------------------------- 考试信息列表
+ final ExamInfoDict examInfoDict = new ExamInfoDict();
+ examInfoDict.setId(1);
+ examInfoDict.setExamType(0);
+ examInfoDict.setAnswerIs(1);
+
+ final ExamInfoDict examInfoDict1 = new ExamInfoDict();
+ examInfoDict1.setId(2);
+ examInfoDict1.setExamType(0);
+ examInfoDict1.setAnswerIs(0);
+
+ final ExamInfoDict examInfoDict2 = new ExamInfoDict();
+ examInfoDict2.setId(3);
+ examInfoDict2.setExamType(1);
+ examInfoDict2.setAnswerIs(0);
+
+ final List examInfoDicts = new ArrayList<>();
+ examInfoDicts.add(examInfoDict);
+ examInfoDicts.add(examInfoDict1);
+ examInfoDicts.add(examInfoDict2);
+
+ // ------------------------------------------------- 用户信息
+ final UserInfoDict userInfoDict = new UserInfoDict();
+ userInfoDict.setId(1);
+ userInfoDict.setPhotoPath("yx.mm.com");
+ userInfoDict.setRealName("张三");
+ userInfoDict.setExamInfoDict(examInfoDicts);
+
+ tempMap = new HashMap<>();
+ tempMap.put("userInfo", userInfoDict);
+ tempMap.put("flag", 1);
+ }
+
+ @Test
+ public void getValueTest() {
+ final BeanPath pattern = new BeanPath("$.userInfo.examInfoDict[0].id");
+ final Object result = pattern.getValue(tempMap);
+ Assertions.assertEquals(1, result);
+ }
+
+ @Test
+ public void setValueTest() {
+ final BeanPath pattern = new BeanPath("userInfo.examInfoDict[0].id");
+ pattern.setValue(tempMap, 2);
+ final Object result = pattern.getValue(tempMap);
+ Assertions.assertEquals(2, result);
+ }
+
+ @Test
+ public void getMapTest () {
+ final BeanPath pattern = new BeanPath("userInfo[id, photoPath]");
+ @SuppressWarnings("unchecked")
+ final Map result = (Map)pattern.getValue(tempMap);
+ Assertions.assertEquals(1, result.get("id"));
+ Assertions.assertEquals("yx.mm.com", result.get("photoPath"));
+ }
+
+ @Test
+ public void getKeyWithDotTest () {
+ final Map dataMap = new HashMap<>(16);
+ dataMap.put("aa", "value0");
+ dataMap.put("aa.bb.cc", "value111111");// key 是类名 格式 带 ' . '
+
+ final BeanPath pattern = new BeanPath("'aa.bb.cc'");
+ Assertions.assertEquals("value111111", pattern.getValue(dataMap));
+ }
+
+ @Test
+ public void issue2362Test() {
+ final Map map = new HashMap<>();
+
+ BeanPath beanPath = BeanPath.of("list[0].name");
+ beanPath.setValue(map, "张三");
+ Assertions.assertEquals("{list=[{name=张三}]}", map.toString());
+
+ map.clear();
+ beanPath = BeanPath.of("list[1].name");
+ beanPath.setValue(map, "张三");
+ Assertions.assertEquals("{list=[null, {name=张三}]}", map.toString());
+
+ map.clear();
+ beanPath = BeanPath.of("list[0].1.name");
+ beanPath.setValue(map, "张三");
+ Assertions.assertEquals("{list=[[null, {name=张三}]]}", map.toString());
+ }
+}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathTest.java
new file mode 100644
index 000000000..fca57a7ef
--- /dev/null
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2023. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.bean.path;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class BeanPathTest {
+
+ @Test
+ void parseDotTest() {
+ BeanPath beanPath = new BeanPath("userInfo.examInfoDict[0].id");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("examInfoDict[0].id", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("examInfoDict", beanPath.getNode().toString());
+ Assertions.assertEquals("[0].id", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("0", beanPath.getNode().toString());
+ Assertions.assertEquals(".id", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("id", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void parseDotWithQuoteTest() {
+ BeanPath beanPath = new BeanPath("'userInfo'.examInfoDict[0].'id'");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("examInfoDict[0].'id'", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("examInfoDict", beanPath.getNode().toString());
+ Assertions.assertEquals("[0].'id'", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("0", beanPath.getNode().toString());
+ Assertions.assertEquals(".'id'", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("id", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void parseDotWithQuoteTest2() {
+ BeanPath beanPath = new BeanPath("userInfo.'examInfoDict'[0].id");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("'examInfoDict'[0].id", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("examInfoDict", beanPath.getNode().toString());
+ Assertions.assertEquals("[0].id", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("0", beanPath.getNode().toString());
+ Assertions.assertEquals(".id", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("id", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void parseBucketTest() {
+ BeanPath beanPath = new BeanPath("[userInfo][examInfoDict][0][id]");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("[examInfoDict][0][id]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("examInfoDict", beanPath.getNode().toString());
+ Assertions.assertEquals("[0][id]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("0", beanPath.getNode().toString());
+ Assertions.assertEquals("[id]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("id", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void parseBucketWithQuoteTest() {
+ BeanPath beanPath = new BeanPath("['userInfo']['examInfoDict'][0][id]");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("['examInfoDict'][0][id]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("examInfoDict", beanPath.getNode().toString());
+ Assertions.assertEquals("[0][id]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("0", beanPath.getNode().toString());
+ Assertions.assertEquals("[id]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("id", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void parseBucketWithQuoteTest2() {
+ BeanPath beanPath = new BeanPath("[userInfo][examInfoDict][0]['id']");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("[examInfoDict][0]['id']", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("examInfoDict", beanPath.getNode().toString());
+ Assertions.assertEquals("[0]['id']", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("0", beanPath.getNode().toString());
+ Assertions.assertEquals("['id']", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("id", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void rangePathTest() {
+ BeanPath beanPath = new BeanPath("[userInfo][2:3]");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("[2:3]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("[2:3:1]", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void listPathTest() {
+ BeanPath beanPath = new BeanPath("[userInfo][1,2,3]");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("[1,2,3]", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("[1, 2, 3]", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+
+ @Test
+ void listKeysPathTest() {
+ BeanPath beanPath = new BeanPath("[userInfo]['a', 'b', 'c']");
+ Assertions.assertEquals("userInfo", beanPath.getNode().toString());
+ Assertions.assertEquals("['a', 'b', 'c']", beanPath.getChild());
+
+ beanPath = beanPath.next();
+ Assertions.assertEquals("[a, b, c]", beanPath.getNode().toString());
+ Assertions.assertNull(beanPath.getChild());
+ }
+}
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java
index bc24f7d5f..42d422a1f 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java
@@ -12,7 +12,7 @@
package org.dromara.hutool.json;
-import org.dromara.hutool.core.bean.BeanPath;
+import org.dromara.hutool.core.bean.BeanPathOld;
import org.dromara.hutool.core.convert.ConvertException;
import org.dromara.hutool.core.convert.Converter;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
@@ -64,11 +64,11 @@ public interface JSON extends Converter, Cloneable, Serializable {
*
* @param expression 表达式
* @return 对象
- * @see BeanPath#get(Object)
+ * @see BeanPathOld#get(Object)
* @since 4.0.6
*/
default Object getByPath(final String expression) {
- return BeanPath.of(expression).get(this);
+ return BeanPathOld.of(expression).get(this);
}
/**
@@ -93,7 +93,7 @@ public interface JSON extends Converter, Cloneable, Serializable {
* @param value 值
*/
default void putByPath(final String expression, final Object value) {
- BeanPath.of(expression).set(this, value);
+ BeanPathOld.of(expression).set(this, value);
}
/**
@@ -118,7 +118,7 @@ public interface JSON extends Converter, Cloneable, Serializable {
* @param expression 表达式
* @param resultType 返回值类型
* @return 对象
- * @see BeanPath#get(Object)
+ * @see BeanPathOld#get(Object)
* @since 4.0.6
*/
@SuppressWarnings("unchecked")