1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "annotator/annotator_jni_common.h"
18
19 #include "utils/java/jni-base.h"
20 #include "utils/java/scoped_local_ref.h"
21
22 namespace libtextclassifier3 {
23 namespace {
24
EntityTypesFromJObject(JNIEnv * env,const jobject & jobject)25 std::unordered_set<std::string> EntityTypesFromJObject(JNIEnv* env,
26 const jobject& jobject) {
27 std::unordered_set<std::string> entity_types;
28 jobjectArray jentity_types = reinterpret_cast<jobjectArray>(jobject);
29 const int size = env->GetArrayLength(jentity_types);
30 for (int i = 0; i < size; ++i) {
31 jstring jentity_type =
32 reinterpret_cast<jstring>(env->GetObjectArrayElement(jentity_types, i));
33 entity_types.insert(ToStlString(env, jentity_type));
34 }
35 return entity_types;
36 }
37
38 template <typename T>
FromJavaOptionsInternal(JNIEnv * env,jobject joptions,const std::string & class_name)39 T FromJavaOptionsInternal(JNIEnv* env, jobject joptions,
40 const std::string& class_name) {
41 if (!joptions) {
42 return {};
43 }
44
45 const ScopedLocalRef<jclass> options_class(env->FindClass(class_name.c_str()),
46 env);
47 if (!options_class) {
48 return {};
49 }
50
51 const std::pair<bool, jobject> status_or_locales = CallJniMethod0<jobject>(
52 env, joptions, options_class.get(), &JNIEnv::CallObjectMethod,
53 "getLocale", "Ljava/lang/String;");
54 const std::pair<bool, jobject> status_or_reference_timezone =
55 CallJniMethod0<jobject>(env, joptions, options_class.get(),
56 &JNIEnv::CallObjectMethod, "getReferenceTimezone",
57 "Ljava/lang/String;");
58 const std::pair<bool, int64> status_or_reference_time_ms_utc =
59 CallJniMethod0<int64>(env, joptions, options_class.get(),
60 &JNIEnv::CallLongMethod, "getReferenceTimeMsUtc",
61 "J");
62 const std::pair<bool, jobject> status_or_detected_text_language_tags =
63 CallJniMethod0<jobject>(
64 env, joptions, options_class.get(), &JNIEnv::CallObjectMethod,
65 "getDetectedTextLanguageTags", "Ljava/lang/String;");
66 const std::pair<bool, int> status_or_annotation_usecase =
67 CallJniMethod0<int>(env, joptions, options_class.get(),
68 &JNIEnv::CallIntMethod, "getAnnotationUsecase", "I");
69
70 if (!status_or_locales.first || !status_or_reference_timezone.first ||
71 !status_or_reference_time_ms_utc.first ||
72 !status_or_detected_text_language_tags.first ||
73 !status_or_annotation_usecase.first) {
74 return {};
75 }
76
77 T options;
78 options.locales =
79 ToStlString(env, reinterpret_cast<jstring>(status_or_locales.second));
80 options.reference_timezone = ToStlString(
81 env, reinterpret_cast<jstring>(status_or_reference_timezone.second));
82 options.reference_time_ms_utc = status_or_reference_time_ms_utc.second;
83 options.detected_text_language_tags = ToStlString(
84 env,
85 reinterpret_cast<jstring>(status_or_detected_text_language_tags.second));
86 options.annotation_usecase =
87 static_cast<AnnotationUsecase>(status_or_annotation_usecase.second);
88 return options;
89 }
90 } // namespace
91
FromJavaSelectionOptions(JNIEnv * env,jobject joptions)92 SelectionOptions FromJavaSelectionOptions(JNIEnv* env, jobject joptions) {
93 if (!joptions) {
94 return {};
95 }
96
97 const ScopedLocalRef<jclass> options_class(
98 env->FindClass(TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
99 "$SelectionOptions"),
100 env);
101 const std::pair<bool, jobject> status_or_locales = CallJniMethod0<jobject>(
102 env, joptions, options_class.get(), &JNIEnv::CallObjectMethod,
103 "getLocales", "Ljava/lang/String;");
104 const std::pair<bool, int> status_or_annotation_usecase =
105 CallJniMethod0<int>(env, joptions, options_class.get(),
106 &JNIEnv::CallIntMethod, "getAnnotationUsecase", "I");
107 if (!status_or_locales.first || !status_or_annotation_usecase.first) {
108 return {};
109 }
110
111 SelectionOptions options;
112 options.locales =
113 ToStlString(env, reinterpret_cast<jstring>(status_or_locales.second));
114 options.annotation_usecase =
115 static_cast<AnnotationUsecase>(status_or_annotation_usecase.second);
116
117 return options;
118 }
119
FromJavaClassificationOptions(JNIEnv * env,jobject joptions)120 ClassificationOptions FromJavaClassificationOptions(JNIEnv* env,
121 jobject joptions) {
122 return FromJavaOptionsInternal<ClassificationOptions>(
123 env, joptions,
124 TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$ClassificationOptions");
125 }
126
FromJavaAnnotationOptions(JNIEnv * env,jobject joptions)127 AnnotationOptions FromJavaAnnotationOptions(JNIEnv* env, jobject joptions) {
128 if (!joptions) return {};
129 const ScopedLocalRef<jclass> options_class(
130 env->FindClass(TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
131 "$AnnotationOptions"),
132 env);
133 if (!options_class) return {};
134 const std::pair<bool, jobject> status_or_entity_types =
135 CallJniMethod0<jobject>(env, joptions, options_class.get(),
136 &JNIEnv::CallObjectMethod, "getEntityTypes",
137 "[Ljava/lang/String;");
138 if (!status_or_entity_types.first) return {};
139 const std::pair<bool, bool> status_or_enable_serialized_entity_data =
140 CallJniMethod0<bool>(env, joptions, options_class.get(),
141 &JNIEnv::CallBooleanMethod,
142 "isSerializedEntityDataEnabled", "Z");
143 if (!status_or_enable_serialized_entity_data.first) return {};
144 AnnotationOptions annotation_options =
145 FromJavaOptionsInternal<AnnotationOptions>(
146 env, joptions,
147 TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$AnnotationOptions");
148 annotation_options.entity_types =
149 EntityTypesFromJObject(env, status_or_entity_types.second);
150 annotation_options.is_serialized_entity_data_enabled =
151 status_or_enable_serialized_entity_data.second;
152 return annotation_options;
153 }
154
155 } // namespace libtextclassifier3
156