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

com.almworks.jira.structure.api.util.JsonUtil Maven / Gradle / Ivy

There is a newer version: 17.25.3
Show newest version
package com.almworks.jira.structure.api.util;

import com.atlassian.annotations.Internal;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.type.TypeReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;

import static org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES;

@Internal
public final class JsonUtil {
  private static final org.slf4j.Logger logger = LoggerFactory.getLogger(JsonUtil.class);

  public static final TypeReference> JSON_MAP = new TypeReference>() {
  };

  @NotNull
  public static String toJson(@Nullable Object object) {
    return toJson(object, defaultMapper());
  }

  @NotNull
  public static String toJson(@Nullable Object object, ObjectMapper mapper) {
    if (object == null) return "";
    try {
      return mapper.writeValueAsString(object);
    } catch (IOException e) {
      logger.warn("failed to serialize " + object, e);
      return "";
    }
  }

  @Nullable
  public static  T fromJson(String specJson, Class expectedClass) {
    return fromJson(specJson, expectedClass, defaultMapper());
  }

  @Nullable
  public static  T fromJson(String specJson, Class expectedClass, ObjectMapper mapper) {
    if (specJson == null || specJson.length() == 0) return null;
    try {
      return mapper.readValue(specJson, expectedClass);
    } catch (IOException e) {
      logger.warn("failed to deserialize " + specJson + " for " + expectedClass, e);
      return null;
    }
  }

  @Nullable
  public static  T fromJson(String json, TypeReference typeRef) {
    return fromJson(json, typeRef, defaultMapper());
  }

  @Nullable
  public static  T fromJson(String json, TypeReference typeRef, ObjectMapper mapper) {
    if (json == null || json.isEmpty()) {
      return null;
    }
    try {
      return mapper.readValue(json, typeRef);
    } catch (IOException e) {
      logger.warn("failed to deserialize " + json + " for " + typeRef, e);
      return null;
    }
  }

  public static Map fromJson(String json) {
    return fromJson(json, defaultMapper());
  }

  @Nullable
  public static Map fromJson(String json, ObjectMapper mapper) {
    return fromJson(json, JSON_MAP, mapper);
  }

  @Nullable
  public static  T fromMap(Map json, Class expectedClass) {
    return fromMap(json, expectedClass, defaultMapper());
  }

  @Nullable
  public static  T fromMap(Map json, Class expectedClass, ObjectMapper mapper) {
    if (json == null || json.isEmpty()) {
      return null;
    }
    try {
      return mapper.convertValue(json, expectedClass);
    } catch (IllegalArgumentException e) {
      logger.warn("failed to convert " + json + " to " + expectedClass, e);
      return null;
    }
  }

  @Nullable
  public static Map toMap(Object object) {
    return toMap(object, defaultMapper());
  }

  @Nullable
  public static Map toMap(Object object, ObjectMapper mapper) {
    try {
      return mapper.convertValue(object, JSON_MAP);
    } catch (IllegalArgumentException e) {
      logger.warn("failed to convert " + object + " to " + JSON_MAP, e);
      return null;
    }
  }

  public static ObjectMapper defaultMapper() {
    return new ObjectMapper().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
  }

  public static ObjectMapper withUnknownPropertiesMapper() {
    return defaultMapper().disable(FAIL_ON_UNKNOWN_PROPERTIES);
  }

  /**
   * We can't inline JSON into the page, because that stuff is read by the browser's HTML interpreter first rather than the JS interpreter, as it
   * would in AJAX. This means we must escape forward slashes to prevent XSS holes, because the HTML interpreter would pick up "" which is a
   * perfectly valid JSON string, but would terminate the script tag. Note: The "/" itself is not harmful, but in combination with a terminating
   * script tag it is.
   * The method is a full analog of com.atlassian.greenhopper.web.util.WebUtilities#encodeInlineJson(java.lang.String)
   */
  @NotNull
  public static String encodeInlineJson(@NotNull String json) {
    return json.replace("/", "\\/");
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy