Skip to content

Commit

Permalink
Sync with underscore-java
Browse files Browse the repository at this point in the history
  • Loading branch information
javadev authored Aug 15, 2024
1 parent bce5da3 commit 8be4480
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 94 deletions.
30 changes: 19 additions & 11 deletions src/main/java/com/github/underscore/Json.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ package com.github.underscore

import java.math.BigDecimal
import java.math.BigInteger
import java.util.*

object Json {
private const val NULL = "null"
private const val DIGIT = "digit"
private const val PARSE_MAX_DEPTH: Int = 10000

@JvmOverloads
@JvmStatic
Expand All @@ -52,7 +52,12 @@ object Json {

@JvmStatic
fun fromJson(string: String): Any? {
return JsonParser(string).parse()
return JsonParser(string, PARSE_MAX_DEPTH).parse()
}

@JvmStatic
fun fromJson(string: String, maxDepth: Int): Any? {
return JsonParser(string, maxDepth).parse()
}

@JvmStatic
Expand Down Expand Up @@ -430,7 +435,7 @@ object Json {
) :
RuntimeException(String.format("%s at %d:%d", message, line, column))

class JsonParser(private val json: String) {
class JsonParser(private val json: String, private val maxDepth: Int) {
private var index = 0
private var line = 1
private var lineOffset = 0
Expand All @@ -445,28 +450,31 @@ object Json {
fun parse(): Any? {
read()
skipWhiteSpace()
val result = readValue()
val result = readValue(0)
skipWhiteSpace()
if (!isEndOfText) {
throw error("Unexpected character")
}
return result
}

private fun readValue(): Any? {
private fun readValue(depth: Int): Any? {
if (depth > maxDepth) {
throw error("Maximum depth exceeded")
}
return when (current.toChar()) {
'n' -> readNull()
't' -> readTrue()
'f' -> readFalse()
'"' -> readString()
'[' -> readArray()
'{' -> readObject()
'[' -> readArray(depth + 1)
'{' -> readObject(depth + 1)
'-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> readNumber()
else -> throw expected("value")
}
}

private fun readArray(): List<Any?> {
private fun readArray(depth: Int): List<Any?> {
read()
val array: MutableList<Any?> = ArrayList()
skipWhiteSpace()
Expand All @@ -475,7 +483,7 @@ object Json {
}
do {
skipWhiteSpace()
array.add(readValue())
array.add(readValue(depth))
skipWhiteSpace()
} while (readChar(','))
if (!readChar(']')) {
Expand All @@ -484,7 +492,7 @@ object Json {
return array
}

private fun readObject(): Map<String, Any?> {
private fun readObject(depth: Int): Map<String, Any?> {
read()
val `object`: MutableMap<String, Any?> = LinkedHashMap()
skipWhiteSpace()
Expand All @@ -499,7 +507,7 @@ object Json {
throw expected("':'")
}
skipWhiteSpace()
`object`[name] = readValue()
`object`[name] = readValue(depth)
skipWhiteSpace()
} while (readChar(','))
if (!readChar('}')) {
Expand Down
81 changes: 54 additions & 27 deletions src/main/java/com/github/underscore/U.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
*/
package com.github.underscore;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -91,23 +90,24 @@ public class U<T> extends Underscore<T> {
private static final int BUFFER_LENGTH_1024 = 1024;
private static final int RESPONSE_CODE_400 = 400;
private static final String ROOT = "root";
private static String upper = "[A-Z\\xc0-\\xd6\\xd8-\\xde\\u0400-\\u04FF]";
private static String lower = "[a-z\\xdf-\\xf6\\xf8-\\xff]+";
private static String selfClosing = "-self-closing";
private static String nilKey = "-nil";
private static java.util.regex.Pattern reWords =
private static final String UPPER = "[A-Z\\xc0-\\xd6\\xd8-\\xde\\u0400-\\u04FF]";
private static final String LOWER = "[a-z\\xdf-\\xf6\\xf8-\\xff]+";
private static final String SELF_CLOSING = "-self-closing";
private static final String NIL_KEY = "-nil";
private static final String OMIT_XML_DECL = "#omit-xml-declaration";
private static final java.util.regex.Pattern RE_WORDS =
java.util.regex.Pattern.compile(
upper
UPPER
+ "+(?="
+ upper
+ lower
+ UPPER
+ LOWER
+ ")|"
+ upper
+ UPPER
+ "?"
+ lower
+ LOWER
+ "|"
+ upper
+ "+|[0-9]+");
+ UPPER
+ "+|\\d+");

static {
String[] deburredLetters =
Expand Down Expand Up @@ -243,7 +243,7 @@ public Chain<T> compact() {

@Override
public Chain<T> compact(final T falsyValue) {
return new Chain<>(Underscore.compact(value(), falsyValue));
return new Chain<>(Underscore.compactList(value(), falsyValue));
}

@Override
Expand Down Expand Up @@ -1460,7 +1460,7 @@ public static String deburr(final String string) {
public static List<String> words(final String string) {
final String localString = baseToString(string);
final List<String> result = new ArrayList<>();
final java.util.regex.Matcher matcher = reWords.matcher(localString);
final java.util.regex.Matcher matcher = RE_WORDS.matcher(localString);
while (matcher.find()) {
result.add(matcher.group());
}
Expand Down Expand Up @@ -2069,7 +2069,7 @@ public static long downloadUrl(final String url, final String fileName)
public static void decompressGzip(final String sourceFileName, final String targetFileName)
throws IOException {
try (GZIPInputStream gis =
new GZIPInputStream(new FileInputStream(new File(sourceFileName)))) {
new GZIPInputStream(new FileInputStream(sourceFileName))) {
Files.copy(gis, Paths.get(targetFileName));
}
}
Expand Down Expand Up @@ -2523,6 +2523,14 @@ public static <T> String join(final Iterable<T> iterable, final String separator
return Underscore.join(iterable, separator);
}

public static <T> String joinToString(final Iterable<T> iterable, final String separator,
final String prefix, final String postfix,
final int limit,
final String truncated,
final Function<T, String> transform) {
return Underscore.joinToString(iterable, separator, prefix, postfix, limit, truncated, transform);
}

public static String toJson(Collection collection) {
return Json.toJson(collection);
}
Expand Down Expand Up @@ -2601,6 +2609,11 @@ public static Map<String, Object> fromJsonMap(final String string) {
return getStringObjectMap(object);
}

public static Map<String, Object> fromJsonMap(final String string, final int maxDepth) {
final Object object = Json.fromJson(string, maxDepth);
return getStringObjectMap(object);
}

@SuppressWarnings("unchecked")
private static Map<String, Object> getStringObjectMap(Object object) {
final Map<String, Object> result;
Expand Down Expand Up @@ -2737,6 +2750,20 @@ public static String xmlToJson(String xml) {
return xmlToJson(xml, Json.JsonStringBuilder.Step.TWO_SPACES, null);
}

@SuppressWarnings("unchecked")
public static String xmlToJsonMinimum(String xml, Json.JsonStringBuilder.Step identStep) {
Object object = Xml.fromXml(xml);
if (object instanceof Map) {
((Map) object).remove(OMIT_XML_DECL);
return Json.toJson(replaceSelfClosingWithEmpty((Map) object), identStep);
}
return Json.toJson((List) object, identStep);
}

public static String xmlToJsonMinimum(String xml) {
return xmlToJsonMinimum(xml, Json.JsonStringBuilder.Step.TWO_SPACES);
}

public static String xmlToJson(String xml, Json.JsonStringBuilder.Step identStep) {
return xmlToJson(xml, identStep, null);
}
Expand Down Expand Up @@ -2872,8 +2899,8 @@ public static Map<String, Object> removeMinusesAndConvertNumbers(Map<String, Obj
} else {
newKey = entry.getKey();
}
if (!entry.getKey().equals(selfClosing)
&& !entry.getKey().equals("#omit-xml-declaration")) {
if (!entry.getKey().equals(SELF_CLOSING)
&& !entry.getKey().equals(OMIT_XML_DECL)) {
outMap.put(newKey, makeObject(entry.getValue()));
}
}
Expand Down Expand Up @@ -2950,7 +2977,7 @@ public static Map<String, Object> replaceSelfClosingWithEmpty(Map<String, Object
public static Object replaceSelfClosingWithValue(Map<String, Object> map, String value) {
Object outMap = new LinkedHashMap<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (selfClosing.equals(entry.getKey()) && "true".equals(entry.getValue())) {
if (SELF_CLOSING.equals(entry.getKey()) && "true".equals(entry.getValue())) {
if (map.size() == 1) {
outMap = value;
break;
Expand Down Expand Up @@ -3213,9 +3240,9 @@ public static Map<String, Object> replaceFirstLevel(Map<String, Object> map, int
}
if (level == 0 && Xml.XmlValue.getMapValue(outMap) instanceof Map) {
Map<String, Object> outMap2 = (Map<String, Object>) Xml.XmlValue.getMapValue(outMap);
if (selfClosing.equals(Xml.XmlValue.getMapKey(outMap2))
if (SELF_CLOSING.equals(Xml.XmlValue.getMapKey(outMap2))
&& "true".equals(Xml.XmlValue.getMapValue(outMap2))) {
outMap2.remove(selfClosing);
outMap2.remove(SELF_CLOSING);
}
return outMap2;
}
Expand Down Expand Up @@ -3244,11 +3271,11 @@ public static Map<String, Object> replaceNilWithNull(Map<String, Object> map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object outValue = makeReplaceNilWithNull(entry.getValue());
if (outValue instanceof Map
&& (nilKey.equals(Xml.XmlValue.getMapKey(outValue))
&& (NIL_KEY.equals(Xml.XmlValue.getMapKey(outValue))
|| Xml.XmlValue.getMapKey(outValue).endsWith(":nil"))
&& "true".equals(Xml.XmlValue.getMapValue(outValue))
&& ((Map) outValue).containsKey(selfClosing)
&& "true".equals(((Map) outValue).get(selfClosing))) {
&& ((Map) outValue).containsKey(SELF_CLOSING)
&& "true".equals(((Map) outValue).get(SELF_CLOSING))) {
outValue = null;
}
outMap.put(entry.getKey(), outValue);
Expand Down Expand Up @@ -3392,7 +3419,7 @@ public Builder addNull(final String key) {

@SuppressWarnings("unchecked")
public Map<String, Object> build() {
return (Map<String, Object>) ((LinkedHashMap) data).clone();
return (Map<String, Object>) ((LinkedHashMap<?, ?>) data).clone();
}

public String toXml() {
Expand Down Expand Up @@ -3498,13 +3525,13 @@ public ArrayBuilder add(final Builder builder) {

@SuppressWarnings("unchecked")
public ArrayBuilder merge(final List<Object> list) {
U.merge(data, (List<Object>) ((ArrayList) list).clone());
U.merge(data, (List<Object>) ((ArrayList<?>) list).clone());
return this;
}

@SuppressWarnings("unchecked")
public List<Object> build() {
return (List<Object>) ((ArrayList) data).clone();
return (List<Object>) ((ArrayList<?>) data).clone();
}

public String toXml() {
Expand Down
Loading

0 comments on commit 8be4480

Please sign in to comment.