Skip to content

Commit 61ad637

Browse files
committed
1.0.4
1 parent ff1919c commit 61ad637

File tree

3 files changed

+62
-84
lines changed

3 files changed

+62
-84
lines changed

readme

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ Release notes:
66
- parser converts JSON text to Java objects:
77
JSON object, String, Number (BigDecimal), Boolean, null, Object[] array of listed types;
88
- JSON object members (name/value pairs) are stored in order of appearance/creation;
9-
- when the names within an object are not unique, parser stores the last name/value pair only;
10-
- JSON object setter acceps types listed above, all Java primitives and primitive arrays;
11-
- in addition, generator converts Java Lists to JSON arrays [V[0],...,V[n]] and
12-
Java Maps - to JSON objects {"K": V,...}.
9+
- when the names within an object are not unique, parser stores the last value only;
10+
- JSON object setter accepts any Java object, all Java primitives and primitive arrays;
11+
- in addition to the parsed types, the generator converts Java Lists to JSON arrays
12+
and Java Maps to JSON objects. The null key is converted to a "null" member name.
13+
Other Java objects are converted to JSON strings.
1314

1415
Overview:
1516
static Object parse(String json) throws IOException, ParseException;
@@ -21,11 +22,11 @@ Overview:
2122

2223
Methods:
2324
String toString(); // stringify object
24-
JSON clone() throws CloneNotSupportedException; // clones the member list only
25+
JSON clone(); // clones the member list only
2526
List<String> list(); // list of member names
2627
boolean exists(String memberName);
2728
Object get(String memberName);
28-
JSON set(String memberName, Object value) throws NullPointerException, IllegalArgumentException;
29+
JSON set(String memberName, Object value);
2930
Object remove(String memberName);
3031

3132
Usage example see in https://github.com/miktim/JSON/blob/master/test/JSONTest.java

src/org/miktim/json/JSON.java

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
* Release notes:
55
* - Java 7+, Android compatible;
66
* - in accordance with RFC 8259: https://datatracker.ietf.org/doc/rfc8259/?include_text=1
7-
* - supported Java objects:
8-
* JSON object, String, Number, Boolean, null, Object[] array of listed types;
9-
* - parser applies BigDecimal for numbers;
10-
* - JSON properties are stored in creation/appearance order.
7+
* - parser converts JSON text to Java objects:
8+
* JSON object, String, Number (BigDecimal), Boolean, null, Object[] array of listed types;
9+
* - JSON object members (name/value pairs) are stored in creation/appearance order;
10+
* - when the names within an object are not unique, parser stores the last value only;
1111
*
1212
* Created: 2020-03-07
1313
*/
@@ -41,7 +41,7 @@ public static String stringify(Object object) throws IllegalArgumentException {
4141
return stringifyObject(object);
4242
}
4343

44-
private LinkedHashMap<String, Object> properties = new LinkedHashMap<>();
44+
private LinkedHashMap<String, Object> members = new LinkedHashMap<>();
4545

4646
public JSON() {
4747

@@ -58,43 +58,38 @@ public String toString() {
5858

5959
@SuppressWarnings("unchecked")
6060
@Override
61-
public JSON clone() throws CloneNotSupportedException {
62-
JSON clone = (JSON) super.clone();
63-
clone.properties = (LinkedHashMap<String, Object>) this.properties.clone();
61+
public JSON clone() {//throws CloneNotSupportedException {
62+
// JSON clone = (JSON) super.clone();
63+
JSON clone = new JSON();
64+
clone.members = (LinkedHashMap<String, Object>) this.members.clone();
6465
return clone;
6566
}
6667

6768
public List<String> list() {
68-
return new ArrayList<>(this.properties.keySet());
69+
return new ArrayList<>(this.members.keySet());
6970
}
7071

71-
private String checkPropName(String propName) {
72-
if (propName == null) {
73-
throw new NullPointerException("Illegal property name");
74-
}
75-
return propName;
76-
}
77-
78-
public boolean exists(String propName) {
79-
return listProperties().containsKey(propName);
72+
public boolean exists(String memberName) {
73+
return getMembers().containsKey(memberName);
8074
}
8175

82-
public Object get(String propName) {
83-
return listProperties().get(propName);
76+
public Object get(String memberName) {
77+
return getMembers().get(memberName);
8478
}
8579

86-
public JSON set(String propName, Object value)
87-
throws NullPointerException, IllegalArgumentException {
88-
listProperties().put(checkPropName(propName), checkObjectType(value));
80+
public JSON set(String memberName, Object value) {
81+
// throws NullPointerException, IllegalArgumentException {
82+
// getMembers().put(checkPropName(memberName), checkObjectType(value));
83+
getMembers().put(memberName, value);
8984
return this;
9085
}
9186

92-
public Object remove(String propName) {
93-
return this.listProperties().remove(propName);
87+
public Object remove(String memberName) {
88+
return this.getMembers().remove(memberName);
9489
}
9590

96-
private LinkedHashMap<String, Object> listProperties() {
97-
return this.properties;
91+
private LinkedHashMap<String, Object> getMembers() {
92+
return this.members;
9893
}
9994

10095
static class Parser {
@@ -171,11 +166,11 @@ private Object parseObject() throws IOException, ParseException {
171166
object = new JSON();
172167
if (!expectedChar('}')) { // empty object
173168
do {
174-
Object propName = parseObject();
175-
if ((propName instanceof String) && expectedChar(':')) {
176-
((JSON) object).set((String) propName, parseObject());
169+
Object memberName = parseObject();
170+
if ((memberName instanceof String) && expectedChar(':')) {
171+
((JSON) object).set((String) memberName, parseObject());
177172
} else {
178-
throw newParseException("Property name expected",
173+
throw newParseException("Name expected",
179174
null, offset);
180175
}
181176
} while (expectedChar(','));
@@ -224,7 +219,7 @@ private Object parseObject() throws IOException, ParseException {
224219
} else if (charIn(NUMBERS, lastChar())) {
225220
String number = nextChars(NUMBERS);
226221
try {
227-
object = (Number) new BigDecimal(number);
222+
object = new BigDecimal(number);
228223
} catch (NumberFormatException e) {
229224
throw newParseException("Unparseable number:",
230225
number, offset);
@@ -261,7 +256,7 @@ static String stringifyObject(Object value) {
261256
// } else if (value instanceof Character) {
262257
// return stringifyObject(value.toString());
263258
} else if (value instanceof JSON) {
264-
return stringifyObject(((JSON) value).properties);
259+
return stringifyObject(((JSON) value).members);
265260
} else if (value.getClass().isArray()) {
266261
StringBuilder sb = new StringBuilder("[");
267262
String separator = "";
@@ -277,7 +272,7 @@ static String stringifyObject(Object value) {
277272
String separator = "";
278273
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) value).entrySet()) {
279274
sb.append(separator)
280-
// null key (property name) is converted to "null"
275+
// null key (member name) is converted to "null"
281276
.append(stringifyObject(String.valueOf(entry.getKey())))
282277
.append(": ")
283278
.append(stringifyObject(entry.getValue()));
@@ -290,24 +285,6 @@ static String stringifyObject(Object value) {
290285
// + value.getClass().getSimpleName());
291286
}
292287

293-
static Object checkObjectType(Object obj) throws IllegalArgumentException {
294-
if (obj == null
295-
|| (obj instanceof String)
296-
|| (obj instanceof Number)
297-
|| (obj instanceof Boolean)
298-
|| (obj instanceof JSON)
299-
|| (obj instanceof Character)) {
300-
} else if (obj.getClass().isArray()) {
301-
for (int i = 0; i < Array.getLength(obj); i++) {
302-
checkObjectType(Array.get(obj, i));
303-
}
304-
} else {
305-
throw new IllegalArgumentException("Unsupported object: "
306-
+ obj.getClass().getSimpleName());
307-
}
308-
return obj;
309-
}
310-
311288
private static final char[] ESCAPED_CHARS = {'"', '/', '\\', 'b', 'f', 'n', 'r', 't'};
312289
private static final char[] CHARS_UNESCAPED = {0x22, 0x2F, 0x5C, 0x8, 0xC, 0xA, 0xD, 0x9};
313290

test/JSONTest.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.io.File;
55
import java.io.FileReader;
66
import java.math.BigDecimal;
7+
import java.util.ArrayList;
78
import java.util.Date;
89
import org.miktim.json.JSON;
910

@@ -35,7 +36,7 @@ public static void main(String[] args) throws Exception {
3536
.set("Unescaped", unescaped)
3637
.set("EmptyJSON", new JSON())
3738
.set("intArray", new int[][]{{0, 1, 2}, {3, 4, 5, 6}})
38-
.set("Null", null)
39+
.set(null, null)
3940
.set("True", true)
4041
.set("False", false)
4142
.set("Char", 'c')
@@ -45,35 +46,37 @@ public static void main(String[] args) throws Exception {
4546
.set("Int", 14159265)
4647
.set("Byte", (byte) 0xFF);
4748
out(json);
48-
out("List properties: " + json.list());
49-
for (String propName : json.list()) {
50-
if (json.get(propName) != null) {
51-
out("\"" + propName + "\" is instance of: "
52-
+ json.get(propName).getClass().getSimpleName());
49+
out("List members: " + JSON.stringify(json.list()));
50+
for (String memberName : json.list()) {
51+
if (json.get(memberName) != null) {
52+
out("\"" + memberName + "\" is instance of: "
53+
+ json.get(memberName).getClass().getSimpleName());
5354
} else {
54-
out("\"" + propName + "\" is " + json.get(propName));
55+
out("\"" + memberName + "\" is " + json.get(memberName));
5556
}
5657
}
5758

5859
out("\n\rTest stringify/parse JSON:");
5960
out(json);
61+
out("List members: " + JSON.stringify(json.list()));
6062
json = (JSON) JSON.parse(json.toString());
6163
out(json);
62-
for (String propName : json.list()) {
63-
if (json.get(propName) != null) {
64-
out("\"" + propName + "\" is instance of: "
65-
+ json.get(propName).getClass().getSimpleName());
64+
out("List members: " + JSON.stringify(json.list()));
65+
for (String memberName : json.list()) {
66+
if (json.get(memberName) != null) {
67+
out("\"" + memberName + "\" is instance of: "
68+
+ json.get(memberName).getClass().getSimpleName());
6669
} else {
67-
out("\"" + propName + "\" is " + json.get(propName));
70+
out("\"" + memberName + "\" is " + json.get(memberName));
6871
}
6972
}
7073

71-
out("\n\rTest nullnamed/nonexistent property:");
72-
out("Remove null/nonexistent property returns: "
74+
out("\n\rTest nullnamed/nonexistent member:");
75+
out("Remove null/nonexistent member returns: "
7376
+ json.remove(null) + "/" + json.remove("nonexistent"));
74-
out("Get null/nonexistent property returns: "
77+
out("Get null/nonexistent member returns: "
7578
+ json.get(null) + "/" + json.get("nonexistent"));
76-
out("Exists null/nonexistent property returns: "
79+
out("Exists null/nonexistent member returns: "
7780
+ json.exists(null) + "/" + json.exists("nonexistent"));
7881

7982
out("\n\rTest JSON clone then remove \"BigDecimal\":");
@@ -94,6 +97,12 @@ public static void main(String[] args) throws Exception {
9497
out(JSON.stringify(array));
9598
out(JSON.stringify(cloned.get("Array")));
9699

100+
out("\n\rTest generator with other Java objects (ArrayList with Date, File entries):");
101+
ArrayList<Object> arrayList = new ArrayList<>();
102+
arrayList.add(new Date());
103+
arrayList.add(new File(path, "json.json"));
104+
out(JSON.stringify(arrayList));
105+
97106
// examples from RFC 8259 https://datatracker.ietf.org/doc/rfc8259/?include_text=1
98107
out("\n\rTest examples from RFC 8259:");
99108
out(JSON.parse("\"\\uD834\\uDD1E\"")); // G-clef
@@ -158,24 +167,15 @@ public static void main(String[] args) throws Exception {
158167
out(json.get("Description"));
159168
json.set("Description", "Naked Gun");
160169
out(JSON.stringify(array));
161-
array[0] = 123;
162-
array[1] = null;
163-
out(JSON.stringify(array));
164170

165171
// ParseExceptions
166172
// out(JSON.parse("\"asfas\\uD83\uDD1E\"")); // unparseable u-escaped char
167173
// out(JSON.parse("\"\uD834\\uDD1\"")); // unparseable u-escaped char
168174
// out(JSON.parse("123e")); // unparseable number
169175
// out(JSON.parse("123 e")); // EOT Expected
176+
// out(JSON.parse("{{}}"); // name expected
170177
// out(JSON.parse("{\"Latitude\": 37.371991\n\"")); // "}" expected
171178
// out(JSON.parse("b123")); // unexpected char
172179
// out(JSON.parse("falsen")); // unknown literal
173-
// NullPointerException
174-
// json.set(null,123); // null property name
175-
// IllegalArgumentExceptions
176-
// json.set("File", new File(path,"json.json")); // unsupported object
177-
// array[1] = new Date();
178-
// JSON.stringify(array); // unsupported object in array
179-
// json.set("unsupported", array) // unsupported object in array
180180
}
181181
}

0 commit comments

Comments
 (0)