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

de.gold.scim.common.utils.JsonHelper Maven / Gradle / Ivy

The newest version!
package de.gold.scim.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;

import de.gold.scim.common.constants.ScimType;
import de.gold.scim.common.exceptions.IncompatibleAttributeException;
import de.gold.scim.common.exceptions.InternalServerException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;


/**
 * author Pascal Knueppel 
* created at: 28.09.2019 - 00:05
*
*/ @Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class JsonHelper { /** * will read a json document from the classpath * * @param classPathLocation the location of the document * @return the parsed json document */ public static JsonNode loadJsonDocument(String classPathLocation) { log.trace("trying to read classpath resource from: {}", classPathLocation); try (InputStream inputStream = JsonHelper.class.getResourceAsStream(classPathLocation)) { return new ObjectMapper().readTree(inputStream); } catch (IOException e) { throw de.gold.scim.common.exceptions.IOException.builder().message(e.getMessage()).cause(e).build(); } } /** * will read a json document from the classpath * * @param classPathLocation the location of the document * @return the parsed json document */ public static T loadJsonDocument(String classPathLocation, Class type) { log.trace("trying to read classpath resource from: {}", classPathLocation); try (InputStream inputStream = JsonHelper.class.getResourceAsStream(classPathLocation)) { JsonNode jsonNode = new ObjectMapper().readTree(inputStream); return copyResourceToObject(jsonNode, type); } catch (IOException e) { throw de.gold.scim.common.exceptions.IOException.builder().message(e.getMessage()).cause(e).build(); } } /** * will read a json document from a file * * @param file the location of the document * @return the parsed json document */ public static T loadJsonDocument(File file, Class type) { log.trace("trying to read classpath resource from: {}", file.getAbsolutePath()); try (InputStream inputStream = new FileInputStream(file)) { JsonNode jsonNode = new ObjectMapper().readTree(inputStream); return copyResourceToObject(jsonNode, type); } catch (IOException e) { throw de.gold.scim.common.exceptions.IOException.builder().message(e.getMessage()).cause(e).build(); } } /** * will read a json document from a file * * @param file the location of the document * @return the parsed json document */ public static JsonNode loadJsonDocument(File file) { log.trace("trying to read classpath resource from: {}", file.getAbsolutePath()); try (InputStream inputStream = new FileInputStream(file)) { return new ObjectMapper().readTree(inputStream); } catch (IOException e) { throw de.gold.scim.common.exceptions.IOException.builder().message(e.getMessage()).cause(e).build(); } } /** * will read a json document from the given string * * @param jsonDocument the direct json representation * @return the parsed json document */ public static JsonNode readJsonDocument(String jsonDocument) { if (StringUtils.isBlank(jsonDocument)) { return null; } log.trace("trying to read json document: {}", jsonDocument); try (Reader reader = new StringReader(jsonDocument)) { return new ObjectMapper().readTree(reader); } catch (IOException e) { throw de.gold.scim.common.exceptions.IOException.builder() .message("Invalid content, the document could not be parsed") .cause(e) .build(); } } /** * will read a json document from the given string * * @param jsonDocument the direct json representation * @return the parsed json document */ public static T readJsonDocument(String jsonDocument, Class type) { log.trace("trying to read json document: {}", jsonDocument); try (Reader reader = new StringReader(jsonDocument)) { JsonNode jsonNode = new ObjectMapper().readTree(reader); return copyResourceToObject(jsonNode, type); } catch (IOException e) { throw de.gold.scim.common.exceptions.IOException.builder() .message("Invalid content, the document could not be parsed") .cause(e) .build(); } } /** * tries to get an array from the given json node * * @param jsonNode the json node from which the array should be extracted * @param name the name of the json array attribute * @return the json array attribute or an empty if the attribute is not present */ public static Optional getArrayAttribute(JsonNode jsonNode, String name) { JsonNode attribute = Objects.requireNonNull(jsonNode, "jsonNode must not be null").get(name); if (attribute == null) { return Optional.empty(); } if (attribute.isArray()) { return Optional.of((ArrayNode)attribute); } throw IncompatibleAttributeException.builder() .message("attribute with name '" + name + "' is not of type array") .build(); } /** * tries to get an json object from the given json node * * @param jsonNode the json node from which the json object should be extracted * @param name the name of the json object attribute * @return the json object attribute or an empty if the attribute is not present */ public static Optional getObjectAttribute(JsonNode jsonNode, String name) { JsonNode attribute = Objects.requireNonNull(jsonNode, "jsonNode must not be null").get(name); if (attribute == null) { return Optional.empty(); } if (attribute.isObject()) { return Optional.of((ObjectNode)attribute); } throw IncompatibleAttributeException.builder() .message("attribute with name '" + name + "' is not of type object") .build(); } /** * extracts a list of simple attributes from the given json node * * @param jsonNode the json document containing an array with simple attributes * @param attributeName the name of the attribute that is an array with simple attributes * @return a list of attributes or an empty */ public static Optional> getSimpleAttributeArray(JsonNode jsonNode, String attributeName) { return getSimpleAttributeArray(jsonNode, attributeName, String.class); } /** * extracts a list of simple attributes from the given json node * * @param jsonNode the json document containing an array with simple attributes * @param attributeName the name of the attribute that is an array with simple attributes * @param type the type of the values within the array * @return a list of attributes or an empty */ public static Optional> getSimpleAttributeArray(JsonNode jsonNode, String attributeName, Class type) { Optional simpleArrayOptional = getArrayAttribute(jsonNode, attributeName); if (!simpleArrayOptional.isPresent()) { return Optional.empty(); } JsonNode simpleArray = simpleArrayOptional.get(); if (simpleArray.isObject()) { final String errorMessage = "attribute '" + attributeName + "' is not a simple array attribute"; throw IncompatibleAttributeException.builder().message(errorMessage).build(); } List arrayResult = new ArrayList<>(); for ( JsonNode node : simpleArray ) { getAsAttribute(node, type).ifPresent(arrayResult::add); } return Optional.of(arrayResult); } /** * will get a string attribute with the given name from the given json node * * @param jsonNode the json node to get the attribute from * @param name the name of the attribute * @return the value as string or an empty */ public static Optional getSimpleAttribute(JsonNode jsonNode, String name) { return getSimpleAttribute(jsonNode, name, String.class); } /** * will get a string attribute with the given name from the given json node * * @param jsonNode the json node to get the attribute from * @param name the name of the attribute * @param type the type of the attribute to return * @return the value of the given type or an empty */ public static Optional getSimpleAttribute(JsonNode jsonNode, String name, Class type) { JsonNode attribute = Objects.requireNonNull(jsonNode, "jsonNode must not be null").get(name); if (attribute == null) { return Optional.empty(); } if (attribute.isNull()) { return Optional.empty(); } if (attribute.isArray()) { throw IncompatibleAttributeException.builder() .message("attribute '" + name + "' is not of type " + type.getSimpleName()) .build(); } return getAsAttribute(attribute, type); } /** * will remove an attribute from the given jsonNode * * @param jsonNode the json node from which the attribute should be removed * @param attributeName the name of the attribute to remove */ public static JsonNode removeAttribute(JsonNode jsonNode, String attributeName) { return ((ObjectNode)jsonNode).remove(attributeName); } /** * will remove a simple value from a simple array node in the given json document * * @param jsonNode the array from which the value should be removed * @param value the value that should be removed from the document */ public static JsonNode removeSimpleAttributeFromArray(JsonNode jsonNode, String value) { if (jsonNode == null) { return null; } if (!jsonNode.isArray()) { log.error("cannot remove value '{}' from a json node that is not a simple array", value); return jsonNode; } int index = -1; for ( int i = 0 ; i < jsonNode.size() ; i++ ) { JsonNode simpleNode = jsonNode.get(i); if (simpleNode.isObject() || simpleNode.isArray()) { break; } if (simpleNode.textValue().equals(value)) { index = i; break; } } if (index > -1) { ((ArrayNode)jsonNode).remove(index); } else { log.error("could not remove value '{}' from json array because its sub-elements are not primitive types", value); } return jsonNode; } /** * will remove an attribute from the given jsonNode * * @param jsonNode the json node from which the attribute should be removed * @param attributeName the name of the attribute to remove * @param newAttriute the new attribute that should be added */ public static JsonNode addAttribute(JsonNode jsonNode, String attributeName, JsonNode newAttriute) { return ((ObjectNode)jsonNode).set(attributeName, newAttriute); } /** * will remove an attribute from the given jsonNode * * @param jsonArray the json node from which the attribute should be removed * @param newAttriute the new attribute that should be added */ public static JsonNode addAttributeToArray(JsonNode jsonArray, JsonNode newAttriute) { return ((ArrayNode)jsonArray).add(newAttriute); } /** * will remove an attribute from the given jsonNode * * @param jsonNode the json node from which the attribute should be removed * @param attributeName the name of the attribute to remove * @param value the value of the new replaced node */ public static JsonNode writeValue(JsonNode jsonNode, String attributeName, T value) { JsonNode valueNode = new TextNode(String.valueOf(value)); return ((ObjectNode)jsonNode).replace(attributeName, valueNode); } /** * will remove an attribute from the given jsonNode * * @param jsonNode the json node from which the attribute should be removed * @param attributeName the name of the attribute to remove * @param replaceNode the new node that should be used as replacement */ public static JsonNode replaceNode(JsonNode jsonNode, String attributeName, JsonNode replaceNode) { return ((ObjectNode)jsonNode).replace(attributeName, replaceNode); } /** * gets the simple attribute of the given json node * * @param attribute the json node that should be a simple attribute * @param type the type to extract * @return the extracted attribute or an empty */ private static Optional getAsAttribute(JsonNode attribute, Class type) { if (String.class.equals(type)) { return Optional.of((T)attribute.asText()); } if (Boolean.class.equals(type)) { return Optional.of((T)Boolean.valueOf(attribute.asBoolean())); } if (Integer.class.equals(type)) { return Optional.of((T)Integer.valueOf(attribute.asInt())); } if (Long.class.equals(type)) { return Optional.of((T)Long.valueOf(attribute.asLong())); } if (Float.class.equals(type)) { return Optional.of((T)Float.valueOf((float)attribute.asDouble())); } if (Double.class.equals(type)) { return Optional.of((T)Double.valueOf(attribute.asDouble())); } if (Long.class.equals(type)) { return Optional.of((T)Long.valueOf(attribute.asLong())); } throw IncompatibleAttributeException.builder() .message("attribute '" + attribute + "' is not of type" + type.getSimpleName()) .build(); } /** * creates a new instance of the given type and moves the content from the resource into the new node * * @param resource the resource that holds the content that must be moved to the new object * @param type the type from which an instance will be created with a noArgs constructor * @return a newly created instance with the content of the {@code resource}-node */ public static T copyResourceToObject(JsonNode resource, Class type) { if (resource == null) { return null; } if (resource.isArray()) { throw new IncompatibleAttributeException("operation not possible for array", null, null, ScimType.Custom.INVALID_PARAMETERS); } if (type.isAssignableFrom(resource.getClass())) { return (T)resource; } T newInstance = getNewInstance(type); resource.fields().forEachRemaining(stringJsonNodeEntry -> { JsonHelper.addAttribute(newInstance, stringJsonNodeEntry.getKey(), stringJsonNodeEntry.getValue()); }); return newInstance; } /** * creates a new instance of the given type * * @param type the type from which a new instance will be created * @param the type must define a noArgs constructor * @return the newly created instance */ private static T getNewInstance(Class type) { try { return type.newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new InternalServerException("could not create instance of type '" + type + "': " + e.getMessage(), e, null); } } /** * will extract a scim attribute by its scim-name. * * @param attributeName the scim name of the attribute e.g. "userName" of "name.givenName" * @return the json node or an empty */ public static Optional getSimpleAttributeByName(JsonNode jsonNode, String attributeName) { String[] nameParts = attributeName.split("\\."); JsonNode subNode = jsonNode.get(nameParts[0]); if (nameParts.length == 1) { return Optional.ofNullable(subNode); } return Optional.ofNullable(subNode.get(nameParts[1])); } /** * validates if the given string structure is valid json or not * * @param json the string to validate * @return true if the given string is a valid json structure, false else */ public static boolean isValidJson(final String json) { try { final JsonParser parser = new ObjectMapper().getFactory().createParser(json); while (parser.nextToken() != null) {} return true; } catch (IOException ex) { log.trace(ex.getMessage()); return false; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy