1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.statementservice.database
18 
19 import android.content.UriRelativeFilter
20 import android.content.UriRelativeFilterGroup
21 import android.util.JsonReader
22 import androidx.room.TypeConverter
23 import org.json.JSONArray
24 import org.json.JSONObject
25 import java.io.StringReader
26 import java.util.ArrayList
27 
28 class Converters {
29     companion object {
30         private const val ACTION_NAME = "action"
31         private const val FILTERS_NAME = "filters"
32         private const val URI_PART_NAME = "uriPart"
33         private const val PATTERN_TYPE_NAME = "patternType"
34         private const val FILTER_NAME = "filter"
35     }
36 
37     @TypeConverter
38     fun groupsToJson(groups: List<UriRelativeFilterGroup>): String {
39         val json = JSONArray()
40         for (group in groups) {
41             json.put(groupToJson(group))
42         }
43         return json.toString()
44     }
45 
46     @TypeConverter
47     fun stringToGroups(json: String): List<UriRelativeFilterGroup> {
48         val groups = ArrayList<UriRelativeFilterGroup>()
49         StringReader(json).use { stringReader ->
50             JsonReader(stringReader).use { reader ->
51                 reader.beginArray()
52                 while (reader.hasNext()) {
53                     groups.add(parseGroup(reader))
54                 }
55                 reader.endArray()
56             }
57         }
58         return groups
59     }
60 
61     private fun groupToJson(group: UriRelativeFilterGroup): JSONObject {
62         val jsonObject = JSONObject()
63         jsonObject.put(ACTION_NAME, group.action)
64         val filters = JSONArray()
65         for (filter in group.uriRelativeFilters) {
66             filters.put(filterToJson(filter))
67         }
68         jsonObject.put(FILTERS_NAME, filters)
69         return jsonObject
70     }
71 
72     private fun filterToJson(filter: UriRelativeFilter): JSONObject {
73         val jsonObject = JSONObject()
74         jsonObject.put(URI_PART_NAME, filter.uriPart)
75         jsonObject.put(PATTERN_TYPE_NAME, filter.patternType)
76         jsonObject.put(FILTER_NAME, filter.filter)
77         return jsonObject
78     }
79 
80     private fun parseGroup(reader: JsonReader): UriRelativeFilterGroup {
81         val jsonObject = JSONObject()
82         reader.beginObject()
83         while (reader.hasNext()) {
84             val name = reader.nextName()
85             when (name) {
86                 ACTION_NAME -> jsonObject.put(ACTION_NAME, reader.nextInt())
87                 FILTERS_NAME -> jsonObject.put(FILTERS_NAME, parseFilters(reader))
88                 else -> reader.skipValue()
89             }
90         }
91         reader.endObject()
92 
93         val group = UriRelativeFilterGroup(jsonObject.getInt(ACTION_NAME))
94         val filters = jsonObject.getJSONArray(FILTERS_NAME)
95         for (i in 0 until filters.length()) {
96             val filter = filters.getJSONObject(i)
97             group.addUriRelativeFilter(UriRelativeFilter(
98                 filter.getInt(URI_PART_NAME),
99                 filter.getInt(PATTERN_TYPE_NAME),
100                 filter.getString(FILTER_NAME)
101             ))
102         }
103         return group
104     }
105 
106     private fun parseFilters(reader: JsonReader): JSONArray {
107         val filters = JSONArray()
108         reader.beginArray()
109         while (reader.hasNext()) {
110             filters.put(parseFilter(reader))
111         }
112         reader.endArray()
113         return filters
114     }
115 
116     private fun parseFilter(reader: JsonReader): JSONObject {
117         reader.beginObject()
118         val jsonObject = JSONObject()
119         while (reader.hasNext()) {
120             val name = reader.nextName()
121             when (name) {
122                 URI_PART_NAME, PATTERN_TYPE_NAME -> jsonObject.put(name, reader.nextInt())
123                 FILTER_NAME -> jsonObject.put(name, reader.nextString())
124                 else -> reader.skipValue()
125             }
126         }
127         reader.endObject()
128         return jsonObject
129     }
130 }