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