add DuplicateMode

This commit is contained in:
Looly
2024-10-01 23:44:00 +08:00
parent 449fe1fa2e
commit e54c0b26f6
34 changed files with 217 additions and 179 deletions

View File

@@ -119,7 +119,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @param value 值,可以是: Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the JSONNull.NULL。
* @return this.
*/
public JSONArray addObj(final Object value) {
public JSONArray addValue(final Object value) {
// add时如果value为字符串不解析而是作为JSONPrimitive对待
this.add(this.factory.getMapper().toJSON(value, false));
return this;
@@ -138,7 +138,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
}
final JSONObject jo = this.factory.ofObj();
for (int i = 0; i < names.size(); i += 1) {
jo.putObj(names.getStr(i), this.getObj(i));
jo.putValue(names.getStr(i), this.getObj(i));
}
return jo;
}
@@ -171,7 +171,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @param element 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return this
*/
public JSONArray setObj(final int index, final Object element) {
public JSONArray setValue(final int index, final Object element) {
// set时如果value为字符串不解析而是作为JSONPrimitive对待
set(index, this.factory.getMapper().toJSON(element, false));
return this;

View File

@@ -65,9 +65,9 @@ public class JSONConfig implements Serializable {
*/
private boolean stripTrailingZeros = true;
/**
* 是否检查重复key
* 重复key的put策略
*/
private boolean checkDuplicate;
private DuplicateMode duplicateMode = DuplicateMode.OVERRIDE;
/**
* Number写出模式
*/
@@ -247,24 +247,22 @@ public class JSONConfig implements Serializable {
}
/**
* 是否检查多个相同的key
* 获取key重复策略
*
* @return 是否检查多个相同的key
* @since 5.8.5
* @return key重复策略
*/
public boolean isCheckDuplicate() {
return checkDuplicate;
public DuplicateMode getDuplicateMode() {
return duplicateMode;
}
/**
* 是否检查多个相同的key
* 设置key重复策略
*
* @param checkDuplicate 是否检查多个相同的key
* @param duplicateMode key重复策略
* @return this
* @since 5.8.5
*/
public JSONConfig setCheckDuplicate(final boolean checkDuplicate) {
this.checkDuplicate = checkDuplicate;
public JSONConfig set(final DuplicateMode duplicateMode) {
this.duplicateMode = duplicateMode;
return this;
}
@@ -290,4 +288,23 @@ public class JSONConfig implements Serializable {
this.numberWriteMode = numberWriteMode;
return this;
}
/**
* 重复key或重复对象处理方式<br>
* 只针对{@link JSONObject}检查在put时key的重复情况
*/
public enum DuplicateMode {
/**
* 抛出异常
*/
THROW,
/**
* 覆盖
*/
OVERRIDE,
/**
* 忽略
*/
IGNORE
}
}

View File

@@ -204,10 +204,13 @@ public class JSONFactory {
/**
* 创建JSONPrimitive
*
* @param value 值
* @param value 值{@code null}则返回{@code null}
* @return JSONPrimitive
*/
public JSONPrimitive ofPrimitive(final Object value) {
if(null == value){
return null;
}
return new JSONPrimitive(value, this);
}

View File

@@ -144,7 +144,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
}
// endregion
// region ----- put
// region ----- increment or append
/**
* 对值加一如果值不存在赋值1如果为数字类型做加一操作
*
@@ -155,7 +155,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
public JSONObject increment(final String key) throws JSONException {
final JSON json = this.get(key);
if(null == json){
return putObj(key, 1);
return putValue(key, 1);
}
if(json instanceof JSONPrimitive){
@@ -186,15 +186,17 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
public JSONObject append(final String key, final Object value) throws JSONException {
final Object object = this.getObj(key);
if (object == null) {
this.putObj(key, value);
this.putValue(key, value);
} else if (object instanceof JSONArray) {
((JSONArray) object).addObj(value);
((JSONArray) object).addValue(value);
} else {
this.putObj(key, factory.ofArray().addObj(object).addObj(value));
this.putValue(key, factory.ofArray().addValue(object).addValue(value));
}
return this;
}
// endregion
// region ----- put
/**
* 通过lambda批量设置值<br>
* 实际使用时可以使用getXXX的方法引用来完成键值对的赋值
@@ -207,7 +209,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* @return this
*/
public JSONObject putFields(final SerSupplier<?>... fields) {
Arrays.stream(fields).forEach(f -> putObj(LambdaUtil.getFieldName(f), f.get()));
Arrays.stream(fields).forEach(f -> putValue(LambdaUtil.getFieldName(f), f.get()));
return this;
}
@@ -218,9 +220,9 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* @return this.
* @throws JSONException 值是无穷数字抛出此异常
*/
public JSONObject putAllObj(final Map<?, ?> map) {
public JSONObject putAllValue(final Map<?, ?> map) {
if(MapUtil.isNotEmpty(map)){
map.forEach((key, value) -> putObj(StrUtil.toStringOrNull(key), value));
map.forEach((key, value) -> putValue(StrUtil.toStringOrNull(key), value));
}
return this;
}
@@ -229,11 +231,11 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* 设置键值对到JSONObject中在忽略null模式下如果值为{@code null},将此键移除
*
* @param key 键
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the {@code null}
* @return this.
* @throws JSONException 值是无穷数字抛出此异常
*/
public JSONObject putObj(final String key, final Object value) throws JSONException {
public JSONObject putValue(final String key, final Object value) throws JSONException {
// put时如果value为字符串不解析而是作为JSONPrimitive对待
this.put(key, factory.getMapper().toJSON(value, false));
return this;
@@ -253,11 +255,17 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
return null;
}
final boolean ignoreNullValue = config().isIgnoreNullValue();
if (null == value && ignoreNullValue) {
final JSONConfig config = config();
if (null == value && config.isIgnoreNullValue()) {
// 忽略值模式下如果值为空清除key
return this.remove(key);
} else if (config().isCheckDuplicate() && containsKey(key)) {
}
final JSONConfig.DuplicateMode duplicateMode = config.getDuplicateMode();
if (JSONConfig.DuplicateMode.OVERRIDE != duplicateMode && containsKey(key)) {
if(JSONConfig.DuplicateMode.IGNORE == duplicateMode){
return null;
}
throw new JSONException("Duplicate key \"{}\"", key);
}
return super.put(key, value);

View File

@@ -55,7 +55,7 @@ public class Claims implements Serializable {
claimJSON.remove(name);
return;
}
claimJSON.putObj(name, value);
claimJSON.putValue(name, value);
}
/**

View File

@@ -202,7 +202,7 @@ public class JSONParser {
final MutableEntry<Object, Object> entry = new MutableEntry<>(key, value);
if (predicate.test(entry)) {
// 使用修改后的键值对
jsonObject.putObj((String) entry.getKey(), entry.getValue());
jsonObject.putValue((String) entry.getKey(), entry.getValue());
}
} else {
jsonObject.put(key, value);
@@ -242,7 +242,7 @@ public class JSONParser {
final MutableEntry<Object, Object> entry = MutableEntry.of(jsonArray.size(), value);
if (predicate.test(entry)) {
// 使用修改后的键值对用户修改后可能不是JSON此处使用set调用mapper转换
jsonArray.setObj((Integer) entry.getKey(), entry.getValue());
jsonArray.setValue((Integer) entry.getKey(), entry.getValue());
}
} else {
jsonArray.add(value);

View File

@@ -109,7 +109,7 @@ public class ArrayTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJ
// 非标准的二进制流,则按照普通数组对待
final JSONArray result = context.getOrCreateArray();
for (final byte b : bytes) {
result.addObj(b);
result.addValue(b);
}
return result;
}

View File

@@ -59,7 +59,7 @@ public class EntryTypeAdapter implements MatcherJSONSerializer<Map.Entry<?, ?>>,
@Override
public JSON serialize(final Map.Entry<?, ?> bean, final JSONContext context) {
return context.getOrCreateObj()
.putObj(ConvertUtil.toStr(bean.getKey()), bean.getValue());
.putValue(ConvertUtil.toStr(bean.getKey()), bean.getValue());
}
@Override

View File

@@ -114,7 +114,7 @@ public class IterTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
next = iter.next();
// 检查循环引用
if (next != source) {
jsonArray.addObj(next);
jsonArray.addValue(next);
}
}
}

View File

@@ -82,7 +82,7 @@ public class MapTypeAdapter implements MatcherJSONSerializer<Map<?, ?>>, Matcher
final JSONObject result = context.getOrCreateObj();
// 注入键值对
for (final Map.Entry<?, ?> e : bean.entrySet()) {
result.putObj(StrUtil.toStringOrNull(e.getKey()), e.getValue());
result.putValue(StrUtil.toStringOrNull(e.getKey()), e.getValue());
}
return result;
}

View File

@@ -87,10 +87,10 @@ public class ResourceBundleSerializer implements MatcherJSONSerializer<ResourceB
JSONObject nextTarget = target.getJSONObject(segment);
if (nextTarget == null) {
nextTarget = JSONUtil.ofObj(target.config());
target.putObj(segment, nextTarget);
target.putValue(segment, nextTarget);
}
target = nextTarget;
}
target.putObj(path[last], value);
target.putValue(path[last], value);
}
}

View File

@@ -136,24 +136,24 @@ public class TemporalTypeAdapter implements MatcherJSONSerializer<TemporalAccess
private static void toJSONObject(final TemporalAccessor bean, final JSONObject json) {
if (bean instanceof LocalDate) {
final LocalDate localDate = (LocalDate) bean;
json.putObj(YEAR_KEY, localDate.getYear());
json.putObj(MONTH_KEY, localDate.getMonthValue());
json.putObj(DAY_KEY, localDate.getDayOfMonth());
json.putValue(YEAR_KEY, localDate.getYear());
json.putValue(MONTH_KEY, localDate.getMonthValue());
json.putValue(DAY_KEY, localDate.getDayOfMonth());
} else if (bean instanceof LocalDateTime) {
final LocalDateTime localDateTime = (LocalDateTime) bean;
json.putObj(YEAR_KEY, localDateTime.getYear());
json.putObj(MONTH_KEY, localDateTime.getMonthValue());
json.putObj(DAY_KEY, localDateTime.getDayOfMonth());
json.putObj(HOUR_KEY, localDateTime.getHour());
json.putObj(MINUTE_KEY, localDateTime.getMinute());
json.putObj(SECOND_KEY, localDateTime.getSecond());
json.putObj(NANO_KEY, localDateTime.getNano());
json.putValue(YEAR_KEY, localDateTime.getYear());
json.putValue(MONTH_KEY, localDateTime.getMonthValue());
json.putValue(DAY_KEY, localDateTime.getDayOfMonth());
json.putValue(HOUR_KEY, localDateTime.getHour());
json.putValue(MINUTE_KEY, localDateTime.getMinute());
json.putValue(SECOND_KEY, localDateTime.getSecond());
json.putValue(NANO_KEY, localDateTime.getNano());
} else if (bean instanceof LocalTime) {
final LocalTime localTime = (LocalTime) bean;
json.putObj(HOUR_KEY, localTime.getHour());
json.putObj(MINUTE_KEY, localTime.getMinute());
json.putObj(SECOND_KEY, localTime.getSecond());
json.putObj(NANO_KEY, localTime.getNano());
json.putValue(HOUR_KEY, localTime.getHour());
json.putValue(MINUTE_KEY, localTime.getMinute());
json.putValue(SECOND_KEY, localTime.getSecond());
json.putValue(NANO_KEY, localTime.getNano());
} else{
throw new JSONException("Unsupported type: {}", bean.getClass().getName());
}

View File

@@ -84,10 +84,10 @@ public class BeanToJSONCopier implements Copier<JSONObject> {
final MutableEntry<Object, Object> entry = new MutableEntry<>(fieldName, sValue);
if (predicate.test(entry)) {
// 使用修改后的键值对
target.putObj((String) entry.getKey(), entry.getValue());
target.putValue((String) entry.getKey(), entry.getValue());
}
} else if (null != sValue || !ignoreNullValue) {
target.putObj(fieldName, sValue);
target.putValue(fieldName, sValue);
}
}
}

View File

@@ -82,9 +82,9 @@ public class JSONNodeBeanFactory implements NodeBeanFactory<JSON> {
return bean;
} else if (node instanceof NameNode) {
if(bean instanceof JSONObject){
((JSONObject) bean).putObj(((NameNode) node).getName(), value);
((JSONObject) bean).putValue(((NameNode) node).getName(), value);
} else if(bean instanceof JSONArray){
((JSONArray) bean).setObj(Integer.parseInt(((NameNode) node).getName()), value);
((JSONArray) bean).setValue(Integer.parseInt(((NameNode) node).getName()), value);
}
return bean;
}