Advertisement
Guest User

QueryObjectConverter for Retrofit2

a guest
Apr 25th, 2017
557
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.34 KB | None | 0 0
  1. import android.support.annotation.NonNull;
  2.  
  3. import com.google.gson.Gson;
  4. import com.google.gson.JsonElement;
  5.  
  6. import java.util.Collection;
  7. import java.util.LinkedHashSet;
  8. import java.util.Map;
  9. import java.util.Objects;
  10. import java.util.Optional;
  11. import java.util.Set;
  12. import java.util.stream.Collectors;
  13.  
  14. import javax.inject.Inject;
  15.  
  16. public class QueryObjectConverter {
  17.  
  18.     private final Gson gson;
  19.  
  20.     @Inject
  21.     public QueryObjectConverter(Gson gson) {
  22.         this.gson = gson;
  23.     }
  24.  
  25.     /**
  26.      * Converts an object to serialized URI parameters.
  27.      *
  28.      * @param value The value to be converted (can be an object or collection).
  29.      * @return Serialized URI parameters for use with {@literal @}{@link retrofit2.http.QueryMap}(encoded=true).
  30.      */
  31.     public Map<String, String> convert(Object value) {
  32.         return convertTree(gson.toJsonTree(value));
  33.     }
  34.  
  35.     /**
  36.      * Converts the given JSON tree to serialized URI parameters. This is equivalent to helpers.js/encodeParams.
  37.      *
  38.      * @param tree The JSON tree (can be an object or array).
  39.      * @return Serialized URI parameters for use with {@literal @}{@link retrofit2.http.QueryMap}(encoded=false).
  40.      */
  41.     public Map<String, String> convertTree(JsonElement tree) {
  42.         ParamsMap params = new ParamsMap();
  43.         if (tree.isJsonArray()) {
  44.             int i = 0;
  45.             for (JsonElement element : tree.getAsJsonArray()) {
  46.                 buildObjectParams(Integer.toString(i), element, params);
  47.                 i++;
  48.             }
  49.         } else if (tree.isJsonObject()) {
  50.             for (Map.Entry<String, JsonElement> entry : tree.getAsJsonObject().entrySet()) {
  51.                 buildObjectParams(entry.getKey(), entry.getValue(), params);
  52.             }
  53.         } else if (!tree.isJsonNull()) {
  54.             throw new IllegalArgumentException("Cannot convert " + tree.toString());
  55.         }
  56.         return params;
  57.     }
  58.  
  59.     /**
  60.      * Recursive helper method for {@link #convertTree(JsonElement)}. This is equivalent to helpers.js/buildObjectParams.
  61.      *
  62.      * @param prefix The prefix for the parameter names.
  63.      * @param tree   The remaining JSON tree.
  64.      * @param params The params object to write to.
  65.      */
  66.     private void buildObjectParams(String prefix, JsonElement tree, ParamsMap params) {
  67.         if (tree.isJsonArray()) {
  68.             int i = 0;
  69.             for (JsonElement element : tree.getAsJsonArray()) {
  70.                 buildObjectParams(prefix + "[" + i + "]", element, params);
  71.                 i++;
  72.             }
  73.         } else if (tree.isJsonObject()) {
  74.             for (Map.Entry<String, JsonElement> entry : tree.getAsJsonObject().entrySet()) {
  75.                 buildObjectParams(prefix + "[" + entry.getKey() + "]", entry.getValue(), params);
  76.             }
  77.         } else if (tree.isJsonPrimitive()) {
  78.             params.put(prefix, tree.getAsJsonPrimitive().getAsString());
  79.         }
  80.     }
  81.  
  82.     /**
  83.      * A map class that allows multiple entries per key.
  84.      */
  85.     private static class ParamsMap implements Map<String, String> {
  86.  
  87.         private final Set<Entry<String, String>> entries = new LinkedHashSet<>();
  88.  
  89.         @Override
  90.         public int size() {
  91.             return entries.size();
  92.         }
  93.  
  94.         @Override
  95.         public boolean isEmpty() {
  96.             return entries.isEmpty();
  97.         }
  98.  
  99.         @Override
  100.         public boolean containsKey(Object key) {
  101.             return entries.stream().anyMatch(entry -> entry.getKey().equals(key));
  102.         }
  103.  
  104.         @Override
  105.         public boolean containsValue(Object value) {
  106.             return entries.stream().anyMatch(entry -> entry.getValue().equals(value));
  107.         }
  108.  
  109.         /**
  110.          * @param key The key to look for.
  111.          * @return The value of the FIRST matching entry or null if none matches.
  112.          */
  113.         @Override
  114.         public String get(Object key) {
  115.             Optional<Entry<String, String>> result = entries.stream().filter(entry -> entry.getKey().equals(key)).findFirst();
  116.             return result.isPresent() ? result.get().getValue() : null;
  117.         }
  118.  
  119.         @Override
  120.         public String put(String key, String value) {
  121.             entries.add(new ParamEntry(key, value));
  122.             return null;
  123.         }
  124.  
  125.         @Override
  126.         public String remove(Object key) {
  127.  
  128.             return null;
  129.         }
  130.  
  131.         @Override
  132.         public void putAll(@NonNull Map<? extends String, ? extends String> m) {
  133.             for (Entry<? extends String, ? extends String> entry : m.entrySet()) {
  134.                 put(entry.getKey(), entry.getValue());
  135.             }
  136.         }
  137.  
  138.         @Override
  139.         public void clear() {
  140.             entries.clear();
  141.         }
  142.  
  143.         @NonNull
  144.         @Override
  145.         public Set<String> keySet() {
  146.             return entries.stream().map(Entry::getKey).collect(Collectors.toSet());
  147.         }
  148.  
  149.         @NonNull
  150.         @Override
  151.         public Collection<String> values() {
  152.             return entries.stream().map(Entry::getValue).collect(Collectors.toList());
  153.         }
  154.  
  155.         @NonNull
  156.         @Override
  157.         public Set<Entry<String, String>> entrySet() {
  158.             return entries;
  159.         }
  160.     }
  161.  
  162.     private static class ParamEntry implements Map.Entry<String, String> {
  163.         private final String key;
  164.         private final String value;
  165.  
  166.         public ParamEntry(String key, String value) {
  167.             this.key = Objects.requireNonNull(key);
  168.             this.value = Objects.requireNonNull(value);
  169.         }
  170.  
  171.         @Override
  172.         public String getKey() {
  173.             return key;
  174.         }
  175.  
  176.         @Override
  177.         public String getValue() {
  178.             return value;
  179.         }
  180.  
  181.         @Override
  182.         public String setValue(String value) {
  183.             throw new UnsupportedOperationException();
  184.         }
  185.  
  186.         @Override
  187.         public boolean equals(Object o) {
  188.             if (this == o) return true;
  189.             if (o == null || getClass() != o.getClass()) return false;
  190.             ParamEntry that = (ParamEntry) o;
  191.             return key.equals(that.key) && value.equals(that.value);
  192.  
  193.         }
  194.  
  195.         @Override
  196.         public int hashCode() {
  197.             int result = key.hashCode();
  198.             result = 31 * result + value.hashCode();
  199.             return result;
  200.         }
  201.     }
  202.  
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement