diff --git a/JSONPointer.java b/JSONPointer.java new file mode 100644 index 0000000..a05db98 --- /dev/null +++ b/JSONPointer.java @@ -0,0 +1,61 @@ +package org.json; + +import static java.lang.String.format; +import static java.util.Collections.emptyList; + +import java.util.ArrayList; +import java.util.List; + +public class JSONPointer { + + private List refTokens; + + public JSONPointer(String pointer) { + if (pointer == null) { + throw new NullPointerException("pointer cannot be null"); + } + if (pointer.isEmpty()) { + refTokens = emptyList(); + return; + } + if (pointer.startsWith("#/")) { + pointer = pointer.substring(2); + } else if (pointer.startsWith("/")) { + pointer = pointer.substring(1); + } else { + throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'"); + } + refTokens = new ArrayList(); + for (String token : pointer.split("/")) { + refTokens.add(unescape(token)); + } + } + + private String unescape(String token) { + return token.replace("~1", "/").replace("~0", "~"); + } + + public Object queryFrom(JSONObject document) { + if (refTokens.isEmpty()) { + return document; + } + Object current = document; + for (String token : refTokens) { + if (current instanceof JSONObject) { + current = ((JSONObject) current).opt(unescape(token)); + } else if (current instanceof JSONArray) { + current = readByIndexToken(current, unescape(token)); + } + } + return current; + } + + private Object readByIndexToken(Object current, String indexToken) { + try { + return ((JSONArray) current).opt(Integer.parseInt(unescape(indexToken))); + } catch (NumberFormatException e) { + throw new JSONPointerException(format("%s is not an array index", unescape(indexToken)), e); + } + } + +} diff --git a/JSONPointerException.java b/JSONPointerException.java new file mode 100644 index 0000000..599f0bb --- /dev/null +++ b/JSONPointerException.java @@ -0,0 +1,21 @@ +package org.json; + +/** + * The JSONPointerException is thrown by {@link JSONPointer} if an error occurs + * during evaluating a pointer. + * + * @author erosb + * + */ +public class JSONPointerException extends JSONException { + private static final long serialVersionUID = 8872944667561856751L; + + public JSONPointerException(String message) { + super(message); + } + + public JSONPointerException(String message, Throwable cause) { + super(message, cause); + } + +}