1 /*
2 * Copyright (c) 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 #include <vector>
17 #include "error_util.h"
18 #include "hilog/log.h"
19 #include "locale_config.h"
20 #include "variable_convertor.h"
21 #include "holiday_manager_addon.h"
22
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "HolidayManagerJs" };
27 using namespace OHOS::HiviewDFX;
28
HolidayManagerAddon()29 HolidayManagerAddon::HolidayManagerAddon() : env_(nullptr) {}
30
~HolidayManagerAddon()31 HolidayManagerAddon::~HolidayManagerAddon()
32 {
33 }
34
Destructor(napi_env env,void * nativeObject,void * hint)35 void HolidayManagerAddon::Destructor(napi_env env, void *nativeObject, void *hint)
36 {
37 if (!nativeObject) {
38 return;
39 }
40 delete reinterpret_cast<HolidayManagerAddon *>(nativeObject);
41 nativeObject = nullptr;
42 }
43
InitHolidayManager(napi_env env,napi_value exports)44 napi_value HolidayManagerAddon::InitHolidayManager(napi_env env, napi_value exports)
45 {
46 napi_status status = napi_ok;
47 napi_property_descriptor properties[] = {
48 DECLARE_NAPI_FUNCTION("isHoliday", IsHoliday),
49 DECLARE_NAPI_FUNCTION("getHolidayInfoItemArray", GetHolidayInfoItemArray)
50 };
51
52 napi_value constructor = nullptr;
53 status = napi_define_class(env, "HolidayManager", NAPI_AUTO_LENGTH, HolidayManagerConstructor, nullptr,
54 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
55 if (status != napi_ok) {
56 HiLog::Error(LABEL, "Define class failed when InitHolidayManager");
57 return nullptr;
58 }
59
60 status = napi_set_named_property(env, exports, "HolidayManager", constructor);
61 if (status != napi_ok) {
62 HiLog::Error(LABEL, "Set property failed when InitHolidayManager");
63 return nullptr;
64 }
65 return exports;
66 }
67
HolidayManagerConstructor(napi_env env,napi_callback_info info)68 napi_value HolidayManagerAddon::HolidayManagerConstructor(napi_env env, napi_callback_info info)
69 {
70 size_t argc = 1;
71 napi_value argv[1] = { 0 };
72 napi_value thisVar = nullptr;
73 void *data = nullptr;
74 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
75 if (status != napi_ok) {
76 return nullptr;
77 }
78 napi_valuetype valueType = napi_valuetype::napi_undefined;
79 napi_typeof(env, argv[0], &valueType);
80 if (valueType != napi_valuetype::napi_string) {
81 napi_throw_type_error(env, nullptr, "Parameter type does not match");
82 return nullptr;
83 }
84 std::unique_ptr<HolidayManagerAddon> obj = std::make_unique<HolidayManagerAddon>();
85 status =
86 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), HolidayManagerAddon::Destructor, nullptr, nullptr);
87 if (status != napi_ok) {
88 HiLog::Error(LABEL, "Wrap HolidayManagerAddon failed");
89 return nullptr;
90 }
91 int32_t code = 0;
92 std::string path = GetString(env, argv[0], code);
93 if (code) {
94 return nullptr;
95 }
96 if (!obj->InitHolidayManagerContext(env, info, path.c_str())) {
97 HiLog::Error(LABEL, "Init HolidayManager failed");
98 return nullptr;
99 }
100 obj.release();
101 return thisVar;
102 }
103
InitHolidayManagerContext(napi_env env,napi_callback_info info,const char * path)104 bool HolidayManagerAddon::InitHolidayManagerContext(napi_env env, napi_callback_info info, const char* path)
105 {
106 napi_value global = nullptr;
107 napi_status status = napi_get_global(env, &global);
108 if (status != napi_ok) {
109 HiLog::Error(LABEL, "Get global failed");
110 return false;
111 }
112 env_ = env;
113 holidayManager_ = std::make_unique<HolidayManager>(path);
114 return holidayManager_ != nullptr;
115 }
116
GetString(napi_env & env,napi_value & value,int32_t & code)117 std::string HolidayManagerAddon::GetString(napi_env &env, napi_value &value, int32_t &code)
118 {
119 size_t len = 0;
120 napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
121 if (status != napi_ok) {
122 HiLog::Error(LABEL, "Get string failed");
123 code = 1;
124 return "";
125 }
126 std::vector<char> buf(len + 1);
127 status = napi_get_value_string_utf8(env, value, buf.data(), len + 1, &len);
128 if (status != napi_ok) {
129 HiLog::Error(LABEL, "Create string failed");
130 code = 1;
131 return "";
132 }
133 return buf.data();
134 }
135
IsHoliday(napi_env env,napi_callback_info info)136 napi_value HolidayManagerAddon::IsHoliday(napi_env env, napi_callback_info info)
137 {
138 size_t argc = 1;
139 napi_value argv[1] = { 0 };
140 napi_value thisVar = nullptr;
141 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL);
142 if (status != napi_ok) {
143 return nullptr;
144 }
145 HolidayManagerAddon *obj = nullptr;
146 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
147 if (status != napi_ok || !obj || !obj->holidayManager_) {
148 HiLog::Error(LABEL, "Get HolidayManager object failed");
149 return nullptr;
150 }
151 napi_value result = nullptr;
152 bool flag = VariableConvertor::CheckNapiValueType(env, argv[0]);
153 bool res = false;
154 if (flag) {
155 std::vector<int> list = ValidateParamDate(env, argv[0]);
156 if (list.size() == 3) { // 3 is the number of parameters
157 // 0, 1, and 2 indicate that the first, second, and third parameters of the list are read
158 res = obj->holidayManager_->IsHoliday(list.at(0), list.at(1), list.at(2));
159 }
160 } else {
161 res = obj->holidayManager_->IsHoliday();
162 }
163 status = napi_get_boolean(env, res, &result);
164 return result;
165 }
166
GetHolidayInfoItemArray(napi_env env,napi_callback_info info)167 napi_value HolidayManagerAddon::GetHolidayInfoItemArray(napi_env env, napi_callback_info info)
168 {
169 size_t argc = 1;
170 napi_value argv[1] = { 0 };
171 argv[0] = nullptr;
172 napi_value thisVar = nullptr;
173 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL);
174 if (status != napi_ok) {
175 return nullptr;
176 }
177 HolidayManagerAddon *obj = nullptr;
178 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
179 if (status != napi_ok || !obj || !obj->holidayManager_) {
180 HiLog::Error(LABEL, "Get HolidayManager object failed");
181 return nullptr;
182 }
183 bool flag = VariableConvertor::CheckNapiValueType(env, argv[0]);
184 if (flag) {
185 int32_t year = ValidateParamNumber(env, argv[0]);
186 std::vector<HolidayInfoItem> itemList = obj->holidayManager_->GetHolidayInfoItemArray(year);
187 return GetHolidayInfoItemResult(env, itemList);
188 } else {
189 std::vector<HolidayInfoItem> itemList = obj->holidayManager_->GetHolidayInfoItemArray();
190 return GetHolidayInfoItemResult(env, itemList);
191 }
192 }
193
GetHolidayInfoItemResult(napi_env env,std::vector<HolidayInfoItem> itemList)194 napi_value HolidayManagerAddon::GetHolidayInfoItemResult(napi_env env, std::vector<HolidayInfoItem> itemList)
195 {
196 napi_value result = nullptr;
197 napi_status status = napi_create_array_with_length(env, itemList.size(), &result);
198 if (status != napi_ok) {
199 HiLog::Error(LABEL, "create HolidayInfoItem array failed.");
200 return nullptr;
201 }
202 for (size_t i = 0; i < itemList.size(); i++) {
203 napi_value item = CreateHolidayItem(env, itemList[i]);
204 status = napi_set_element(env, result, i, item);
205 if (status != napi_ok) {
206 HiLog::Error(LABEL, "Failed to set HolidayInfoItem element.");
207 return nullptr;
208 }
209 }
210 return result;
211 }
212
ValidateParamDate(napi_env & env,napi_value & argv)213 std::vector<int> HolidayManagerAddon::ValidateParamDate(napi_env &env, napi_value &argv)
214 {
215 std::vector<int> list;
216 napi_valuetype valueType = napi_valuetype::napi_undefined;
217 napi_typeof(env, argv, &valueType);
218 if (valueType != napi_valuetype::napi_object) {
219 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, true);
220 return list;
221 }
222 list.push_back(GetDateValue(env, argv, "getFullYear"));
223 list.push_back(GetDateValue(env, argv, "getMonth") + MONTH_INCREASE_ONE);
224 list.push_back(GetDateValue(env, argv, "getDate"));
225 return list;
226 }
227
GetDateValue(napi_env env,napi_value value,const std::string method)228 int HolidayManagerAddon::GetDateValue(napi_env env, napi_value value, const std::string method)
229 {
230 int val = 0;
231 if (!value) {
232 return val;
233 }
234 napi_value funcGetDateInfo = nullptr;
235 napi_status status = napi_get_named_property(env, value, method.c_str(), &funcGetDateInfo);
236 if (status != napi_ok) {
237 HiLog::Error(LABEL, "Get method %{public}s failed", method.c_str());
238 return val;
239 }
240 napi_value ret_value = nullptr;
241 status = napi_call_function(env, value, funcGetDateInfo, 0, nullptr, &ret_value);
242 if (status != napi_ok) {
243 HiLog::Error(LABEL, "Get milliseconds failed");
244 return val;
245 }
246
247 status = napi_get_value_int32(env, ret_value, &val);
248 if (status != napi_ok) {
249 HiLog::Error(LABEL, "Retrieve field failed");
250 return val;
251 }
252 return val;
253 }
254
ValidateParamNumber(napi_env & env,napi_value & argv)255 int32_t HolidayManagerAddon::ValidateParamNumber(napi_env &env, napi_value &argv)
256 {
257 napi_valuetype valueType = napi_valuetype::napi_undefined;
258 napi_typeof(env, argv, &valueType);
259 if (valueType != napi_valuetype::napi_number) {
260 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, true);
261 return -1;
262 }
263 int32_t val = 0;
264 napi_status status = napi_get_value_int32(env, argv, &val);
265 if (status != napi_ok) {
266 HiLog::Error(LABEL, "Retrieve field failed");
267 return -1;
268 }
269 return val;
270 }
271
CreateHolidayItem(napi_env env,const HolidayInfoItem & holidayItem)272 napi_value HolidayManagerAddon::CreateHolidayItem(napi_env env, const HolidayInfoItem &holidayItem)
273 {
274 napi_value result;
275 napi_status status = napi_create_object(env, &result);
276 if (status != napi_ok) {
277 HiLog::Error(LABEL, "Create Holiday Item object failed.");
278 return nullptr;
279 }
280 status = napi_set_named_property(env, result, "baseName",
281 VariableConvertor::CreateString(env, holidayItem.baseName));
282 if (status != napi_ok) {
283 HiLog::Error(LABEL, "Failed to set element baseName.");
284 return nullptr;
285 }
286 status = napi_set_named_property(env, result, "year",
287 VariableConvertor::CreateNumber(env, holidayItem.year));
288 if (status != napi_ok) {
289 HiLog::Error(LABEL, "Failed to set element year.");
290 return nullptr;
291 }
292 status = napi_set_named_property(env, result, "month",
293 VariableConvertor::CreateNumber(env, holidayItem.month));
294 if (status != napi_ok) {
295 HiLog::Error(LABEL, "Failed to set element month.");
296 return nullptr;
297 }
298 status = napi_set_named_property(env, result, "day",
299 VariableConvertor::CreateNumber(env, holidayItem.day));
300 if (status != napi_ok) {
301 HiLog::Error(LABEL, "Failed to set element day.");
302 return nullptr;
303 }
304 napi_value localNames = HolidayLocalNameItem(env, holidayItem.localNames);
305 if (localNames != nullptr) {
306 status = napi_set_named_property(env, result, "localNames", localNames);
307 if (status != napi_ok) {
308 HiLog::Error(LABEL, "Failed to set element localNames.");
309 return nullptr;
310 }
311 }
312 return result;
313 }
314
HolidayLocalNameItem(napi_env env,const std::vector<HolidayLocalName> localNames)315 napi_value HolidayManagerAddon::HolidayLocalNameItem(napi_env env, const std::vector<HolidayLocalName> localNames)
316 {
317 napi_value result = nullptr;
318 napi_status status = napi_create_array_with_length(env, localNames.size(), &result);
319 if (status != napi_ok) {
320 HiLog::Error(LABEL, "create HolidayLocalName array failed.");
321 return nullptr;
322 }
323 for (size_t i = 0; i < localNames.size(); i++) {
324 napi_value localNameItem;
325 status = napi_create_object(env, &localNameItem);
326 if (status != napi_ok) {
327 HiLog::Error(LABEL, "Create HolidayLocalName Item object failed.");
328 return nullptr;
329 }
330 status = napi_set_named_property(env, localNameItem, "language",
331 VariableConvertor::CreateString(env, localNames[i].language));
332 if (status != napi_ok) {
333 HiLog::Error(LABEL, "Create HolidayLocalName.language Item object failed.");
334 return nullptr;
335 }
336 status = napi_set_named_property(env, localNameItem, "name",
337 VariableConvertor::CreateString(env, localNames[i].name));
338 if (status != napi_ok) {
339 HiLog::Error(LABEL, "Create HolidayLocalName.name Item object failed.");
340 return nullptr;
341 }
342 status = napi_set_element(env, result, i, localNameItem);
343 if (status != napi_ok) {
344 HiLog::Error(LABEL, "Failed to set HolidayLocalName element.");
345 return nullptr;
346 }
347 }
348 return result;
349 }
350 } // namespace I18n
351 } // namespace Global
352 } // namespace OHOS