package com.battery.device.api.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.battery.device.api.DeviceAdapter;
|
|
/** 管理启用设备适配器的运行时实例及其会话生命周期。 */
|
public final class DeviceAdapterRegistry implements AutoCloseable
|
{
|
private final Map<String, DeviceAdapterFactory> factories = new HashMap<>();
|
private final Map<String, RegisteredAdapter> adapters = new HashMap<>();
|
|
public DeviceAdapterRegistry(List<DeviceAdapterFactory> 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> T execute(String adapterCode, Function<DeviceAdapter, T> 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<RegisteredAdapter> 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;
|
}
|
}
|
}
|