All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.zuunr.jsonpointer.JsonPointer Maven / Gradle / Ivy

package com.zuunr.jsonpointer;

import com.zuunr.json.JsonArray;
import com.zuunr.json.JsonArrayBuilder;
import com.zuunr.json.JsonValue;

/**
 * @author Niklas Eldberger
 */
public class JsonPointer {

    private static final JsonValue FRAGMENT_START = JsonValue.of("#");

    private String asString;
    private JsonArray asArray;

    public static JsonPointer of(String pointer) {
        JsonArrayBuilder builder = JsonArray.EMPTY.builder();
        JsonArray array = JsonArray.of(pointer.split("/"));
        if (pointer.endsWith("/")) {
            array = array.add("");
        }
        if (FRAGMENT_START.equals(array.head())) {
            array = array.tail();
        }
        for (JsonValue referenceTokenJsonValue : array) {

            Integer integer = integerOf(referenceTokenJsonValue.asString());
            if (integer == null) {
                JsonValue unescaped = unescape(referenceTokenJsonValue);
                builder.add(unescaped);
            } else {
                builder.add(integer);
            }
        }
        return new JsonPointer(pointer, builder.build());
    }

    public static JsonPointer of(JsonArray array) {
        JsonArrayBuilder builder = JsonArray.EMPTY.builder();
        StringBuilder stringBuilder = null;
        for (JsonValue unescapedReferenceToken : array) {
            JsonValue escaped;
            if (unescapedReferenceToken.isString()) {
                escaped = escape(unescapedReferenceToken);
            } else if (unescapedReferenceToken.isInteger()) {
                escaped = unescapedReferenceToken;
            } else {
                throw new RuntimeException("Only Integer and String is supported");
            }

            if (stringBuilder == null) {
                stringBuilder = new StringBuilder();
            } else {
                stringBuilder.append("/");
            }
            builder.add(escaped);
            stringBuilder.append(escaped.isString() ? escaped.asString() : escaped.toString());
        }
        return new JsonPointer(stringBuilder.toString(), builder.build());
    }

    private JsonPointer(String pointer, JsonArray pointerArray) {
        this.asString = pointer;
        this.asArray = pointerArray;
    }

    private static JsonValue unescape(JsonValue referenceTokenJsonValue) {
        String unescaped = referenceTokenJsonValue.asString().replace("~1", "/");
        unescaped = unescaped.replace("~0", "~");
        unescaped = decodeHex(unescaped);
        return JsonValue.of(unescaped);
    }

    public static String decodeHex(String stringWithHex) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < stringWithHex.length(); i++) {
            char charToAppend;
            if (stringWithHex.charAt(i) == '%' && i < stringWithHex.length() - 2) {
                String hexValue = stringWithHex.substring(i + 1, i + 3);
                charToAppend = (char) Integer.parseInt(hexValue, 16);
                i = i + 2;
            } else {
                charToAppend = stringWithHex.charAt(i);
            }
            builder.append(charToAppend);
        }
        return builder.toString();
    }

    private static JsonValue escape(JsonValue unescaped) {
        String escaped = unescaped.asString().replace("~", "~0");
        escaped = escaped.replace("/", "~1");
        return JsonValue.of(escaped);
    }

    public JsonArray asJsonArray() {
        return asArray;
    }

    public String asString() {
        return asString;
    }

    @Override
    public String toString() {
        return asString();
    }

    private static Integer integerOf(String string) {
        try {
            return Integer.parseInt(string);
        } catch (Exception e) {
            return null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy