1use jni::JNIEnv;
23use jni::objects::{JClass, JString};
24use jni::sys::{jlong, jint, jstring};
25use crate::hooks::{RiHookBus, RiHookEvent, RiHookKind, RiModulePhase};
26use crate::java::exception::check_not_null;
27use std::sync::Arc;
28
29#[no_mangle]
34pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookBus_new0(
35 _env: JNIEnv,
36 _class: JClass,
37) -> jlong {
38 Arc::into_raw(Arc::new(RiHookBus::new())) as jlong
41}
42
43#[no_mangle]
44pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookBus_free0(
45 _env: JNIEnv,
46 _class: JClass,
47 ptr: jlong,
48) {
49 if ptr != 0 {
50 unsafe {
53 let _ = Arc::from_raw(ptr as *const RiHookBus);
54 }
55 }
56}
57
58#[no_mangle]
59pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookBus_emit0(
60 mut env: JNIEnv,
61 _class: JClass,
62 ptr: jlong,
63 kind_ordinal: jint,
64 module: JString,
65 phase_ordinal: jint,
66) {
67 if !check_not_null(&mut env, ptr, "RiHookBus") {
68 return;
69 }
70
71 let bus = unsafe { &*(ptr as *const RiHookBus) };
72
73 let kind = match kind_ordinal {
74 0 => RiHookKind::Startup,
75 1 => RiHookKind::Shutdown,
76 2 => RiHookKind::BeforeModulesInit,
77 3 => RiHookKind::AfterModulesInit,
78 4 => RiHookKind::BeforeModulesStart,
79 5 => RiHookKind::AfterModulesStart,
80 6 => RiHookKind::BeforeModulesShutdown,
81 7 => RiHookKind::AfterModulesShutdown,
82 8 => RiHookKind::ConfigReload,
83 _ => RiHookKind::Startup,
84 };
85
86 let module_str: Option<String> = if module.is_null() {
87 None
88 } else {
89 match env.get_string(&module) {
90 Ok(s) => Some(s.into()),
91 Err(_) => None,
92 }
93 };
94
95 let phase = if phase_ordinal < 0 {
96 None
97 } else {
98 Some(match phase_ordinal {
99 0 => RiModulePhase::Init,
100 1 => RiModulePhase::BeforeStart,
101 2 => RiModulePhase::Start,
102 3 => RiModulePhase::AfterStart,
103 4 => RiModulePhase::BeforeShutdown,
104 5 => RiModulePhase::Shutdown,
105 6 => RiModulePhase::AfterShutdown,
106 7 => RiModulePhase::AsyncInit,
107 8 => RiModulePhase::AsyncBeforeStart,
108 9 => RiModulePhase::AsyncStart,
109 10 => RiModulePhase::AsyncAfterStart,
110 11 => RiModulePhase::AsyncBeforeShutdown,
111 12 => RiModulePhase::AsyncShutdown,
112 13 => RiModulePhase::AsyncAfterShutdown,
113 _ => RiModulePhase::Init,
114 })
115 };
116
117 let _ = bus.emit_simple(&kind, module_str.as_deref(), phase);
118}
119
120#[no_mangle]
121pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookBus_hasHandlers0(
122 mut env: JNIEnv,
123 _class: JClass,
124 ptr: jlong,
125 kind_ordinal: jint,
126) -> jni::sys::jboolean {
127 if !check_not_null(&mut env, ptr, "RiHookBus") {
128 return 0;
129 }
130
131 let bus = unsafe { &*(ptr as *const RiHookBus) };
132
133 let kind = match kind_ordinal {
134 0 => RiHookKind::Startup,
135 1 => RiHookKind::Shutdown,
136 2 => RiHookKind::BeforeModulesInit,
137 3 => RiHookKind::AfterModulesInit,
138 4 => RiHookKind::BeforeModulesStart,
139 5 => RiHookKind::AfterModulesStart,
140 6 => RiHookKind::BeforeModulesShutdown,
141 7 => RiHookKind::AfterModulesShutdown,
142 8 => RiHookKind::ConfigReload,
143 _ => RiHookKind::Startup,
144 };
145
146 if bus.has_handlers(&kind) { 1 } else { 0 }
147}
148
149#[no_mangle]
154pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookEvent_new0(
155 mut env: JNIEnv,
156 _class: JClass,
157 kind_ordinal: jint,
158 module: JString,
159 phase_ordinal: jint,
160) -> jlong {
161 let kind = match kind_ordinal {
162 0 => RiHookKind::Startup,
163 1 => RiHookKind::Shutdown,
164 2 => RiHookKind::BeforeModulesInit,
165 3 => RiHookKind::AfterModulesInit,
166 4 => RiHookKind::BeforeModulesStart,
167 5 => RiHookKind::AfterModulesStart,
168 6 => RiHookKind::BeforeModulesShutdown,
169 7 => RiHookKind::AfterModulesShutdown,
170 8 => RiHookKind::ConfigReload,
171 _ => RiHookKind::Startup,
172 };
173
174 let module_str: Option<String> = if module.is_null() {
175 None
176 } else {
177 env.get_string(&module).ok().map(|s| s.into())
178 };
179
180 let phase = if phase_ordinal < 0 {
181 None
182 } else {
183 Some(match phase_ordinal {
184 0 => RiModulePhase::Init,
185 1 => RiModulePhase::BeforeStart,
186 2 => RiModulePhase::Start,
187 3 => RiModulePhase::AfterStart,
188 4 => RiModulePhase::BeforeShutdown,
189 5 => RiModulePhase::Shutdown,
190 6 => RiModulePhase::AfterShutdown,
191 7 => RiModulePhase::AsyncInit,
192 8 => RiModulePhase::AsyncBeforeStart,
193 9 => RiModulePhase::AsyncStart,
194 10 => RiModulePhase::AsyncAfterStart,
195 11 => RiModulePhase::AsyncBeforeShutdown,
196 12 => RiModulePhase::AsyncShutdown,
197 13 => RiModulePhase::AsyncAfterShutdown,
198 _ => RiModulePhase::Init,
199 })
200 };
201
202 let event = Box::new(RiHookEvent::new(kind, module_str, phase));
203 Box::into_raw(event) as jlong
204}
205
206#[no_mangle]
207pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookEvent_getKind0(
208 mut env: JNIEnv,
209 _class: JClass,
210 ptr: jlong,
211) -> jint {
212 if !check_not_null(&mut env, ptr, "RiHookEvent") {
213 return 0;
214 }
215
216 let event = unsafe { &*(ptr as *const RiHookEvent) };
217 match event.kind {
218 RiHookKind::Startup => 0,
219 RiHookKind::Shutdown => 1,
220 RiHookKind::BeforeModulesInit => 2,
221 RiHookKind::AfterModulesInit => 3,
222 RiHookKind::BeforeModulesStart => 4,
223 RiHookKind::AfterModulesStart => 5,
224 RiHookKind::BeforeModulesShutdown => 6,
225 RiHookKind::AfterModulesShutdown => 7,
226 RiHookKind::ConfigReload => 8,
227 }
228}
229
230#[no_mangle]
231pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookEvent_getModule0(
232 mut env: JNIEnv,
233 _class: JClass,
234 ptr: jlong,
235) -> jstring {
236 if !check_not_null(&mut env, ptr, "RiHookEvent") {
237 return std::ptr::null_mut();
238 }
239
240 let event = unsafe { &*(ptr as *const RiHookEvent) };
241 match &event.module {
242 Some(module) => match env.new_string(module) {
243 Ok(s) => s.into_raw(),
244 Err(_) => std::ptr::null_mut(),
245 },
246 None => std::ptr::null_mut(),
247 }
248}
249
250#[no_mangle]
251pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookEvent_getPhase0(
252 mut env: JNIEnv,
253 _class: JClass,
254 ptr: jlong,
255) -> jint {
256 if !check_not_null(&mut env, ptr, "RiHookEvent") {
257 return -1;
258 }
259
260 let event = unsafe { &*(ptr as *const RiHookEvent) };
261 match &event.phase {
262 Some(phase) => match phase {
263 RiModulePhase::Init => 0,
264 RiModulePhase::BeforeStart => 1,
265 RiModulePhase::Start => 2,
266 RiModulePhase::AfterStart => 3,
267 RiModulePhase::BeforeShutdown => 4,
268 RiModulePhase::Shutdown => 5,
269 RiModulePhase::AfterShutdown => 6,
270 RiModulePhase::AsyncInit => 7,
271 RiModulePhase::AsyncBeforeStart => 8,
272 RiModulePhase::AsyncStart => 9,
273 RiModulePhase::AsyncAfterStart => 10,
274 RiModulePhase::AsyncBeforeShutdown => 11,
275 RiModulePhase::AsyncShutdown => 12,
276 RiModulePhase::AsyncAfterShutdown => 13,
277 },
278 None => -1,
279 }
280}
281
282#[no_mangle]
283pub extern "system" fn Java_com_dunimd_ri_hooks_RiHookEvent_free0(
284 _env: JNIEnv,
285 _class: JClass,
286 ptr: jlong,
287) {
288 if ptr != 0 {
289 unsafe {
290 let _ = Box::from_raw(ptr as *mut RiHookEvent);
291 }
292 }
293}