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