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