Skip to content

Commit 612e419

Browse files
committed
initial implementation of JSONPointer
1 parent 25a8797 commit 612e419

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

JSONPointer.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.json;
2+
3+
import static java.lang.String.format;
4+
import static java.util.Collections.emptyList;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
public class JSONPointer {
10+
11+
private List<String> refTokens;
12+
13+
public JSONPointer(String pointer) {
14+
if (pointer == null) {
15+
throw new NullPointerException("pointer cannot be null");
16+
}
17+
if (pointer.isEmpty()) {
18+
refTokens = emptyList();
19+
return;
20+
}
21+
if (pointer.startsWith("#/")) {
22+
pointer = pointer.substring(2);
23+
} else if (pointer.startsWith("/")) {
24+
pointer = pointer.substring(1);
25+
} else {
26+
throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'");
27+
}
28+
refTokens = new ArrayList<String>();
29+
for (String token : pointer.split("/")) {
30+
refTokens.add(unescape(token));
31+
}
32+
}
33+
34+
private String unescape(String token) {
35+
return token.replace("~1", "/").replace("~0", "~");
36+
}
37+
38+
public Object queryFrom(JSONObject document) {
39+
if (refTokens.isEmpty()) {
40+
return document;
41+
}
42+
Object current = document;
43+
for (String token : refTokens) {
44+
if (current instanceof JSONObject) {
45+
current = ((JSONObject) current).opt(unescape(token));
46+
} else if (current instanceof JSONArray) {
47+
current = readByIndexToken(current, unescape(token));
48+
}
49+
}
50+
return current;
51+
}
52+
53+
private Object readByIndexToken(Object current, String indexToken) {
54+
try {
55+
return ((JSONArray) current).opt(Integer.parseInt(unescape(indexToken)));
56+
} catch (NumberFormatException e) {
57+
throw new JSONPointerException(format("%s is not an array index", unescape(indexToken)), e);
58+
}
59+
}
60+
61+
}

JSONPointerException.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.json;
2+
3+
/**
4+
* The JSONPointerException is thrown by {@link JSONPointer} if an error occurs
5+
* during evaluating a pointer.
6+
*
7+
* @author erosb
8+
*
9+
*/
10+
public class JSONPointerException extends JSONException {
11+
private static final long serialVersionUID = 8872944667561856751L;
12+
13+
public JSONPointerException(String message) {
14+
super(message);
15+
}
16+
17+
public JSONPointerException(String message, Throwable cause) {
18+
super(message, cause);
19+
}
20+
21+
}

0 commit comments

Comments
 (0)