package com.ruoyi.device.registry; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import com.ruoyi.device.api.DeviceAdapter; /** 管理启用设备适配器的运行时实例及其会话生命周期。 */ public final class DeviceAdapterRegistry implements AutoCloseable { private final Map factories = new HashMap<>(); private final Map adapters = new HashMap<>(); public DeviceAdapterRegistry(List factories) { Objects.requireNonNull(factories, "factories").forEach(factory -> { String type = normalizeType(factory.adapterType()); if (this.factories.put(type, factory) != null) throw new IllegalArgumentException("Duplicate device adapter factory: " + type); }); } /** 按数据库或代码配置注册、替换或移除运行时实例。 */ public void synchronize(AdapterInstanceConfig config) { Objects.requireNonNull(config, "config"); if (!config.enabled()) { remove(config.adapterCode()); return; } RegisteredAdapter previous; synchronized (this) { RegisteredAdapter current = adapters.get(config.adapterCode()); if (current != null && current.config.equals(config)) return; DeviceAdapterFactory factory = factories.get(normalizeType(config.adapterType())); if (factory == null) throw new AdapterRegistryException("Unsupported device adapter type: " + config.adapterType()); DeviceAdapter replacement = factory.create(config); previous = adapters.put(config.adapterCode(), new RegisteredAdapter(config, replacement)); } closeWhenIdle(previous); } /** 在实例级串行边界内执行一次适配器操作;未注册时给出可识别失败。 */ public T execute(String adapterCode, Function operation) { Objects.requireNonNull(operation, "operation"); RegisteredAdapter registered; synchronized (this) { registered = adapters.get(adapterCode); if (registered == null) throw new AdapterRegistryException("Device adapter is not enabled: " + adapterCode); registered.operationLock.lock(); } try { return operation.apply(registered.adapter); } finally { registered.operationLock.unlock(); } } public synchronized boolean contains(String adapterCode) { return adapters.containsKey(adapterCode); } @Override public void close() { List registered; synchronized (this) { registered = List.copyOf(adapters.values()); adapters.clear(); } registered.forEach(this::closeWhenIdle); } private void remove(String adapterCode) { RegisteredAdapter previous; synchronized (this) { previous = adapters.remove(adapterCode); } closeWhenIdle(previous); } private void closeWhenIdle(RegisteredAdapter registered) { if (registered == null) return; registered.operationLock.lock(); try { registered.adapter.close(); } finally { registered.operationLock.unlock(); } } private static String normalizeType(String value) { return Objects.requireNonNull(value, "adapterType").trim().toUpperCase(Locale.ROOT); } private static final class RegisteredAdapter { private final AdapterInstanceConfig config; private final DeviceAdapter adapter; private final ReentrantLock operationLock = new ReentrantLock(true); private RegisteredAdapter(AdapterInstanceConfig config, DeviceAdapter adapter) { this.config = config; this.adapter = adapter; } } }