001package com.gigya.android.sdk.api; 002 003import android.support.annotation.Nullable; 004 005import com.gigya.android.sdk.GigyaLogger; 006import com.gigya.android.sdk.utils.ObjectUtils; 007import com.google.gson.Gson; 008 009import org.json.JSONException; 010import org.json.JSONObject; 011 012import java.util.Map; 013 014/** 015 * Gigya generic response class. 016 */ 017public class GigyaApiResponse { 018 019 private static final String LOG_TAG = "GigyaApiResponse"; 020 021 public static final int INVALID_VALUE = -1; 022 public static final int OK = 200; 023 024 private String json; 025 private Map<String, Object> mapped; 026 027 // GSON Support. 028 private Gson gson = new Gson(); 029 030 public Gson getGson() { 031 return gson; 032 } 033 034 public GigyaApiResponse(String json) { 035 this.json = json; 036 try { 037 JSONObject jo = new JSONObject(json); 038 mapped = ObjectUtils.toMap(jo); 039 GigyaLogger.debug(LOG_TAG, "json mapped!"); 040 } catch (JSONException e) { 041 e.printStackTrace(); 042 } 043 } 044 045 /** 046 * Get JSON formatted of the current response. 047 * 048 * @return JSON formatted String. 049 */ 050 public String asJson() { 051 return this.json; 052 } 053 054 /** 055 * Optional parsing of the current response with generic given type. Uses GSON as the parsing engine. 056 * 057 * @param clazz Requested type for parsing. 058 * @return Parsed hard copy class according to provided type. 059 */ 060 @Nullable 061 public <T> T parseTo(Class<T> clazz) { 062 try { 063 return getGson().fromJson(asJson(), clazz); 064 } catch (Exception ex) { 065 ex.printStackTrace(); 066 } 067 return null; 068 } 069 070 /** 071 * Check if response parameters contains a specific key. 072 * 073 * @param key Required key for evaluation. 074 * @return TRUE of key is present. 075 */ 076 @SuppressWarnings("LoopStatementThatDoesntLoop") 077 public boolean contains(String key) { 078 return mapped.containsKey(key); 079 } 080 081 /** 082 * Check if response parameters contains a specific nested key. 083 * Nested key example: profile.firstName 084 * 085 * @param key Required key for evaluation. 086 * @return TRUE of nested key is present. 087 */ 088 public boolean containsNested(String key) { 089 String[] split = key.split("\\."); 090 if (split.length == 1) { 091 return mapped.containsKey(key); 092 } else { 093 Map map = mapped; 094 for (int i = 0; i < split.length; i++) { 095 Object obj = map.get(split[i]); 096 if (obj == null) { 097 return false; 098 } 099 if (obj instanceof Map) { 100 map = (Map) obj; 101 } else if (i < split.length - 1) { 102 return false; 103 } 104 } 105 return true; 106 } 107 } 108 109 /** 110 * Type field optional getter. 111 * Allows fetching an parsed object from response parameters given required type. 112 * Uses GSON as the parsing engine. 113 * 114 * @param key Requested parameter key. 115 * @param clazz Required parsed object type. 116 * @return Parsed hard copy class according to provided key and type. 117 */ 118 @SuppressWarnings("unchecked") 119 @Nullable 120 public <T> T getField(String key, Class<T> clazz) { 121 String[] split = key.split("\\."); 122 if (split.length == 1) { 123 if (mapped.containsKey(key)) { 124 final String json = gson.toJson(mapped.get(key)); 125 return gson.fromJson(json, clazz); 126 } 127 } 128 if (containsNested(key)) { 129 Map map = mapped; 130 Object obj = null; 131 for (int i = 0; i < split.length; i++) { 132 obj = map.get(split[i]); 133 if (i < split.length - 1) { 134 map = (Map) obj; 135 } 136 } 137 if (obj == null) { 138 return null; 139 } 140 if (obj.getClass() == clazz) { 141 return (T) obj; 142 } 143 } else { 144 return null; 145 } 146 return null; 147 } 148 149 //region ROOT ELEMENT GETTERS 150 151 /** 152 * Get response status code 153 * 154 * @return Integer status code. 155 */ 156 public int getStatusCode() { 157 try { 158 return (int) mapped.get("statusCode"); 159 } catch (Exception ex) { 160 ex.printStackTrace(); 161 return INVALID_VALUE; 162 } 163 } 164 165 /** 166 * Get response error code. 167 * 168 * @return Integer error code. 169 */ 170 public int getErrorCode() { 171 try { 172 return (int) mapped.get("errorCode"); 173 } catch (Exception ex) { 174 ex.printStackTrace(); 175 return INVALID_VALUE; 176 } 177 } 178 179 /** 180 * Get response error details if exists. 181 * 182 * @return String error details. 183 */ 184 @Nullable 185 public String getErrorDetails() { 186 if (mapped.containsKey("errorDetails")) { 187 return (String) mapped.get("errorDetails"); 188 } 189 return null; 190 } 191 192 /** 193 * Get response status reason if exists. 194 * 195 * @return String status reason. 196 */ 197 @Nullable 198 public String getStatusReason() { 199 if (mapped.containsKey("statusReason")) { 200 return (String) mapped.get("statusReason"); 201 } 202 return null; 203 } 204 205 /** 206 * Get response callId. 207 * 208 * @return String callId. 209 */ 210 @Nullable 211 public String getCallId() { 212 if (mapped.containsKey("callId")) { 213 return (String) mapped.get("callId"); 214 } 215 return null; 216 } 217 218 /** 219 * Get response time. 220 * 221 * @return String formatted timestamp. 222 */ 223 @Nullable 224 public String getTime() { 225 if (mapped.containsKey("time")) { 226 return (String) mapped.get("time"); 227 } 228 return null; 229 } 230 231 //endregion 232}