JsonUtils.java

  1. /*******************************************************************************
  2.  * Copyright 2017 The MIT Internet Trust Consortium
  3.  *
  4.  * Portions copyright 2011-2013 The MITRE Corporation
  5.  *
  6.  * Licensed under the Apache License, Version 2.0 (the "License");
  7.  * you may not use this file except in compliance with the License.
  8.  * You may obtain a copy of the License at
  9.  *
  10.  *   http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  *******************************************************************************/
  18. /**
  19.  *
  20.  */
  21. package org.mitre.util;

  22. import java.io.IOException;
  23. import java.util.ArrayList;
  24. import java.util.Date;
  25. import java.util.HashMap;
  26. import java.util.HashSet;
  27. import java.util.List;
  28. import java.util.Map;
  29. import java.util.Set;

  30. import org.mitre.oauth2.model.PKCEAlgorithm;
  31. import org.slf4j.Logger;
  32. import org.slf4j.LoggerFactory;

  33. import com.google.common.collect.Lists;
  34. import com.google.common.collect.Sets;
  35. import com.google.gson.Gson;
  36. import com.google.gson.JsonElement;
  37. import com.google.gson.JsonNull;
  38. import com.google.gson.JsonObject;
  39. import com.google.gson.JsonSyntaxException;
  40. import com.google.gson.reflect.TypeToken;
  41. import com.google.gson.stream.JsonReader;
  42. import com.google.gson.stream.JsonWriter;
  43. import com.nimbusds.jose.EncryptionMethod;
  44. import com.nimbusds.jose.JWEAlgorithm;
  45. import com.nimbusds.jose.JWSAlgorithm;

  46. /**
  47.  * A collection of null-safe converters from common classes and JSON elements, using GSON.
  48.  *
  49.  * @author jricher
  50.  *
  51.  */
  52. @SuppressWarnings(value = {"rawtypes", "unchecked"})
  53. public class JsonUtils {

  54.     /**
  55.      * Logger for this class
  56.      */
  57.     private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);

  58.     private static Gson gson = new Gson();

  59.     /**
  60.      * Translate a set of strings to a JSON array, empty array returned as null
  61.      * @param value
  62.      * @return
  63.      */
  64.     public static JsonElement getAsArray(Set<String> value) {
  65.         return getAsArray(value, false);
  66.     }


  67.     /**
  68.      * Translate a set of strings to a JSON array, optionally preserving the empty array. Otherwise (default) empty array is returned as null.
  69.      * @param value
  70.      * @param preserveEmpty
  71.      * @return
  72.      */
  73.     public static JsonElement getAsArray(Set<String> value, boolean preserveEmpty) {
  74.         if (!preserveEmpty && value != null && value.isEmpty()) {
  75.             // if we're not preserving empty arrays and the value is empty, return null
  76.             return JsonNull.INSTANCE;
  77.         } else {
  78.             return gson.toJsonTree(value, new TypeToken<Set<String>>(){}.getType());
  79.         }
  80.     }

  81.     /**
  82.      * Gets the value of the given member (expressed as integer seconds since epoch) as a Date
  83.      */
  84.     public static Date getAsDate(JsonObject o, String member) {
  85.         if (o.has(member)) {
  86.             JsonElement e = o.get(member);
  87.             if (e != null && e.isJsonPrimitive()) {
  88.                 return new Date(e.getAsInt() * 1000L);
  89.             } else {
  90.                 return null;
  91.             }
  92.         } else {
  93.             return null;
  94.         }
  95.     }

  96.     /**
  97.      * Gets the value of the given member as a JWE Algorithm, null if it doesn't exist
  98.      */
  99.     public static JWEAlgorithm getAsJweAlgorithm(JsonObject o, String member) {
  100.         String s = getAsString(o, member);
  101.         if (s != null) {
  102.             return JWEAlgorithm.parse(s);
  103.         } else {
  104.             return null;
  105.         }
  106.     }

  107.     /**
  108.      * Gets the value of the given member as a JWE Encryption Method, null if it doesn't exist
  109.      */
  110.     public static EncryptionMethod getAsJweEncryptionMethod(JsonObject o, String member) {
  111.         String s = getAsString(o, member);
  112.         if (s != null) {
  113.             return EncryptionMethod.parse(s);
  114.         } else {
  115.             return null;
  116.         }
  117.     }

  118.     /**
  119.      * Gets the value of the given member as a JWS Algorithm, null if it doesn't exist
  120.      */
  121.     public static JWSAlgorithm getAsJwsAlgorithm(JsonObject o, String member) {
  122.         String s = getAsString(o, member);
  123.         if (s != null) {
  124.             return JWSAlgorithm.parse(s);
  125.         } else {
  126.             return null;
  127.         }
  128.     }

  129.     /**
  130.      * Gets the value of the given member as a PKCE Algorithm, null if it doesn't exist
  131.      * @param o
  132.      * @param member
  133.      * @return
  134.      */
  135.     public static PKCEAlgorithm getAsPkceAlgorithm(JsonObject o, String member) {
  136.         String s = getAsString(o, member);
  137.         if (s != null) {
  138.             return PKCEAlgorithm.parse(s);
  139.         } else {
  140.             return null;
  141.         }
  142.     }

  143.     /**
  144.      * Gets the value of the given member as a string, null if it doesn't exist
  145.      */
  146.     public static String getAsString(JsonObject o, String member) {
  147.         if (o.has(member)) {
  148.             JsonElement e = o.get(member);
  149.             if (e != null && e.isJsonPrimitive()) {
  150.                 return e.getAsString();
  151.             } else {
  152.                 return null;
  153.             }
  154.         } else {
  155.             return null;
  156.         }
  157.     }

  158.     /**
  159.      * Gets the value of the given member as a boolean, null if it doesn't exist
  160.      */
  161.     public static Boolean getAsBoolean(JsonObject o, String member) {
  162.         if (o.has(member)) {
  163.             JsonElement e = o.get(member);
  164.             if (e != null && e.isJsonPrimitive()) {
  165.                 return e.getAsBoolean();
  166.             } else {
  167.                 return null;
  168.             }
  169.         } else {
  170.             return null;
  171.         }
  172.     }

  173.     /**
  174.      * Gets the value of the given member as a Long, null if it doesn't exist
  175.      */
  176.     public static Long getAsLong(JsonObject o, String member) {
  177.         if (o.has(member)) {
  178.             JsonElement e = o.get(member);
  179.             if (e != null && e.isJsonPrimitive()) {
  180.                 return e.getAsLong();
  181.             } else {
  182.                 return null;
  183.             }
  184.         } else {
  185.             return null;
  186.         }
  187.     }

  188.     /**
  189.      * Gets the value of the given given member as a set of strings, null if it doesn't exist
  190.      */
  191.     public static Set<String> getAsStringSet(JsonObject o, String member) throws JsonSyntaxException {
  192.         if (o.has(member)) {
  193.             if (o.get(member).isJsonArray()) {
  194.                 return gson.fromJson(o.get(member), new TypeToken<Set<String>>(){}.getType());
  195.             } else {
  196.                 return Sets.newHashSet(o.get(member).getAsString());
  197.             }
  198.         } else {
  199.             return null;
  200.         }
  201.     }

  202.     /**
  203.      * Gets the value of the given given member as a set of strings, null if it doesn't exist
  204.      */
  205.     public static List<String> getAsStringList(JsonObject o, String member) throws JsonSyntaxException {
  206.         if (o.has(member)) {
  207.             if (o.get(member).isJsonArray()) {
  208.                 return gson.fromJson(o.get(member), new TypeToken<List<String>>(){}.getType());
  209.             } else {
  210.                 return Lists.newArrayList(o.get(member).getAsString());
  211.             }
  212.         } else {
  213.             return null;
  214.         }
  215.     }

  216.     /**
  217.      * Gets the value of the given member as a list of JWS Algorithms, null if it doesn't exist
  218.      */
  219.     public static List<JWSAlgorithm> getAsJwsAlgorithmList(JsonObject o, String member) {
  220.         List<String> strings = getAsStringList(o, member);
  221.         if (strings != null) {
  222.             List<JWSAlgorithm> algs = new ArrayList<>();
  223.             for (String alg : strings) {
  224.                 algs.add(JWSAlgorithm.parse(alg));
  225.             }
  226.             return algs;
  227.         } else {
  228.             return null;
  229.         }
  230.     }

  231.     /**
  232.      * Gets the value of the given member as a list of JWS Algorithms, null if it doesn't exist
  233.      */
  234.     public static List<JWEAlgorithm> getAsJweAlgorithmList(JsonObject o, String member) {
  235.         List<String> strings = getAsStringList(o, member);
  236.         if (strings != null) {
  237.             List<JWEAlgorithm> algs = new ArrayList<>();
  238.             for (String alg : strings) {
  239.                 algs.add(JWEAlgorithm.parse(alg));
  240.             }
  241.             return algs;
  242.         } else {
  243.             return null;
  244.         }
  245.     }

  246.     /**
  247.      * Gets the value of the given member as a list of JWS Algorithms, null if it doesn't exist
  248.      */
  249.     public static List<EncryptionMethod> getAsEncryptionMethodList(JsonObject o, String member) {
  250.         List<String> strings = getAsStringList(o, member);
  251.         if (strings != null) {
  252.             List<EncryptionMethod> algs = new ArrayList<>();
  253.             for (String alg : strings) {
  254.                 algs.add(EncryptionMethod.parse(alg));
  255.             }
  256.             return algs;
  257.         } else {
  258.             return null;
  259.         }
  260.     }

  261.     public static Map readMap(JsonReader reader) throws IOException {
  262.         Map map = new HashMap<>();
  263.         reader.beginObject();
  264.         while(reader.hasNext()) {
  265.             String name = reader.nextName();
  266.             Object value = null;
  267.             switch(reader.peek()) {
  268.                 case STRING:
  269.                     value = reader.nextString();
  270.                     break;
  271.                 case BOOLEAN:
  272.                     value = reader.nextBoolean();
  273.                     break;
  274.                 case NUMBER:
  275.                     value = reader.nextLong();
  276.                     break;
  277.                 default:
  278.                     logger.debug("Found unexpected entry");
  279.                     reader.skipValue();
  280.                     continue;
  281.             }
  282.             map.put(name, value);
  283.         }
  284.         reader.endObject();
  285.         return map;
  286.     }

  287.     public static Set readSet(JsonReader reader) throws IOException {
  288.         Set arraySet = null;
  289.         reader.beginArray();
  290.         switch (reader.peek()) {
  291.             case STRING:
  292.                 arraySet = new HashSet<>();
  293.                 while (reader.hasNext()) {
  294.                     arraySet.add(reader.nextString());
  295.                 }
  296.                 break;
  297.             case NUMBER:
  298.                 arraySet = new HashSet<>();
  299.                 while (reader.hasNext()) {
  300.                     arraySet.add(reader.nextLong());
  301.                 }
  302.                 break;
  303.             default:
  304.                 arraySet = new HashSet();
  305.                 break;
  306.         }
  307.         reader.endArray();
  308.         return arraySet;
  309.     }

  310.     public static void writeNullSafeArray(JsonWriter writer, Set<String> items) throws IOException {
  311.         if (items != null) {
  312.             writer.beginArray();
  313.             for (String s : items) {
  314.                 writer.value(s);
  315.             }
  316.             writer.endArray();
  317.         } else {
  318.             writer.nullValue();
  319.         }
  320.     }

  321. }