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

com.fasterxml.jackson.contrib.jsonpath.util.JsonPathUtil Maven / Gradle / Ivy

package com.fasterxml.jackson.contrib.jsonpath.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;


/**
 * Various util methods for getting/fixing Json paths, taken from annotations.
 * Some paths are handled by Jway fmwk, but not all.
 *
 */
public class JsonPathUtil {

	/**
	 * Make a string out of all elements in the json collection.
	 *
	 * @param jsonPathStack the collection of json paths.
	 * @return the string representation.
	 */
	public String getJsonPath(final Collection jsonPathStack) {
		StringBuilder stringBuilder = new StringBuilder();
		String delimiter = "";
		for (String entry : jsonPathStack) {
			stringBuilder.append(delimiter);
			stringBuilder.append(entry);
			delimiter = ".";
		}
		return stringBuilder.toString();
	}

	/**
	 * Construct proper Json path using JsonProperty and JsonPath annotations.
	 * If parentJsonPath is empty then first JsonProperty/JsonPath will be resolved as absolute;
	 * all subsequent annotation values will be resolved as relative
	 *
	 * @param candidateField wraps Json annotations.
	 * @param parentJsonPath the current relative json path.
	 * @return the relative json path of the passed field.
	 */
	public Collection resolveRelativeJsonPaths(final CandidateField candidateField,
			final Collection parentJsonPath) {

		String fieldJsonPath = candidateField.getJsonPathFromField();

		if (fieldJsonPath.charAt(0) == '$' && !parentJsonPath.isEmpty()) { //Handle new absolute json path defined on field
			return makeNewRootRelativePath(fieldJsonPath);
		}

		return updateExistingRelativePath(parentJsonPath, fieldJsonPath);
	}

	private Collection makeNewRootRelativePath(final String jsonPathVal) {
		return Arrays.asList(jsonPathVal);
	}

	private Collection updateExistingRelativePath(final Collection parentJsonPath, final String jsonPathVal) {
		List currentJsonPath = new ArrayList<>(parentJsonPath);
		String jsonPathPrefixRegex = "^[^.]*\\.";
		String sanitizedJsonPathValue = jsonPathVal.replaceFirst(jsonPathPrefixRegex, "");

		if (currentJsonPath.isEmpty()) { //transform first Jackson property into JsonPath root
			currentJsonPath.add("$." + sanitizedJsonPathValue);
		} else {
			currentJsonPath.add(sanitizedJsonPathValue); //all other jackson properties will be simply appended
		}
		return currentJsonPath;
	}

	/**
	 * Build correct Jway Json path when provided annotation value may not be valid.
	 * E.g. paths like path @path or $path will not be resolved properly by Jway
	 *
	 * @param jsonPath current field json path.
	 * @param parentJsonPath parent json path.
	 * @return the correct json path for the current field.
	 */
	public String buildCorrectJsonPath(final String jsonPath, final String parentJsonPath) {

		final String correctParentJsonPath = "".equals(parentJsonPath) ? "$" : parentJsonPath;

		//matches @.path   $.path  .path
		if (jsonPath.matches("[@\\$]?[.].+")) {
			if (jsonPath.charAt(0) == '@') {
				return correctParentJsonPath + jsonPath.substring(1);
			}
			if (jsonPath.charAt(0) == '.') {
				return correctParentJsonPath + jsonPath;
			}
			return jsonPath;
		}

		//path like @path is invalid should be resolved as relative or absolute, depending on parent path
		if (jsonPath.charAt(0) == '@') {
			return correctParentJsonPath + "." + jsonPath.substring(1);
		}

		//path like $path is invalid should be resolved as absolute
		if (jsonPath.charAt(0) == '$') {
			return "$." + jsonPath.substring(1);
		}

		//any path that doesn't start with @ or $
		return correctParentJsonPath + "." + jsonPath;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy