1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_FORM_FWK_FORM_UTIL_FORM_H
17 #define OHOS_FORM_FWK_FORM_UTIL_FORM_H
18 
19 #include <string>
20 
21 #include "appexecfwk_errors.h"
22 #include "fms_log_wrapper.h"
23 #include "json_serializer.h"
24 
25 namespace OHOS {
26 namespace AppExecFwk {
27 enum class JsonType {
28     NULLABLE,
29     BOOLEAN,
30     NUMBER,
31     OBJECT,
32     ARRAY,
33     STRING,
34 };
35 
36 enum class ArrayType {
37     NUMBER,
38     OBJECT,
39     STRING,
40     NOT_ARRAY,
41 };
42 
43 template<typename T, typename dataType>
CheckArrayType(const nlohmann::json & jsonObject,const std::string & key,dataType & data,ArrayType arrayType,int32_t & parseResult)44 void CheckArrayType(const nlohmann::json &jsonObject, const std::string &key,
45     dataType &data, ArrayType arrayType, int32_t &parseResult)
46 {
47     auto arrays = jsonObject.at(key);
48     if (arrays.empty()) {
49         HILOG_DEBUG("empty array");
50         return;
51     }
52     switch (arrayType) {
53         case ArrayType::STRING:
54             for (const auto &array : arrays) {
55                 if (!array.is_string()) {
56                     HILOG_ERROR("array %{public}s not string type", key.c_str());
57                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
58                 }
59             }
60             if (parseResult == ERR_OK) {
61                 data = jsonObject.at(key).get<T>();
62             }
63             break;
64         case ArrayType::OBJECT:
65             for (const auto &array : arrays) {
66                 if (!array.is_object()) {
67                     HILOG_ERROR("array %{public}s not object type", key.c_str());
68                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
69                     break;
70                 }
71             }
72             if (parseResult == ERR_OK) {
73                 data = jsonObject.at(key).get<T>();
74             }
75             break;
76         case ArrayType::NUMBER:
77             for (const auto &array : arrays) {
78                 if (!array.is_number()) {
79                     HILOG_ERROR("array %{public}s not number type", key.c_str());
80                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
81                 }
82             }
83             if (parseResult == ERR_OK) {
84                 data = jsonObject.at(key).get<T>();
85             }
86             break;
87         case ArrayType::NOT_ARRAY:
88             HILOG_ERROR("array %{public}s not array type", key.c_str());
89             break;
90         default:
91             HILOG_ERROR("array %{public}s type error", key.c_str());
92             break;
93     }
94 }
95 
96 template<typename T, typename dataType>
GetValueIfFindKey(const nlohmann::json & jsonObject,const nlohmann::detail::iter_impl<const nlohmann::json> & end,const std::string & key,dataType & data,JsonType jsonType,bool isNecessary,int32_t & parseResult,ArrayType arrayType)97 void GetValueIfFindKey(const nlohmann::json &jsonObject, const nlohmann::detail::iter_impl<const nlohmann::json> &end,
98     const std::string &key, dataType &data, JsonType jsonType, bool isNecessary, int32_t &parseResult,
99     ArrayType arrayType)
100 {
101     if (parseResult) {
102         return;
103     }
104     if (jsonObject.find(key) != end) {
105         switch (jsonType) {
106             case JsonType::BOOLEAN:
107                 if (!jsonObject.at(key).is_boolean()) {
108                     HILOG_ERROR("type is error %{public}s not boolean", key.c_str());
109                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
110                     break;
111                 }
112                 data = jsonObject.at(key).get<T>();
113                 break;
114             case JsonType::NUMBER:
115                 if (!jsonObject.at(key).is_number()) {
116                     HILOG_ERROR("type is error %{public}s not number", key.c_str());
117                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
118                     break;
119                 }
120                 data = jsonObject.at(key).get<T>();
121                 break;
122             case JsonType::OBJECT:
123                 if (!jsonObject.at(key).is_object()) {
124                     HILOG_ERROR("type is error %{public}s not object", key.c_str());
125                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
126                     break;
127                 }
128                 data = jsonObject.at(key).get<T>();
129                 break;
130             case JsonType::ARRAY:
131                 if (!jsonObject.at(key).is_array()) {
132                     HILOG_ERROR("type is error %{public}s not array", key.c_str());
133                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
134                     break;
135                 }
136                 CheckArrayType<T>(jsonObject, key, data, arrayType, parseResult);
137                 break;
138             case JsonType::STRING:
139                 if (!jsonObject.at(key).is_string()) {
140                     HILOG_ERROR("type is error %{public}s not string", key.c_str());
141                     parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
142                     break;
143                 }
144                 data = jsonObject.at(key).get<T>();
145                 break;
146             case JsonType::NULLABLE:
147                 HILOG_ERROR("type is error %{public}s is nullable", key.c_str());
148                 break;
149             default:
150                 HILOG_ERROR("type is error %{public}s not jsonType", key.c_str());
151                 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
152         }
153         return;
154     }
155     if (isNecessary) {
156         HILOG_ERROR("profile prop %{public}s is mission", key.c_str());
157         parseResult = ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP;
158     }
159 }
160 
161 template<typename T>
GetJsonStrFromInfo(T & t)162 const std::string GetJsonStrFromInfo(T &t)
163 {
164     nlohmann::json json = t;
165     return json.dump();
166 }
167 
168 template<typename T>
ParseInfoFromJsonStr(const char * data,T & t)169 bool ParseInfoFromJsonStr(const char *data, T &t)
170 {
171     if (data == nullptr) {
172         HILOG_ERROR("null data");
173         return false;
174     }
175 
176     nlohmann::json jsonObject = nlohmann::json::parse(data, nullptr, false);
177     if (jsonObject.is_discarded()) {
178         HILOG_ERROR("data is discarded");
179         return false;
180     }
181 
182     t = jsonObject.get<T>();
183     return true;
184 }
185 }  // namespace AppExecFwk
186 }  // namespace OHOS
187 #endif  // OHOS_FORM_FWK_FORM_UTIL_FORM_H
188