19596a2c1Sopenharmony_ci/* 29596a2c1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License. 59596a2c1Sopenharmony_ci * You may obtain a copy of the License at 69596a2c1Sopenharmony_ci * 79596a2c1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 89596a2c1Sopenharmony_ci * 99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and 139596a2c1Sopenharmony_ci * limitations under the License. 149596a2c1Sopenharmony_ci */ 159596a2c1Sopenharmony_ci 169596a2c1Sopenharmony_ci#include <unicode/locid.h> 179596a2c1Sopenharmony_ci#include "error_util.h" 189596a2c1Sopenharmony_ci#include "i18n_hilog.h" 199596a2c1Sopenharmony_ci#include "utils.h" 209596a2c1Sopenharmony_ci#include "variable_convertor.h" 219596a2c1Sopenharmony_ci#include "entity_recognizer_addon.h" 229596a2c1Sopenharmony_ci 239596a2c1Sopenharmony_cinamespace OHOS { 249596a2c1Sopenharmony_cinamespace Global { 259596a2c1Sopenharmony_cinamespace I18n { 269596a2c1Sopenharmony_ciEntityRecognizerAddon::EntityRecognizerAddon() {} 279596a2c1Sopenharmony_ci 289596a2c1Sopenharmony_ciEntityRecognizerAddon::~EntityRecognizerAddon() 299596a2c1Sopenharmony_ci{ 309596a2c1Sopenharmony_ci} 319596a2c1Sopenharmony_ci 329596a2c1Sopenharmony_civoid EntityRecognizerAddon::Destructor(napi_env env, void *nativeObject, void *hint) 339596a2c1Sopenharmony_ci{ 349596a2c1Sopenharmony_ci if (!nativeObject) { 359596a2c1Sopenharmony_ci return; 369596a2c1Sopenharmony_ci } 379596a2c1Sopenharmony_ci delete reinterpret_cast<EntityRecognizerAddon *>(nativeObject); 389596a2c1Sopenharmony_ci nativeObject = nullptr; 399596a2c1Sopenharmony_ci} 409596a2c1Sopenharmony_ci 419596a2c1Sopenharmony_cinapi_value EntityRecognizerAddon::InitEntityRecognizer(napi_env env, napi_value exports) 429596a2c1Sopenharmony_ci{ 439596a2c1Sopenharmony_ci napi_property_descriptor properties[] = { 449596a2c1Sopenharmony_ci DECLARE_NAPI_FUNCTION("findEntityInfo", FindEntityInfo) 459596a2c1Sopenharmony_ci }; 469596a2c1Sopenharmony_ci napi_value entityConstructor = nullptr; 479596a2c1Sopenharmony_ci napi_status status = napi_define_class(env, "EntityRecognizer", NAPI_AUTO_LENGTH, constructor, nullptr, 489596a2c1Sopenharmony_ci sizeof(properties) / sizeof(napi_property_descriptor), properties, &entityConstructor); 499596a2c1Sopenharmony_ci if (status != napi_ok) { 509596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to define class EntityRecognizer at Init."); 519596a2c1Sopenharmony_ci return nullptr; 529596a2c1Sopenharmony_ci } 539596a2c1Sopenharmony_ci status = napi_set_named_property(env, exports, "EntityRecognizer", entityConstructor); 549596a2c1Sopenharmony_ci if (status != napi_ok) { 559596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Set property failed when InitEntityRecognizer"); 569596a2c1Sopenharmony_ci return nullptr; 579596a2c1Sopenharmony_ci } 589596a2c1Sopenharmony_ci return exports; 599596a2c1Sopenharmony_ci} 609596a2c1Sopenharmony_ci 619596a2c1Sopenharmony_cinapi_value EntityRecognizerAddon::constructor(napi_env env, napi_callback_info info) 629596a2c1Sopenharmony_ci{ 639596a2c1Sopenharmony_ci size_t argc = 1; 649596a2c1Sopenharmony_ci napi_value argv[1] = { nullptr }; 659596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 669596a2c1Sopenharmony_ci void *data = nullptr; 679596a2c1Sopenharmony_ci napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 689596a2c1Sopenharmony_ci if (status != napi_ok) { 699596a2c1Sopenharmony_ci return nullptr; 709596a2c1Sopenharmony_ci } 719596a2c1Sopenharmony_ci std::string localeStr; 729596a2c1Sopenharmony_ci if (argc < 1) { 739596a2c1Sopenharmony_ci localeStr = LocaleConfig::GetSystemLocale(); 749596a2c1Sopenharmony_ci } else { 759596a2c1Sopenharmony_ci napi_valuetype valueType = napi_valuetype::napi_undefined; 769596a2c1Sopenharmony_ci napi_typeof(env, argv[0], &valueType); 779596a2c1Sopenharmony_ci if (valueType != napi_valuetype::napi_string) { 789596a2c1Sopenharmony_ci ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "string", true); 799596a2c1Sopenharmony_ci return nullptr; 809596a2c1Sopenharmony_ci } 819596a2c1Sopenharmony_ci int32_t code = 0; 829596a2c1Sopenharmony_ci localeStr = VariableConvertor::GetString(env, argv[0], code); 839596a2c1Sopenharmony_ci if (code != 0) { 849596a2c1Sopenharmony_ci return nullptr; 859596a2c1Sopenharmony_ci } 869596a2c1Sopenharmony_ci } 879596a2c1Sopenharmony_ci UErrorCode localeStatus = U_ZERO_ERROR; 889596a2c1Sopenharmony_ci icu::Locale locale = icu::Locale::forLanguageTag(localeStr, localeStatus); 899596a2c1Sopenharmony_ci if (!IsValidLocaleTag(locale)) { 909596a2c1Sopenharmony_ci ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", true); 919596a2c1Sopenharmony_ci return nullptr; 929596a2c1Sopenharmony_ci } 939596a2c1Sopenharmony_ci std::unique_ptr<EntityRecognizerAddon> obj = std::make_unique<EntityRecognizerAddon>(); 949596a2c1Sopenharmony_ci status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), 959596a2c1Sopenharmony_ci EntityRecognizerAddon::Destructor, nullptr, nullptr); 969596a2c1Sopenharmony_ci if (status != napi_ok) { 979596a2c1Sopenharmony_ci return nullptr; 989596a2c1Sopenharmony_ci } 999596a2c1Sopenharmony_ci obj->entityRecognizer_ = std::make_unique<EntityRecognizer>(locale); 1009596a2c1Sopenharmony_ci if (!obj->entityRecognizer_) { 1019596a2c1Sopenharmony_ci return nullptr; 1029596a2c1Sopenharmony_ci } 1039596a2c1Sopenharmony_ci obj.release(); 1049596a2c1Sopenharmony_ci return thisVar; 1059596a2c1Sopenharmony_ci} 1069596a2c1Sopenharmony_ci 1079596a2c1Sopenharmony_cinapi_value EntityRecognizerAddon::FindEntityInfo(napi_env env, napi_callback_info info) 1089596a2c1Sopenharmony_ci{ 1099596a2c1Sopenharmony_ci size_t argc = 1; 1109596a2c1Sopenharmony_ci napi_value argv[1] = { 0 }; 1119596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 1129596a2c1Sopenharmony_ci void *data = nullptr; 1139596a2c1Sopenharmony_ci napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 1149596a2c1Sopenharmony_ci if (status != napi_ok) { 1159596a2c1Sopenharmony_ci return nullptr; 1169596a2c1Sopenharmony_ci } else if (argc < 1) { 1179596a2c1Sopenharmony_ci ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "text", "", true); 1189596a2c1Sopenharmony_ci return nullptr; 1199596a2c1Sopenharmony_ci } 1209596a2c1Sopenharmony_ci napi_valuetype valueType = napi_valuetype::napi_undefined; 1219596a2c1Sopenharmony_ci napi_typeof(env, argv[0], &valueType); 1229596a2c1Sopenharmony_ci if (valueType != napi_valuetype::napi_string) { 1239596a2c1Sopenharmony_ci ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "text", "string", true); 1249596a2c1Sopenharmony_ci return nullptr; 1259596a2c1Sopenharmony_ci } 1269596a2c1Sopenharmony_ci int32_t code = 0; 1279596a2c1Sopenharmony_ci std::string message = VariableConvertor::GetString(env, argv[0], code); 1289596a2c1Sopenharmony_ci if (code != 0) { 1299596a2c1Sopenharmony_ci return nullptr; 1309596a2c1Sopenharmony_ci } 1319596a2c1Sopenharmony_ci EntityRecognizerAddon *obj = nullptr; 1329596a2c1Sopenharmony_ci status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 1339596a2c1Sopenharmony_ci if (status != napi_ok || obj == nullptr || obj->entityRecognizer_ == nullptr) { 1349596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Get EntityRecognizer object failed"); 1359596a2c1Sopenharmony_ci return nullptr; 1369596a2c1Sopenharmony_ci } 1379596a2c1Sopenharmony_ci std::vector<std::vector<int>> entityInfo = obj->entityRecognizer_->FindEntityInfo(message); 1389596a2c1Sopenharmony_ci napi_value result = GetEntityInfoItem(env, entityInfo); 1399596a2c1Sopenharmony_ci return result; 1409596a2c1Sopenharmony_ci} 1419596a2c1Sopenharmony_ci 1429596a2c1Sopenharmony_cinapi_value EntityRecognizerAddon::GetEntityInfoItem(napi_env env, std::vector<std::vector<int>>& entityInfo) 1439596a2c1Sopenharmony_ci{ 1449596a2c1Sopenharmony_ci napi_value result = nullptr; 1459596a2c1Sopenharmony_ci napi_status status = napi_create_array_with_length(env, entityInfo[0][0] + entityInfo[1][0], &result); 1469596a2c1Sopenharmony_ci if (status != napi_ok) { 1479596a2c1Sopenharmony_ci HILOG_ERROR_I18N("create EntityInfo array failed."); 1489596a2c1Sopenharmony_ci return nullptr; 1499596a2c1Sopenharmony_ci } 1509596a2c1Sopenharmony_ci std::vector<std::string> types = {"phone_number", "date"}; 1519596a2c1Sopenharmony_ci int index = 0; 1529596a2c1Sopenharmony_ci for (std::string::size_type t = 0; t < types.size(); t++) { 1539596a2c1Sopenharmony_ci for (int i = 0; i < entityInfo[t][0]; i++) { 1549596a2c1Sopenharmony_ci int begin = entityInfo[t][2 * i + 1]; 1559596a2c1Sopenharmony_ci int end = entityInfo[t][2 * i + 2]; 1569596a2c1Sopenharmony_ci std::string type = types[t]; 1579596a2c1Sopenharmony_ci napi_value item = CreateEntityInfoItem(env, begin, end, type); 1589596a2c1Sopenharmony_ci status = napi_set_element(env, result, index, item); 1599596a2c1Sopenharmony_ci index++; 1609596a2c1Sopenharmony_ci if (status != napi_ok) { 1619596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to set item element."); 1629596a2c1Sopenharmony_ci return nullptr; 1639596a2c1Sopenharmony_ci } 1649596a2c1Sopenharmony_ci } 1659596a2c1Sopenharmony_ci } 1669596a2c1Sopenharmony_ci return result; 1679596a2c1Sopenharmony_ci} 1689596a2c1Sopenharmony_ci 1699596a2c1Sopenharmony_cinapi_value EntityRecognizerAddon::CreateEntityInfoItem(napi_env env, const int begin, 1709596a2c1Sopenharmony_ci const int end, const std::string& type) 1719596a2c1Sopenharmony_ci{ 1729596a2c1Sopenharmony_ci napi_value result; 1739596a2c1Sopenharmony_ci napi_status status = napi_create_object(env, &result); 1749596a2c1Sopenharmony_ci if (status != napi_ok) { 1759596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Create EntityInfoItem object failed."); 1769596a2c1Sopenharmony_ci return nullptr; 1779596a2c1Sopenharmony_ci } 1789596a2c1Sopenharmony_ci status = napi_set_named_property(env, result, "begin", 1799596a2c1Sopenharmony_ci VariableConvertor::CreateNumber(env, begin)); 1809596a2c1Sopenharmony_ci if (status != napi_ok) { 1819596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to set element begin."); 1829596a2c1Sopenharmony_ci return nullptr; 1839596a2c1Sopenharmony_ci } 1849596a2c1Sopenharmony_ci status = napi_set_named_property(env, result, "end", 1859596a2c1Sopenharmony_ci VariableConvertor::CreateNumber(env, end)); 1869596a2c1Sopenharmony_ci if (status != napi_ok) { 1879596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to set element end."); 1889596a2c1Sopenharmony_ci return nullptr; 1899596a2c1Sopenharmony_ci } 1909596a2c1Sopenharmony_ci status = napi_set_named_property(env, result, "type", 1919596a2c1Sopenharmony_ci VariableConvertor::CreateString(env, type)); 1929596a2c1Sopenharmony_ci if (status != napi_ok) { 1939596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to set element type."); 1949596a2c1Sopenharmony_ci return nullptr; 1959596a2c1Sopenharmony_ci } 1969596a2c1Sopenharmony_ci return result; 1979596a2c1Sopenharmony_ci} 1989596a2c1Sopenharmony_ci 1999596a2c1Sopenharmony_ci} // namespace I18n 2009596a2c1Sopenharmony_ci} // namespace Global 2019596a2c1Sopenharmony_ci} // namespace OHOS