Skip to content

Commit c8ebb3c

Browse files
committed
Initial import: Backport of jdk-sandbox JSON API to JDK 24
Backport of the experimental JSON API from jdk-sandbox commit d22dc2ba8 to work with JDK 24. This is a simplified version with optimizations and value-based features removed for compatibility. Changes from original: - Removed StableValue optimizations - Removed value-based class annotations - Basic implementation without performance optimizations - Compatible with JDK 24 instead of future JDK versions Provides a functional JSON parser and API including: - JsonValue hierarchy (JsonObject, JsonArray, JsonString, etc.) - JSON parsing with JsonParser - Basic immutable value objects Licensed under GNU General Public License version 2 with Classpath exception.
0 parents  commit c8ebb3c

24 files changed

+2784
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
target/
2+
3+
.idea/

LICENSE

Lines changed: 347 additions & 0 deletions
Large diffs are not rendered by default.

Towards a JSON API for the JDK.pdf

75.9 KB
Binary file not shown.

pom.xml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>jdk-sandbox</groupId>
6+
<artifactId>json-experimental</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<packaging>jar</packaging>
9+
10+
<name>JSON Experimental</name>
11+
<description>Experimental JSON API and internal dependencies</description>
12+
13+
<licenses>
14+
<license>
15+
<name>GNU General Public License, version 2, with the Classpath Exception</name>
16+
<url>https://www.gnu.org/licenses/old-licenses/gpl-2.0.html</url>
17+
<distribution>repo</distribution>
18+
</license>
19+
</licenses>
20+
21+
<properties>
22+
<maven.compiler.source>24</maven.compiler.source>
23+
<maven.compiler.target>24</maven.compiler.target>
24+
</properties>
25+
26+
<build>
27+
<plugins>
28+
<plugin>
29+
<groupId>org.apache.maven.plugins</groupId>
30+
<artifactId>maven-compiler-plugin</artifactId>
31+
<version>3.8.1</version>
32+
<configuration>
33+
<source>24</source>
34+
<target>24</target>
35+
</configuration>
36+
</plugin>
37+
</plugins>
38+
</build>
39+
</project>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package jdk.sandbox;
2+
3+
import java.util.function.Supplier;
4+
5+
/**
6+
* Mimics JDK's StableValue using double-checked locking pattern
7+
* for thread-safe lazy initialization.
8+
*/
9+
public class StableValue<T> {
10+
private volatile T value;
11+
private final Object lock = new Object();
12+
13+
private StableValue() {}
14+
15+
public static <T> StableValue<T> of() {
16+
return new StableValue<>();
17+
}
18+
19+
public T get() {
20+
return value;
21+
}
22+
23+
public void set(T value) {
24+
if (this.value == null) {
25+
synchronized (lock) {
26+
if (this.value == null) {
27+
this.value = value;
28+
}
29+
}
30+
}
31+
}
32+
33+
public T orElse(T defaultValue) {
34+
T result = value;
35+
return result != null ? result : defaultValue;
36+
}
37+
38+
public T orElseSet(Supplier<T> supplier) {
39+
T result = value;
40+
if (result == null) {
41+
synchronized (lock) {
42+
result = value;
43+
if (result == null) {
44+
value = result = supplier.get();
45+
}
46+
}
47+
}
48+
return result;
49+
}
50+
51+
public void setOrThrow(T newValue) {
52+
if (value != null) {
53+
throw new IllegalStateException("Value already set");
54+
}
55+
synchronized (lock) {
56+
if (value != null) {
57+
throw new IllegalStateException("Value already set");
58+
}
59+
value = newValue;
60+
}
61+
}
62+
63+
public static <T> Supplier<T> supplier(Supplier<T> supplier) {
64+
return new Supplier<T>() {
65+
private volatile T cached;
66+
private final Object supplierLock = new Object();
67+
68+
@Override
69+
public T get() {
70+
T result = cached;
71+
if (result == null) {
72+
synchronized (supplierLock) {
73+
result = cached;
74+
if (result == null) {
75+
cached = result = supplier.get();
76+
}
77+
}
78+
}
79+
return result;
80+
}
81+
};
82+
}
83+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package jdk.sandbox.demo;
2+
3+
import jdk.sandbox.java.util.json.Json;
4+
import jdk.sandbox.java.util.json.JsonObject;
5+
import jdk.sandbox.java.util.json.JsonString;
6+
import jdk.sandbox.java.util.json.JsonNumber;
7+
import java.util.Map;
8+
9+
public class JsonDemo {
10+
public static void main(String[] args) {
11+
// Create a JSON object using the factory method
12+
JsonObject jsonObject = JsonObject.of(Map.of(
13+
"name", JsonString.of("John"),
14+
"age", JsonNumber.of(30)
15+
));
16+
17+
System.out.println(jsonObject.toString());
18+
19+
// Parse JSON string
20+
String jsonStr = "{\"name\":\"Jane\",\"age\":25}";
21+
var parsed = Json.parse(jsonStr);
22+
System.out.println("Parsed: " + parsed);
23+
}
24+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package jdk.sandbox.internal.util.json;
27+
28+
import java.util.Collections;
29+
import java.util.List;
30+
import jdk.sandbox.java.util.json.JsonArray;
31+
import jdk.sandbox.java.util.json.JsonValue;
32+
33+
34+
/**
35+
* JsonArray implementation class
36+
*/
37+
public final class JsonArrayImpl implements JsonArray {
38+
39+
private final List<JsonValue> theValues;
40+
41+
public JsonArrayImpl(List<JsonValue> from) {
42+
theValues = from;
43+
}
44+
45+
@Override
46+
public List<JsonValue> values() {
47+
return Collections.unmodifiableList(theValues);
48+
}
49+
50+
@Override
51+
public String toString() {
52+
var s = new StringBuilder("[");
53+
for (JsonValue v: values()) {
54+
s.append(v.toString()).append(",");
55+
}
56+
if (!values().isEmpty()) {
57+
s.setLength(s.length() - 1); // trim final comma
58+
}
59+
return s.append("]").toString();
60+
}
61+
62+
@Override
63+
public boolean equals(Object o) {
64+
return o instanceof JsonArray oja &&
65+
values().equals(oja.values());
66+
}
67+
68+
@Override
69+
public int hashCode() {
70+
return values().hashCode();
71+
}
72+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package jdk.sandbox.internal.util.json;
27+
28+
import jdk.sandbox.java.util.json.JsonBoolean;
29+
30+
31+
/**
32+
* JsonBoolean implementation class
33+
*/
34+
public final class JsonBooleanImpl implements JsonBoolean {
35+
36+
private final Boolean theBoolean;
37+
38+
public static final JsonBooleanImpl TRUE = new JsonBooleanImpl(true);
39+
public static final JsonBooleanImpl FALSE = new JsonBooleanImpl(false);
40+
41+
private JsonBooleanImpl(Boolean bool) {
42+
theBoolean = bool;
43+
}
44+
45+
@Override
46+
public boolean value() {
47+
return theBoolean;
48+
}
49+
50+
@Override
51+
public String toString() {
52+
return String.valueOf(value());
53+
}
54+
55+
@Override
56+
public boolean equals(Object o) {
57+
return o instanceof JsonBoolean ojb && value() == ojb.value();
58+
}
59+
60+
@Override
61+
public int hashCode() {
62+
return Boolean.hashCode(value());
63+
}
64+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package jdk.sandbox.internal.util.json;
27+
28+
import jdk.sandbox.java.util.json.JsonNull;
29+
30+
31+
/**
32+
* JsonNull implementation class
33+
*/
34+
public final class JsonNullImpl implements JsonNull {
35+
36+
public static final JsonNullImpl NULL = new JsonNullImpl();
37+
private static final String VALUE = "null";
38+
private static final int HASH = VALUE.hashCode();
39+
40+
private JsonNullImpl() {}
41+
42+
@Override
43+
public String toString() {
44+
return VALUE;
45+
}
46+
47+
@Override
48+
public boolean equals(Object obj) {
49+
return obj instanceof JsonNull;
50+
}
51+
52+
@Override
53+
public int hashCode() {
54+
return HASH;
55+
}
56+
}

0 commit comments

Comments
 (0)