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