use crate::activity::{Activity, ActivityFactory};
use crate::model::ProcessElement;
use std::collections::HashMap;
use std::sync::Arc;
pub trait Plugin: Send + Sync + std::fmt::Debug {
fn name(&self) -> &str;
fn version(&self) -> &str;
fn initialize(&mut self) -> Result<(), PluginError>;
fn get_activity_factories(&self) -> HashMap<String, Arc<dyn ActivityFactory>>;
fn get_custom_activity_types(&self) -> Vec<String>;
}
#[derive(Debug, thiserror::Error)]
pub enum PluginError {
#[error("Plugin initialization failed: {0}")]
InitializationFailed(String),
#[error("Plugin not found: {0}")]
NotFound(String),
}
pub struct PluginRegistry {
plugins: Arc<tokio::sync::RwLock<HashMap<String, Arc<dyn Plugin>>>>,
activity_factories: Arc<tokio::sync::RwLock<HashMap<String, Arc<dyn ActivityFactory>>>>,
}
impl PluginRegistry {
pub fn new() -> Self {
Self {
plugins: Arc::new(tokio::sync::RwLock::new(HashMap::new())),
activity_factories: Arc::new(tokio::sync::RwLock::new(HashMap::new())),
}
}
pub async fn register(&self, plugin: Arc<dyn Plugin>) -> Result<(), PluginError> {
let plugin_name = plugin.name().to_string();
{
let mut plugins = self.plugins.write().await;
plugins.insert(plugin_name.clone(), plugin.clone());
}
{
let mut factories = self.activity_factories.write().await;
for (activity_type, factory) in plugin.get_activity_factories() {
factories.insert(activity_type, factory);
}
}
Ok(())
}
pub async fn get_activity_factory(&self, activity_type: &str) -> Option<Arc<dyn ActivityFactory>> {
let factories = self.activity_factories.read().await;
factories.get(activity_type).cloned()
}
pub async fn get_plugins(&self) -> Vec<Arc<dyn Plugin>> {
let plugins = self.plugins.read().await;
plugins.values().cloned().collect()
}
}
impl Default for PluginRegistry {
fn default() -> Self {
Self::new()
}
}