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