mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
del OldJSONParser
This commit is contained in:
parent
1f705e0e1f
commit
ffe1adbe46
@ -1,257 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.reader;
|
||||
|
||||
import org.dromara.hutool.core.lang.mutable.Mutable;
|
||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.core.text.CharUtil;
|
||||
import org.dromara.hutool.json.*;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* JSON字符串解析器,实现:
|
||||
* <ul>
|
||||
* <li>JSON字符串 --> {@link JSONTokener} --> {@link JSONObject}</li>
|
||||
* <li>JSON字符串 --> {@link JSONTokener} --> {@link JSONArray}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public class OldJSONParser {
|
||||
|
||||
/**
|
||||
* 创建JSONParser
|
||||
*
|
||||
* @param tokener {@link JSONTokener}
|
||||
* @param config JSON配置
|
||||
* @return JSONParser
|
||||
*/
|
||||
public static OldJSONParser of(final JSONTokener tokener, final JSONConfig config) {
|
||||
return new OldJSONParser(tokener, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON配置
|
||||
*/
|
||||
private final JSONConfig config;
|
||||
private final JSONTokener tokener;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param tokener {@link JSONTokener}
|
||||
* @param config JSON配置
|
||||
*/
|
||||
public OldJSONParser(final JSONTokener tokener, final JSONConfig config) {
|
||||
this.tokener = tokener;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取{@link JSONTokener}
|
||||
*
|
||||
* @return {@link JSONTokener}
|
||||
*/
|
||||
public JSONTokener getTokener() {
|
||||
return this.tokener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否结束
|
||||
*
|
||||
* @return 是否结束
|
||||
*/
|
||||
public boolean end() {
|
||||
return this.tokener.end();
|
||||
}
|
||||
|
||||
// region parseTo
|
||||
|
||||
/**
|
||||
* 解析{@link JSONTokener}中的字符到目标的{@link JSONObject}中
|
||||
*
|
||||
* @param jsonObject {@link JSONObject}
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤,{@link Predicate#test(Object)}为{@code true}保留
|
||||
*/
|
||||
public void parseTo(final JSONObject jsonObject, final Predicate<MutableEntry<String, Object>> predicate) {
|
||||
final JSONTokener tokener = this.tokener;
|
||||
|
||||
if (tokener.nextClean() != '{') {
|
||||
throw tokener.syntaxError("A JSONObject text must begin with '{'");
|
||||
}
|
||||
|
||||
char prev;
|
||||
char c;
|
||||
String key;
|
||||
while (true) {
|
||||
prev = tokener.getPrevious();
|
||||
c = tokener.nextClean();
|
||||
switch (c) {
|
||||
case 0:
|
||||
throw tokener.syntaxError("A JSONObject text must end with '}'");
|
||||
case '}':
|
||||
return;
|
||||
case '{':
|
||||
case '[':
|
||||
if (prev == '{') {
|
||||
throw tokener.syntaxError("A JSONObject can not directly nest another JSONObject or JSONArray.");
|
||||
}
|
||||
default:
|
||||
tokener.back();
|
||||
key = tokener.nextString();
|
||||
}
|
||||
|
||||
// The key is followed by ':'.
|
||||
|
||||
c = tokener.nextClean();
|
||||
if (c != ':') {
|
||||
throw tokener.syntaxError("Expected a ':' after a key");
|
||||
}
|
||||
|
||||
jsonObject.set(key, nextValue(), null);
|
||||
|
||||
// Pairs are separated by ','.
|
||||
|
||||
switch (tokener.nextClean()) {
|
||||
case ';':
|
||||
case CharUtil.COMMA:
|
||||
if (tokener.nextClean() == '}') {
|
||||
// issue#2380
|
||||
// 尾后逗号(Trailing Commas),JSON中虽然不支持,但是ECMAScript 2017支持,此处做兼容。
|
||||
return;
|
||||
}
|
||||
tokener.back();
|
||||
break;
|
||||
case '}':
|
||||
return;
|
||||
default:
|
||||
throw tokener.syntaxError("Expected a ',' or '}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析JSON字符串到{@link JSONArray}中
|
||||
*
|
||||
* @param jsonArray {@link JSONArray}
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null} 表示不过滤,,{@link Predicate#test(Object)}为{@code true}保留
|
||||
*/
|
||||
public void parseTo(final JSONArray jsonArray, final Predicate<Mutable<Object>> predicate) {
|
||||
final JSONTokener x = this.tokener;
|
||||
|
||||
if (x.nextClean() != '[') {
|
||||
throw x.syntaxError("A JSONArray text must start with '['");
|
||||
}
|
||||
if (x.nextClean() != ']') {
|
||||
x.back();
|
||||
for (; ; ) {
|
||||
if (x.nextClean() == CharUtil.COMMA) {
|
||||
x.back();
|
||||
jsonArray.add(null, predicate);
|
||||
} else {
|
||||
x.back();
|
||||
jsonArray.add(nextValue(), predicate);
|
||||
}
|
||||
switch (x.nextClean()) {
|
||||
case CharUtil.COMMA:
|
||||
if (x.nextClean() == ']') {
|
||||
return;
|
||||
}
|
||||
x.back();
|
||||
break;
|
||||
case ']':
|
||||
return;
|
||||
default:
|
||||
throw x.syntaxError("Expected a ',' or ']'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* 获得下一个值,值类型可以是Boolean, Double, Integer, JSONArray, JSONObject, Long, or String
|
||||
*
|
||||
* @return Boolean, Double, Integer, JSONArray, JSONObject, Long, or String
|
||||
* @throws JSONException 语法错误
|
||||
*/
|
||||
public Object nextValue() throws JSONException {
|
||||
return nextValue((token, tokener, config) -> {
|
||||
switch (token) {
|
||||
case CharUtil.DELIM_START:
|
||||
try {
|
||||
return new JSONObject(this, config);
|
||||
} catch (final StackOverflowError e) {
|
||||
throw new JSONException("JSONObject depth too large to process.", e);
|
||||
}
|
||||
case CharUtil.BRACKET_START:
|
||||
try {
|
||||
return new JSONArray(this, config);
|
||||
} catch (final StackOverflowError e) {
|
||||
throw new JSONException("JSONObject depth too large to process.", e);
|
||||
}
|
||||
}
|
||||
throw new JSONException("Unsupported object build for token {}", token);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得下一个值,值类型可以是Boolean, Double, Integer, JSONArray, JSONObject, Long, or String
|
||||
*
|
||||
* @param objectBuilder JSON对象构建器
|
||||
* @return Boolean, Double, Integer, JSONArray, JSONObject, Long, or String
|
||||
* @throws JSONException 语法错误
|
||||
*/
|
||||
public Object nextValue(final ObjectBuilder objectBuilder) throws JSONException {
|
||||
final JSONTokener tokener = this.tokener;
|
||||
final char c = tokener.nextClean();
|
||||
switch (c) {
|
||||
case CharUtil.DOUBLE_QUOTES:
|
||||
case CharUtil.SINGLE_QUOTE:
|
||||
return tokener.nextWrapString(c);
|
||||
case CharUtil.DELIM_START:
|
||||
case CharUtil.BRACKET_START:
|
||||
tokener.back();
|
||||
return objectBuilder.build(c, tokener, this.config);
|
||||
}
|
||||
|
||||
/*
|
||||
* 处理无引号包装的字符串,如: true, false, 或 null, 或 number.
|
||||
* 同样兼容非标准的字符串,如key无引号包装。
|
||||
* 此方法会不断读取并积累字符直到遇到token符
|
||||
*/
|
||||
return InternalJSONUtil.parseValueFromString(tokener.nextUnwrapString(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象构建抽象,通过实现此接口,从{@link JSONTokener}解析值并构建指定对象
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ObjectBuilder {
|
||||
/**
|
||||
* 构建
|
||||
*
|
||||
* @param token 符号表示,用于区分对象类型
|
||||
* @param tokener {@link JSONTokener}
|
||||
* @param config {@link JSONConfig}
|
||||
* @return 构建的对象
|
||||
*/
|
||||
Object build(char token, JSONTokener tokener, JSONConfig config);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user