1*3ba32fe9SKudo Chien /* 2*3ba32fe9SKudo Chien * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. 3*3ba32fe9SKudo Chien * 4*3ba32fe9SKudo Chien * You are hereby granted a non-exclusive, worldwide, royalty-free license to use, 5*3ba32fe9SKudo Chien * copy, modify, and distribute this software in source code or binary form for use 6*3ba32fe9SKudo Chien * in connection with the web services and APIs provided by Facebook. 7*3ba32fe9SKudo Chien * 8*3ba32fe9SKudo Chien * As with any software that integrates with the Facebook platform, your use of 9*3ba32fe9SKudo Chien * this software is subject to the Facebook Developer Principles and Policies 10*3ba32fe9SKudo Chien * [http://developers.facebook.com/policy/]. This copyright notice shall be 11*3ba32fe9SKudo Chien * included in all copies or substantial portions of the software. 12*3ba32fe9SKudo Chien * 13*3ba32fe9SKudo Chien * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14*3ba32fe9SKudo Chien * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15*3ba32fe9SKudo Chien * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16*3ba32fe9SKudo Chien * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17*3ba32fe9SKudo Chien * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18*3ba32fe9SKudo Chien * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19*3ba32fe9SKudo Chien */ 20*3ba32fe9SKudo Chien 21*3ba32fe9SKudo Chien package host.exp.exponent.utils 22*3ba32fe9SKudo Chien 23*3ba32fe9SKudo Chien import android.os.Bundle 24*3ba32fe9SKudo Chien import org.json.JSONArray 25*3ba32fe9SKudo Chien import org.json.JSONException 26*3ba32fe9SKudo Chien import org.json.JSONObject 27*3ba32fe9SKudo Chien 28*3ba32fe9SKudo Chien /** 29*3ba32fe9SKudo Chien * Referenced from [com.facebook.internal.BundleJSONConverter] 30*3ba32fe9SKudo Chien * https://github.com/facebook/facebook-android-sdk/blob/main/facebook-core/src/main/java/com/facebook/internal/BundleJSONConverter.kt 31*3ba32fe9SKudo Chien * 32*3ba32fe9SKudo Chien * com.facebook.internal is solely for the use of other packages within the Facebook SDK for 33*3ba32fe9SKudo Chien * Android. Use of any of the classes in this package is unsupported, and they may be modified or 34*3ba32fe9SKudo Chien * removed without warning at any time. 35*3ba32fe9SKudo Chien * 36*3ba32fe9SKudo Chien * A helper class that can round trip between JSON and Bundle objects that contains the types: 37*3ba32fe9SKudo Chien * Boolean, Integer, Long, Double, String If other types are found, an IllegalArgumentException is 38*3ba32fe9SKudo Chien * thrown. 39*3ba32fe9SKudo Chien */ 40*3ba32fe9SKudo Chien 41*3ba32fe9SKudo Chien object BundleJSONConverter { 42*3ba32fe9SKudo Chien private val SETTERS: MutableMap<Class<*>, Setter> = HashMap() 43*3ba32fe9SKudo Chien 44*3ba32fe9SKudo Chien @JvmStatic 45*3ba32fe9SKudo Chien @Throws(JSONException::class) convertToJSONnull46*3ba32fe9SKudo Chien fun convertToJSON(bundle: Bundle): JSONObject { 47*3ba32fe9SKudo Chien val json = JSONObject() 48*3ba32fe9SKudo Chien for (key in bundle.keySet()) { 49*3ba32fe9SKudo Chien val value = 50*3ba32fe9SKudo Chien bundle[key] // Null is not supported. 51*3ba32fe9SKudo Chien ?: continue 52*3ba32fe9SKudo Chien 53*3ba32fe9SKudo Chien // Special case List<String> as getClass would not work, since List is an interface 54*3ba32fe9SKudo Chien if (value is List<*>) { 55*3ba32fe9SKudo Chien val jsonArray = JSONArray() 56*3ba32fe9SKudo Chien val listValue = value as List<String> 57*3ba32fe9SKudo Chien for (stringValue in listValue) { 58*3ba32fe9SKudo Chien jsonArray.put(stringValue) 59*3ba32fe9SKudo Chien } 60*3ba32fe9SKudo Chien json.put(key, jsonArray) 61*3ba32fe9SKudo Chien continue 62*3ba32fe9SKudo Chien } 63*3ba32fe9SKudo Chien 64*3ba32fe9SKudo Chien // Special case Bundle as it's one way, on the return it will be JSONObject 65*3ba32fe9SKudo Chien if (value is Bundle) { 66*3ba32fe9SKudo Chien json.put(key, convertToJSON(value)) 67*3ba32fe9SKudo Chien continue 68*3ba32fe9SKudo Chien } 69*3ba32fe9SKudo Chien val setter = 70*3ba32fe9SKudo Chien SETTERS[value.javaClass] 71*3ba32fe9SKudo Chien ?: throw IllegalArgumentException("Unsupported type: " + value.javaClass) 72*3ba32fe9SKudo Chien setter.setOnJSON(json, key, value) 73*3ba32fe9SKudo Chien } 74*3ba32fe9SKudo Chien return json 75*3ba32fe9SKudo Chien } 76*3ba32fe9SKudo Chien 77*3ba32fe9SKudo Chien @JvmStatic 78*3ba32fe9SKudo Chien @Throws(JSONException::class) convertToBundlenull79*3ba32fe9SKudo Chien fun convertToBundle(jsonObject: JSONObject): Bundle { 80*3ba32fe9SKudo Chien val bundle = Bundle() 81*3ba32fe9SKudo Chien val jsonIterator = jsonObject.keys() 82*3ba32fe9SKudo Chien while (jsonIterator.hasNext()) { 83*3ba32fe9SKudo Chien val key = jsonIterator.next() 84*3ba32fe9SKudo Chien val value = jsonObject[key] 85*3ba32fe9SKudo Chien if (value === JSONObject.NULL) { 86*3ba32fe9SKudo Chien // Null is not supported. 87*3ba32fe9SKudo Chien continue 88*3ba32fe9SKudo Chien } 89*3ba32fe9SKudo Chien 90*3ba32fe9SKudo Chien // Special case JSONObject as it's one way, on the return it would be Bundle. 91*3ba32fe9SKudo Chien if (value is JSONObject) { 92*3ba32fe9SKudo Chien bundle.putBundle(key, convertToBundle(value)) 93*3ba32fe9SKudo Chien continue 94*3ba32fe9SKudo Chien } 95*3ba32fe9SKudo Chien val setter = 96*3ba32fe9SKudo Chien SETTERS[value.javaClass] 97*3ba32fe9SKudo Chien ?: throw IllegalArgumentException("Unsupported type: " + value.javaClass) 98*3ba32fe9SKudo Chien setter.setOnBundle(bundle, key, value) 99*3ba32fe9SKudo Chien } 100*3ba32fe9SKudo Chien return bundle 101*3ba32fe9SKudo Chien } 102*3ba32fe9SKudo Chien 103*3ba32fe9SKudo Chien interface Setter { setOnBundlenull104*3ba32fe9SKudo Chien @Throws(JSONException::class) fun setOnBundle(bundle: Bundle, key: String, value: Any) 105*3ba32fe9SKudo Chien 106*3ba32fe9SKudo Chien @Throws(JSONException::class) fun setOnJSON(json: JSONObject, key: String, value: Any) 107*3ba32fe9SKudo Chien } 108*3ba32fe9SKudo Chien 109*3ba32fe9SKudo Chien init { 110*3ba32fe9SKudo Chien SETTERS[java.lang.Boolean::class.java] = 111*3ba32fe9SKudo Chien object : Setter { 112*3ba32fe9SKudo Chien @Throws(JSONException::class) 113*3ba32fe9SKudo Chien override fun setOnBundle(bundle: Bundle, key: String, value: Any) { 114*3ba32fe9SKudo Chien bundle.putBoolean(key, value as Boolean) 115*3ba32fe9SKudo Chien } 116*3ba32fe9SKudo Chien 117*3ba32fe9SKudo Chien @Throws(JSONException::class) 118*3ba32fe9SKudo Chien override fun setOnJSON(json: JSONObject, key: String, value: Any) { 119*3ba32fe9SKudo Chien json.put(key, value) 120*3ba32fe9SKudo Chien } 121*3ba32fe9SKudo Chien } 122*3ba32fe9SKudo Chien SETTERS[java.lang.Integer::class.java] = 123*3ba32fe9SKudo Chien object : Setter { 124*3ba32fe9SKudo Chien @Throws(JSONException::class) 125*3ba32fe9SKudo Chien override fun setOnBundle(bundle: Bundle, key: String, value: Any) { 126*3ba32fe9SKudo Chien bundle.putInt(key, value as Int) 127*3ba32fe9SKudo Chien } 128*3ba32fe9SKudo Chien 129*3ba32fe9SKudo Chien @Throws(JSONException::class) 130*3ba32fe9SKudo Chien override fun setOnJSON(json: JSONObject, key: String, value: Any) { 131*3ba32fe9SKudo Chien json.put(key, value) 132*3ba32fe9SKudo Chien } 133*3ba32fe9SKudo Chien } 134*3ba32fe9SKudo Chien SETTERS[java.lang.Long::class.java] = 135*3ba32fe9SKudo Chien object : Setter { 136*3ba32fe9SKudo Chien @Throws(JSONException::class) 137*3ba32fe9SKudo Chien override fun setOnBundle(bundle: Bundle, key: String, value: Any) { 138*3ba32fe9SKudo Chien bundle.putLong(key, value as Long) 139*3ba32fe9SKudo Chien } 140*3ba32fe9SKudo Chien 141*3ba32fe9SKudo Chien @Throws(JSONException::class) 142*3ba32fe9SKudo Chien override fun setOnJSON(json: JSONObject, key: String, value: Any) { 143*3ba32fe9SKudo Chien json.put(key, value) 144*3ba32fe9SKudo Chien } 145*3ba32fe9SKudo Chien } 146*3ba32fe9SKudo Chien SETTERS[java.lang.Double::class.java] = 147*3ba32fe9SKudo Chien object : Setter { 148*3ba32fe9SKudo Chien @Throws(JSONException::class) 149*3ba32fe9SKudo Chien override fun setOnBundle(bundle: Bundle, key: String, value: Any) { 150*3ba32fe9SKudo Chien bundle.putDouble(key, value as Double) 151*3ba32fe9SKudo Chien } 152*3ba32fe9SKudo Chien 153*3ba32fe9SKudo Chien @Throws(JSONException::class) 154*3ba32fe9SKudo Chien override fun setOnJSON(json: JSONObject, key: String, value: Any) { 155*3ba32fe9SKudo Chien json.put(key, value) 156*3ba32fe9SKudo Chien } 157*3ba32fe9SKudo Chien } 158*3ba32fe9SKudo Chien SETTERS[String::class.java] = 159*3ba32fe9SKudo Chien object : Setter { 160*3ba32fe9SKudo Chien @Throws(JSONException::class) 161*3ba32fe9SKudo Chien override fun setOnBundle(bundle: Bundle, key: String, value: Any) { 162*3ba32fe9SKudo Chien bundle.putString(key, value as String) 163*3ba32fe9SKudo Chien } 164*3ba32fe9SKudo Chien 165*3ba32fe9SKudo Chien @Throws(JSONException::class) 166*3ba32fe9SKudo Chien override fun setOnJSON(json: JSONObject, key: String, value: Any) { 167*3ba32fe9SKudo Chien json.put(key, value) 168*3ba32fe9SKudo Chien } 169*3ba32fe9SKudo Chien } 170*3ba32fe9SKudo Chien SETTERS[Array<String>::class.java] = 171*3ba32fe9SKudo Chien object : Setter { 172*3ba32fe9SKudo Chien @Throws(JSONException::class) 173*3ba32fe9SKudo Chien override fun setOnBundle(bundle: Bundle, key: String, value: Any) { 174*3ba32fe9SKudo Chien throw IllegalArgumentException("Unexpected type from JSON") 175*3ba32fe9SKudo Chien } 176*3ba32fe9SKudo Chien 177*3ba32fe9SKudo Chien @Throws(JSONException::class) 178*3ba32fe9SKudo Chien override fun setOnJSON(json: JSONObject, key: String, value: Any) { 179*3ba32fe9SKudo Chien val jsonArray = JSONArray() 180*3ba32fe9SKudo Chien for (stringValue in value as Array<String>) { 181*3ba32fe9SKudo Chien jsonArray.put(stringValue) 182*3ba32fe9SKudo Chien } 183*3ba32fe9SKudo Chien json.put(key, jsonArray) 184*3ba32fe9SKudo Chien } 185*3ba32fe9SKudo Chien } 186*3ba32fe9SKudo Chien SETTERS[JSONArray::class.java] = 187*3ba32fe9SKudo Chien object : Setter { 188*3ba32fe9SKudo Chien @Throws(JSONException::class) 189*3ba32fe9SKudo Chien override fun setOnBundle(bundle: Bundle, key: String, value: Any) { 190*3ba32fe9SKudo Chien val jsonArray = value as JSONArray 191*3ba32fe9SKudo Chien val stringArrayList = ArrayList<String>() 192*3ba32fe9SKudo Chien // Empty list, can't even figure out the type, assume an ArrayList<String> 193*3ba32fe9SKudo Chien if (jsonArray.length() == 0) { 194*3ba32fe9SKudo Chien bundle.putStringArrayList(key, stringArrayList) 195*3ba32fe9SKudo Chien return 196*3ba32fe9SKudo Chien } 197*3ba32fe9SKudo Chien 198*3ba32fe9SKudo Chien // Only strings are supported for now 199*3ba32fe9SKudo Chien for (i in 0 until jsonArray.length()) { 200*3ba32fe9SKudo Chien val current = jsonArray[i] 201*3ba32fe9SKudo Chien if (current is String) { 202*3ba32fe9SKudo Chien stringArrayList.add(current) 203*3ba32fe9SKudo Chien } else { 204*3ba32fe9SKudo Chien throw IllegalArgumentException("Unexpected type in an array: " + current.javaClass) 205*3ba32fe9SKudo Chien } 206*3ba32fe9SKudo Chien } 207*3ba32fe9SKudo Chien bundle.putStringArrayList(key, stringArrayList) 208*3ba32fe9SKudo Chien } 209*3ba32fe9SKudo Chien 210*3ba32fe9SKudo Chien @Throws(JSONException::class) 211*3ba32fe9SKudo Chien override fun setOnJSON(json: JSONObject, key: String, value: Any) { 212*3ba32fe9SKudo Chien throw IllegalArgumentException("JSONArray's are not supported in bundles.") 213*3ba32fe9SKudo Chien } 214*3ba32fe9SKudo Chien } 215*3ba32fe9SKudo Chien } 216*3ba32fe9SKudo Chien } 217