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