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 <unicode/locid.h>
17 #include "error_util.h"
18 #include "i18n_hilog.h"
19 #include "utils.h"
20 #include "variable_convertor.h"
21 #include "entity_recognizer_addon.h"
22
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
EntityRecognizerAddon()26 EntityRecognizerAddon::EntityRecognizerAddon() {}
27
~EntityRecognizerAddon()28 EntityRecognizerAddon::~EntityRecognizerAddon()
29 {
30 }
31
Destructor(napi_env env,void * nativeObject,void * hint)32 void EntityRecognizerAddon::Destructor(napi_env env, void *nativeObject, void *hint)
33 {
34 if (!nativeObject) {
35 return;
36 }
37 delete reinterpret_cast<EntityRecognizerAddon *>(nativeObject);
38 nativeObject = nullptr;
39 }
40
InitEntityRecognizer(napi_env env,napi_value exports)41 napi_value EntityRecognizerAddon::InitEntityRecognizer(napi_env env, napi_value exports)
42 {
43 napi_property_descriptor properties[] = {
44 DECLARE_NAPI_FUNCTION("findEntityInfo", FindEntityInfo)
45 };
46 napi_value entityConstructor = nullptr;
47 napi_status status = napi_define_class(env, "EntityRecognizer", NAPI_AUTO_LENGTH, constructor, nullptr,
48 sizeof(properties) / sizeof(napi_property_descriptor), properties, &entityConstructor);
49 if (status != napi_ok) {
50 HILOG_ERROR_I18N("Failed to define class EntityRecognizer at Init.");
51 return nullptr;
52 }
53 status = napi_set_named_property(env, exports, "EntityRecognizer", entityConstructor);
54 if (status != napi_ok) {
55 HILOG_ERROR_I18N("Set property failed when InitEntityRecognizer");
56 return nullptr;
57 }
58 return exports;
59 }
60
constructor(napi_env env,napi_callback_info info)61 napi_value EntityRecognizerAddon::constructor(napi_env env, napi_callback_info info)
62 {
63 size_t argc = 1;
64 napi_value argv[1] = { nullptr };
65 napi_value thisVar = nullptr;
66 void *data = nullptr;
67 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
68 if (status != napi_ok) {
69 return nullptr;
70 }
71 std::string localeStr;
72 if (argc < 1) {
73 localeStr = LocaleConfig::GetSystemLocale();
74 } else {
75 napi_valuetype valueType = napi_valuetype::napi_undefined;
76 napi_typeof(env, argv[0], &valueType);
77 if (valueType != napi_valuetype::napi_string) {
78 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "string", true);
79 return nullptr;
80 }
81 int32_t code = 0;
82 localeStr = VariableConvertor::GetString(env, argv[0], code);
83 if (code != 0) {
84 return nullptr;
85 }
86 }
87 UErrorCode localeStatus = U_ZERO_ERROR;
88 icu::Locale locale = icu::Locale::forLanguageTag(localeStr, localeStatus);
89 if (!IsValidLocaleTag(locale)) {
90 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", true);
91 return nullptr;
92 }
93 std::unique_ptr<EntityRecognizerAddon> obj = std::make_unique<EntityRecognizerAddon>();
94 status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
95 EntityRecognizerAddon::Destructor, nullptr, nullptr);
96 if (status != napi_ok) {
97 return nullptr;
98 }
99 obj->entityRecognizer_ = std::make_unique<EntityRecognizer>(locale);
100 if (!obj->entityRecognizer_) {
101 return nullptr;
102 }
103 obj.release();
104 return thisVar;
105 }
106
FindEntityInfo(napi_env env,napi_callback_info info)107 napi_value EntityRecognizerAddon::FindEntityInfo(napi_env env, napi_callback_info info)
108 {
109 size_t argc = 1;
110 napi_value argv[1] = { 0 };
111 napi_value thisVar = nullptr;
112 void *data = nullptr;
113 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
114 if (status != napi_ok) {
115 return nullptr;
116 } else if (argc < 1) {
117 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "text", "", true);
118 return nullptr;
119 }
120 napi_valuetype valueType = napi_valuetype::napi_undefined;
121 napi_typeof(env, argv[0], &valueType);
122 if (valueType != napi_valuetype::napi_string) {
123 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "text", "string", true);
124 return nullptr;
125 }
126 int32_t code = 0;
127 std::string message = VariableConvertor::GetString(env, argv[0], code);
128 if (code != 0) {
129 return nullptr;
130 }
131 EntityRecognizerAddon *obj = nullptr;
132 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
133 if (status != napi_ok || obj == nullptr || obj->entityRecognizer_ == nullptr) {
134 HILOG_ERROR_I18N("Get EntityRecognizer object failed");
135 return nullptr;
136 }
137 std::vector<std::vector<int>> entityInfo = obj->entityRecognizer_->FindEntityInfo(message);
138 napi_value result = GetEntityInfoItem(env, entityInfo);
139 return result;
140 }
141
GetEntityInfoItem(napi_env env,std::vector<std::vector<int>> & entityInfo)142 napi_value EntityRecognizerAddon::GetEntityInfoItem(napi_env env, std::vector<std::vector<int>>& entityInfo)
143 {
144 napi_value result = nullptr;
145 napi_status status = napi_create_array_with_length(env, entityInfo[0][0] + entityInfo[1][0], &result);
146 if (status != napi_ok) {
147 HILOG_ERROR_I18N("create EntityInfo array failed.");
148 return nullptr;
149 }
150 std::vector<std::string> types = {"phone_number", "date"};
151 int index = 0;
152 for (std::string::size_type t = 0; t < types.size(); t++) {
153 for (int i = 0; i < entityInfo[t][0]; i++) {
154 int begin = entityInfo[t][2 * i + 1];
155 int end = entityInfo[t][2 * i + 2];
156 std::string type = types[t];
157 napi_value item = CreateEntityInfoItem(env, begin, end, type);
158 status = napi_set_element(env, result, index, item);
159 index++;
160 if (status != napi_ok) {
161 HILOG_ERROR_I18N("Failed to set item element.");
162 return nullptr;
163 }
164 }
165 }
166 return result;
167 }
168
CreateEntityInfoItem(napi_env env,const int begin,const int end,const std::string & type)169 napi_value EntityRecognizerAddon::CreateEntityInfoItem(napi_env env, const int begin,
170 const int end, const std::string& type)
171 {
172 napi_value result;
173 napi_status status = napi_create_object(env, &result);
174 if (status != napi_ok) {
175 HILOG_ERROR_I18N("Create EntityInfoItem object failed.");
176 return nullptr;
177 }
178 status = napi_set_named_property(env, result, "begin",
179 VariableConvertor::CreateNumber(env, begin));
180 if (status != napi_ok) {
181 HILOG_ERROR_I18N("Failed to set element begin.");
182 return nullptr;
183 }
184 status = napi_set_named_property(env, result, "end",
185 VariableConvertor::CreateNumber(env, end));
186 if (status != napi_ok) {
187 HILOG_ERROR_I18N("Failed to set element end.");
188 return nullptr;
189 }
190 status = napi_set_named_property(env, result, "type",
191 VariableConvertor::CreateString(env, type));
192 if (status != napi_ok) {
193 HILOG_ERROR_I18N("Failed to set element type.");
194 return nullptr;
195 }
196 return result;
197 }
198
199 } // namespace I18n
200 } // namespace Global
201 } // namespace OHOS