001package com.box.sdkgen.serialization.json;
002
003import com.box.sdkgen.internal.NullablePropertyFilter;
004import com.box.sdkgen.internal.SerializableObject;
005import com.fasterxml.jackson.core.JsonParser;
006import com.fasterxml.jackson.core.JsonProcessingException;
007import com.fasterxml.jackson.core.type.TypeReference;
008import com.fasterxml.jackson.databind.DeserializationFeature;
009import com.fasterxml.jackson.databind.JsonNode;
010import com.fasterxml.jackson.databind.ObjectMapper;
011import com.fasterxml.jackson.databind.ObjectWriter;
012import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
013import com.fasterxml.jackson.databind.util.TokenBuffer;
014import java.io.IOException;
015import java.net.URLEncoder;
016import java.util.HashMap;
017import java.util.Locale;
018import java.util.Map;
019
020public class JsonManager {
021
022  public static final ObjectMapper OBJECT_MAPPER =
023      new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
024
025  public static final SimpleFilterProvider EXPLICITLY_SET_FILTERS =
026      new SimpleFilterProvider()
027          .addFilter("nullablePropertyFilter", new NullablePropertyFilter())
028          .setFailOnUnknownId(false);
029
030  public static final ObjectWriter WRITER = OBJECT_MAPPER.writer(EXPLICITLY_SET_FILTERS);
031
032  public static JsonNode serialize(Object value) {
033    try {
034      TokenBuffer tokenBuffer = new TokenBuffer(OBJECT_MAPPER, false);
035      WRITER.writeValue(tokenBuffer, value);
036
037      JsonNode node = tokenBuffer.asParser().readValueAsTree();
038      tokenBuffer.close();
039
040      return node;
041    } catch (IOException e) {
042      throw new RuntimeException(e);
043    }
044  }
045
046  public static <T extends SerializableObject> T deserialize(JsonNode content, Class<T> valueType) {
047    T deserializedObject = OBJECT_MAPPER.convertValue(content, valueType);
048    deserializedObject.setRawData(content);
049    return deserializedObject;
050  }
051
052  public static JsonNode jsonToSerializedData(String text) {
053    try {
054      return OBJECT_MAPPER.readTree(text);
055    } catch (JsonProcessingException e) {
056      throw new RuntimeException(e);
057    }
058  }
059
060  public static JsonNode jsonToSerializedData(JsonParser jp) {
061    try {
062      return OBJECT_MAPPER.readTree(jp);
063    } catch (IOException e) {
064      throw new RuntimeException(e);
065    }
066  }
067
068  public static String sdToJson(JsonNode jsonNode) {
069    return jsonNode.toString();
070  }
071
072  public static String sdToUrlParams(JsonNode jsonNode) {
073    Map<String, String> map =
074        OBJECT_MAPPER.convertValue(jsonNode, new TypeReference<Map<String, String>>() {});
075    StringBuilder formData = new StringBuilder();
076    for (Map.Entry<String, String> entry : map.entrySet()) {
077      if (formData.length() != 0) {
078        formData.append('&');
079      }
080      formData.append(URLEncoder.encode(entry.getKey()));
081      formData.append('=');
082      formData.append(URLEncoder.encode(entry.getValue()));
083    }
084    return formData.toString();
085  }
086
087  public static String getSdValueByKey(JsonNode jsonNode, String key) {
088    return jsonNode.get(key).asText();
089  }
090
091  public static String sanitizedValue() {
092    return "---[redacted]---";
093  }
094
095  public static JsonNode sanitizeSerializedData(JsonNode sd, Map<String, String> keysToSanitize) {
096    if (sd == null || !sd.isObject()) {
097      return sd;
098    }
099    Map<String, JsonNode> sanitizedDictionary = new HashMap<>();
100    sd.fields()
101        .forEachRemaining(
102            entry -> {
103              String key = entry.getKey();
104              JsonNode value = entry.getValue();
105              if (keysToSanitize.containsKey(key.toLowerCase(Locale.ROOT)) && value.isTextual()) {
106                sanitizedDictionary.put(key, new ObjectMapper().valueToTree(sanitizedValue()));
107              } else if (value.isObject()) {
108                sanitizedDictionary.put(key, sanitizeSerializedData(value, keysToSanitize));
109              } else {
110                sanitizedDictionary.put(key, value);
111              }
112            });
113
114    return new ObjectMapper().valueToTree(sanitizedDictionary);
115  }
116}