1 /*
2 * Copyright (c) 2022-2023 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 SERVICES_EDM_INCLUDE_EDM_IPOLICY_SERIALIZER_H
17 #define SERVICES_EDM_INCLUDE_EDM_IPOLICY_SERIALIZER_H
18
19 #include <algorithm>
20 #include <message_parcel.h>
21 #include <set>
22 #include <string>
23 #include <string_ex.h>
24
25 #include "json/json.h"
26 #include "singleton.h"
27
28 #include "edm_constants.h"
29 #include "edm_log.h"
30
31 namespace OHOS {
32 namespace EDM {
33 /*
34 * Policy data serialize interface
35 *
36 * @tparam DT policy data type,like vector,map,int...
37 */
38 template<class DT>
39 class IPolicySerializer {
40 public:
41 /*
42 * Deserialize a JSON string into a DT object.
43 *
44 * @param jsonString JSON string
45 * @param dataObj DT object
46 * @return true indicates that the operation is successful.
47 */
48 virtual bool Deserialize(const std::string &jsonString, DT &dataObj) = 0;
49
50 /*
51 * Serializes a DT object into a JSON string.
52 *
53 * @param dataObj DT object
54 * @param jsonString JSON string
55 * @return true indicates that the operation is successful.
56 */
57 virtual bool Serialize(const DT &dataObj, std::string &jsonString) = 0;
58
59 /*
60 * Obtains DT object data from the MessageParcel object.
61 *
62 * @param reply MessageParcel
63 * @param result DT object
64 * @return true indicates that the operation is successful.
65 */
66 virtual bool GetPolicy(MessageParcel &data, DT &result) = 0;
67
68 /*
69 * Write DT object data to MessageParcel
70 *
71 * @param reply MessageParcel
72 * @param result DT object
73 * @return true indicates that the operation is successful.
74 */
75 virtual bool WritePolicy(MessageParcel &reply, DT &result) = 0;
76
77 /*
78 * Obtain the final data from all DT data set by the admin.
79 *
80 * @param adminValuesArray DT data collection
81 * @param result The end result
82 * @return true indicates that the operation is successful.
83 */
84 virtual bool MergePolicy(std::vector<DT> &adminValuesArray, DT &result) = 0;
85
86 virtual ~IPolicySerializer() = default;
87 };
88
89 /*
90 * Policy data serialize interface
91 *
92 * @tparam DT policy data type in vector.
93 * @tparam T_ARRAY policy data type,like vector<string>,vector<map>...
94 */
95 template<typename DT, typename T_ARRAY = std::vector<DT>>
96 class ArraySerializer : public IPolicySerializer<T_ARRAY> {
97 public:
98 bool Deserialize(const std::string &jsonString, T_ARRAY &dataObj) override;
99
100 bool Serialize(const T_ARRAY &dataObj, std::string &jsonString) override;
101
102 bool GetPolicy(MessageParcel &data, T_ARRAY &result) override;
103
104 bool WritePolicy(MessageParcel &reply, T_ARRAY &result) override;
105
106 bool MergePolicy(std::vector<T_ARRAY> &data, T_ARRAY &result) override;
107
108 virtual void Deduplication(T_ARRAY &dataObj);
109
110 protected:
111 std::shared_ptr<IPolicySerializer<DT>> serializerInner_;
112 };
113
114 template<typename DT, typename T_ARRAY>
Deserialize(const std::string & jsonString,T_ARRAY & dataObj)115 bool ArraySerializer<DT, T_ARRAY>::Deserialize(const std::string &jsonString, T_ARRAY &dataObj)
116 {
117 if (jsonString.empty()) {
118 return true;
119 }
120 Json::Value root;
121 const auto rawJsonLength = static_cast<int>(jsonString.length());
122 JSONCPP_STRING err;
123 Json::CharReaderBuilder builder;
124 const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
125 if (!reader->parse(jsonString.c_str(), jsonString.c_str() + rawJsonLength, &root, &err)) {
126 EDMLOGE("ArraySerializer Deserialize json to vector error. %{public}s ", err.c_str());
127 return false;
128 }
129 if (!root.isArray()) {
130 return false;
131 }
132 if (root.size() > EdmConstants::DEFAULT_LOOP_MAX_SIZE) {
133 return false;
134 }
135 dataObj = std::vector<DT>(root.size());
136 for (std::uint32_t i = 0; i < root.size(); ++i) {
137 Json::StreamWriterBuilder writerBuilder;
138 const std::string valueJsonString = Json::writeString(writerBuilder, root[i]);
139 DT value;
140 if (!serializerInner_->Deserialize(valueJsonString, value)) {
141 return false;
142 }
143 dataObj.at(i) = value;
144 }
145 return true;
146 }
147
148 template<typename DT, typename T_ARRAY>
Serialize(const T_ARRAY & dataObj,std::string & jsonString)149 bool ArraySerializer<DT, T_ARRAY>::Serialize(const T_ARRAY &dataObj, std::string &jsonString)
150 {
151 if (dataObj.empty()) {
152 jsonString = "";
153 return true;
154 }
155 Json::Value arrayData(Json::arrayValue);
156 for (std::uint32_t i = 0; i < dataObj.size(); ++i) {
157 std::string itemJson;
158 DT item = dataObj.at(i);
159 if (!serializerInner_->Serialize(item, itemJson)) {
160 return false;
161 }
162 arrayData[i] = itemJson;
163 }
164 Json::StreamWriterBuilder builder;
165 builder["indentation"] = " ";
166 jsonString = Json::writeString(builder, arrayData);
167 return true;
168 }
169
170 template<typename DT, typename T_ARRAY>
GetPolicy(MessageParcel & data,T_ARRAY & result)171 bool ArraySerializer<DT, T_ARRAY>::GetPolicy(MessageParcel &data, T_ARRAY &result)
172 {
173 std::vector<std::string> readVector;
174 if (!data.ReadStringVector(&readVector)) {
175 return false;
176 }
177 // Data will be appended to result, and the original data of result will not be deleted.
178 for (const auto &itemJson : readVector) {
179 DT item;
180 if (!itemJson.empty()) {
181 if (!serializerInner_->Deserialize(itemJson, item)) {
182 return false;
183 }
184 result.push_back(item);
185 }
186 }
187 Deduplication(result);
188 return true;
189 }
190
191 template<typename DT, typename T_ARRAY>
WritePolicy(MessageParcel & reply,T_ARRAY & result)192 bool ArraySerializer<DT, T_ARRAY>::WritePolicy(MessageParcel &reply, T_ARRAY &result)
193 {
194 std::vector<std::string> writeVector;
195 for (const auto &item : result) {
196 std::string itemJson;
197 if (!serializerInner_->Serialize(item, itemJson)) {
198 return false;
199 }
200 writeVector.push_back(itemJson);
201 }
202 return reply.WriteStringVector(writeVector);
203 }
204
205 template<typename DT, typename T_ARRAY>
MergePolicy(std::vector<T_ARRAY> & data,T_ARRAY & result)206 bool ArraySerializer<DT, T_ARRAY>::MergePolicy(std::vector<T_ARRAY> &data, T_ARRAY &result)
207 {
208 std::set<DT> stData;
209 for (const auto &dataItem : data) {
210 for (const auto &item : dataItem) {
211 stData.insert(item);
212 }
213 }
214 result.assign(stData.begin(), stData.end());
215 return true;
216 }
217
218 template<typename DT, typename T_ARRAY>
Deduplication(T_ARRAY & dataObj)219 void ArraySerializer<DT, T_ARRAY>::Deduplication(T_ARRAY &dataObj)
220 {
221 std::sort(dataObj.begin(), dataObj.end());
222 auto iter = std::unique(dataObj.begin(), dataObj.end());
223 dataObj.erase(iter, dataObj.end());
224 }
225 } // namespace EDM
226 } // namespace OHOS
227
228 #endif // SERVICES_EDM_INCLUDE_EDM_IPOLICY_SERIALIZER_H
229