diff --git a/src/main/java/com/gravity9/jsonpatch/JsonPathParser.java b/src/main/java/com/gravity9/jsonpatch/JsonPathParser.java index 231c29a1..fe70c2a2 100644 --- a/src/main/java/com/gravity9/jsonpatch/JsonPathParser.java +++ b/src/main/java/com/gravity9/jsonpatch/JsonPathParser.java @@ -1,29 +1,36 @@ package com.gravity9.jsonpatch; +import java.util.Arrays; + public class JsonPathParser { - private JsonPathParser() {} + private JsonPathParser() { + } - private static final String ARRAY_ELEMENT_REGEX = "(?<=\\.)(\\d+)"; + private static final String ARRAY_ELEMENT_REGEX = "\\A((\\d+)[^a-zA-Z]*)\\z"; - /** - * Method parses JsonPointer or JsonPath path to JsonPath syntax - * @param path String containing JsonPath or JsonPointer expression - * @return String containing JsonPath expression - * @throws JsonPatchException throws when invalid JsonPointer expression provided - */ - public static String parsePathToJsonPath(String path) throws JsonPatchException { - if (path.startsWith("$")) { - return path; - } else if (path.contains("?")) { - throw new JsonPatchException("Invalid path, `?` are not allowed in JsonPointer expressions."); - } else if (path.contains("//")) { - throw new JsonPatchException("Invalid path, `//` is not allowed in JsonPointer expressions."); - } + /** + * Method parses JsonPointer or JsonPath path to JsonPath syntax + * + * @param path String containing JsonPath or JsonPointer expression + * @return String containing JsonPath expression + * @throws JsonPatchException throws when invalid JsonPointer expression provided + */ + public static String parsePathToJsonPath(String path) throws JsonPatchException { + if (path.startsWith("$")) { + return path; + } else if (path.contains("?")) { + throw new JsonPatchException("Invalid path, `?` are not allowed in JsonPointer expressions."); + } else if (path.contains("//")) { + throw new JsonPatchException("Invalid path, `//` is not allowed in JsonPointer expressions."); + } - return "$" + path.replace('/', '.') - .replace("~1", "/") // / must be escaped in JsonPointer using ~1 - .replace("~0", "~") // ~ must be escaped in JsonPointer using ~0 - .replaceAll(ARRAY_ELEMENT_REGEX, "[$1]"); - } + return "$" + Arrays.stream(path.replace('/', '.') + .replace("~1", "/") // / must be escaped in JsonPointer using ~1 + .replace("~0", "~") // ~ must be escaped in JsonPointer using ~0 + .split("\\.")) // split string to analyze every path field separately + .filter(s -> !s.isEmpty()) // skip empty string on the beginning of the array + .map(s -> s.replaceAll(ARRAY_ELEMENT_REGEX, "[$1]")) + .reduce("", (s, s2) -> s + "." + s2); //connect the path + } } diff --git a/src/test/resources/jsonpatch/move.json b/src/test/resources/jsonpatch/move.json index 2d1e3d87..07ade959 100644 --- a/src/test/resources/jsonpatch/move.json +++ b/src/test/resources/jsonpatch/move.json @@ -1090,6 +1090,24 @@ }, "expensive": 10 } + }, + { + "op": { "op": "move", "from": "/5gStringToMove", "path": "/5gStringMoved" }, + "node": { + "5gStringToMove":"exists" + }, + "expected": { + "5gStringMoved":"exists" + } + }, + { + "op": { "op": "move", "from": "/String123ToMove", "path": "/StringMoved5g" }, + "node": { + "String123ToMove":"exists" + }, + "expected": { + "StringMoved5g":"exists" + } } ] } \ No newline at end of file