From a3d853226f35d340a9f9e8a988dbd63de49cb2f5 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Wed, 19 Feb 2025 10:57:57 -0700 Subject: [PATCH] musikr: use correct object in jtagmap impl --- musikr/src/main/jni/src/jbuilder.rs | 2 +- musikr/src/main/jni/src/jtagmap.rs | 136 ++++++++++++++++++++++++++++ musikr/src/main/jni/src/lib.rs | 2 +- musikr/src/main/jni/src/tagmap.rs | 85 ----------------- 4 files changed, 138 insertions(+), 87 deletions(-) create mode 100644 musikr/src/main/jni/src/jtagmap.rs delete mode 100644 musikr/src/main/jni/src/tagmap.rs diff --git a/musikr/src/main/jni/src/jbuilder.rs b/musikr/src/main/jni/src/jbuilder.rs index caf65bb3a..5b0f18c70 100644 --- a/musikr/src/main/jni/src/jbuilder.rs +++ b/musikr/src/main/jni/src/jbuilder.rs @@ -13,7 +13,7 @@ use crate::taglib::{ xiph::{self, FLACPictureList}, }; -use crate::tagmap::JTagMap; +use crate::jtagmap::JTagMap; pub struct JMetadataBuilder<'local, 'file_ref> { env: Rc>>, diff --git a/musikr/src/main/jni/src/jtagmap.rs b/musikr/src/main/jni/src/jtagmap.rs new file mode 100644 index 000000000..580045c25 --- /dev/null +++ b/musikr/src/main/jni/src/jtagmap.rs @@ -0,0 +1,136 @@ +use jni::{ + objects::{JClass, JObject, JString, JValueGen}, + JNIEnv, +}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct JTagMap<'local> { + env: Rc>>, + tag_map: JObject<'local>, + array_list_class: JClass<'local>, +} + +impl<'local> JTagMap<'local> { + pub fn new(env: Rc>>) -> Self { + // Get NativeTagMap class and create instance + let tag_map_class = env.borrow_mut().find_class("org/oxycblt/musikr/metadata/NativeTagMap").unwrap(); + let tag_map = env.borrow_mut().new_object(&tag_map_class, "()V", &[]).unwrap(); + + // Get ArrayList class + let array_list_class = env.borrow_mut().find_class("java/util/ArrayList").unwrap(); + + Self { + env, + tag_map, + array_list_class, + } + } + + fn create_array_list(&self, values: &[String]) -> JObject<'local> { + let mut env = self.env.borrow_mut(); + let array_list = env.new_object(&self.array_list_class, "()V", &[]).unwrap(); + + for value in values { + let j_value = env.new_string(value).unwrap(); + env.call_method( + &array_list, + "add", + "(Ljava/lang/Object;)Z", + &[JValueGen::Object(&j_value)], + ).unwrap(); + } + + array_list + } + + pub fn add_id(&self, id: impl Into, value: impl Into) { + let mut env = self.env.borrow_mut(); + let j_id = env.new_string(id.into()).unwrap(); + let j_value = env.new_string(value.into()).unwrap(); + + env.call_method( + &self.tag_map, + "addID", + "(Ljava/lang/String;Ljava/lang/String;)V", + &[JValueGen::Object(&j_id), JValueGen::Object(&j_value)], + ).unwrap(); + } + + pub fn add_id_list(&self, id: impl Into, values: Vec) { + let mut env = self.env.borrow_mut(); + let j_id = env.new_string(id.into()).unwrap(); + let j_values = self.create_array_list(&values); + + env.call_method( + &self.tag_map, + "addID", + "(Ljava/lang/String;Ljava/util/List;)V", + &[JValueGen::Object(&j_id), JValueGen::Object(&j_values)], + ).unwrap(); + } + + pub fn add_custom(&self, description: impl Into, value: impl Into) { + let mut env = self.env.borrow_mut(); + let j_description = env.new_string(description.into()).unwrap(); + let j_value = env.new_string(value.into()).unwrap(); + + env.call_method( + &self.tag_map, + "addCustom", + "(Ljava/lang/String;Ljava/lang/String;)V", + &[JValueGen::Object(&j_description), JValueGen::Object(&j_value)], + ).unwrap(); + } + + pub fn add_custom_list(&self, description: impl Into, values: Vec) { + let mut env = self.env.borrow_mut(); + let j_description = env.new_string(description.into()).unwrap(); + let j_values = self.create_array_list(&values); + + env.call_method( + &self.tag_map, + "addCustom", + "(Ljava/lang/String;Ljava/util/List;)V", + &[JValueGen::Object(&j_description), JValueGen::Object(&j_values)], + ).unwrap(); + } + + pub fn add_combined(&self, id: impl Into, description: impl Into, value: impl Into) { + let mut env = self.env.borrow_mut(); + let j_id = env.new_string(id.into()).unwrap(); + let j_description = env.new_string(description.into()).unwrap(); + let j_value = env.new_string(value.into()).unwrap(); + + env.call_method( + &self.tag_map, + "addCombined", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", + &[JValueGen::Object(&j_id), JValueGen::Object(&j_description), JValueGen::Object(&j_value)], + ).unwrap(); + } + + pub fn add_combined_list(&self, id: impl Into, description: impl Into, values: Vec) { + let mut env = self.env.borrow_mut(); + let j_id = env.new_string(id.into()).unwrap(); + let j_description = env.new_string(description.into()).unwrap(); + let j_values = self.create_array_list(&values); + + env.call_method( + &self.tag_map, + "addCombined", + "(Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V", + &[JValueGen::Object(&j_id), JValueGen::Object(&j_description), JValueGen::Object(&j_values)], + ).unwrap(); + } + + pub fn get_object(&self) -> JObject<'local> { + let mut env = self.env.borrow_mut(); + env.call_method( + &self.tag_map, + "getObject", + "()Ljava/util/Map;", + &[], + ).unwrap().l().unwrap() + } +} diff --git a/musikr/src/main/jni/src/lib.rs b/musikr/src/main/jni/src/lib.rs index a5670e215..0f20cc280 100644 --- a/musikr/src/main/jni/src/lib.rs +++ b/musikr/src/main/jni/src/lib.rs @@ -11,7 +11,7 @@ use std::rc::Rc; mod jbuilder; mod jstream; mod taglib; -mod tagmap; +mod jtagmap; use jbuilder::JMetadataBuilder; use jstream::JInputStream; diff --git a/musikr/src/main/jni/src/tagmap.rs b/musikr/src/main/jni/src/tagmap.rs deleted file mode 100644 index 65c7eb075..000000000 --- a/musikr/src/main/jni/src/tagmap.rs +++ /dev/null @@ -1,85 +0,0 @@ -use jni::{ - objects::{JObject, JValueGen}, - JNIEnv, -}; -use std::cell::RefCell; -use std::collections::HashMap; -use std::rc::Rc; - -pub struct JTagMap<'local> { - env: Rc>>, - map: HashMap>, -} - -impl<'local> JTagMap<'local> { - pub fn new(env: Rc>>) -> Self { - Self { - env, - map: HashMap::new(), - } - } - - pub fn add_id(&mut self, id: impl Into, value: impl Into) { - let id = id.into(); - let value = value.into(); - self.map.entry(id).or_default().push(value); - } - - pub fn add_id_list(&mut self, id: impl Into, values: Vec) { - let id = id.into(); - self.map.entry(id).or_default().extend(values); - } - - pub fn add_combined( - &mut self, - id: impl Into, - description: impl Into, - value: impl Into, - ) { - let id = id.into(); - let description = description.into(); - let value = value.into(); - let combined_key = format!("{}:{}", id, description); - self.map.entry(combined_key).or_default().push(value); - } - - pub fn get_object(&self) -> JObject { - let mut env = self.env.borrow_mut(); - - let map_class = env.find_class("java/util/HashMap").unwrap(); - let map = env.new_object(&map_class, "()V", &[]).unwrap(); - let array_list_class = env.find_class("java/util/ArrayList").unwrap(); - - for (key, values) in &self.map { - let j_key = env.new_string(key).unwrap(); - - // Create ArrayList for values - let array_list = env.new_object(&array_list_class, "()V", &[]).unwrap(); - - // Convert all values to Java strings first - let j_values: Vec = values - .iter() - .map(|v| env.new_string(v).unwrap().into()) - .collect(); - - // Add all values to ArrayList - for value in j_values { - env.call_method( - &array_list, - "add", - "(Ljava/lang/Object;)Z", - &[JValueGen::from(&value)], - ).unwrap(); - } - - env.call_method( - &map, - "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - &[JValueGen::from(&j_key), JValueGen::from(&array_list)], - ).unwrap(); - } - - map - } -}