| | |
| | | import java.util.concurrent.locks.ReentrantLock; |
| | | import java.util.function.Function; |
| | | import com.battery.device.api.DeviceAdapter; |
| | | import com.battery.device.api.TestDataObservationAdapter; |
| | | |
| | | /** 管理启用设备适配器的运行时实例及其会话生命周期。 */ |
| | | public final class DeviceAdapterRegistry implements AutoCloseable |
| | |
| | | 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) |
| | | if (!factories.containsKey(normalizeType(config.adapterType()))) |
| | | throw new AdapterRegistryException("Unsupported device adapter type: " + config.adapterType()); |
| | | } |
| | | |
| | | DeviceAdapter replacement = factory.create(config); |
| | | previous = adapters.put(config.adapterCode(), new RegisteredAdapter(config, replacement)); |
| | | DeviceAdapterFactory factory = factories.get(normalizeType(config.adapterType())); |
| | | register(config, factory.create(config)); |
| | | } |
| | | |
| | | /** |
| | | * 注册已构造的运行时实例。代码装配实例与数据库配置实例共用同一份实例表, |
| | | * 使发现与取数按同一适配器编码解析,避免同编码出现两个实例。 |
| | | */ |
| | | public void register(AdapterInstanceConfig config, DeviceAdapter adapter) |
| | | { |
| | | Objects.requireNonNull(config, "config"); |
| | | Objects.requireNonNull(adapter, "adapter"); |
| | | if (!config.enabled()) |
| | | { |
| | | remove(config.adapterCode()); |
| | | return; |
| | | } |
| | | |
| | | RegisteredAdapter previous; |
| | | synchronized (this) |
| | | { |
| | | previous = adapters.put(config.adapterCode(), new RegisteredAdapter(config, adapter)); |
| | | } |
| | | 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(); |
| | | } |
| | | RegisteredAdapter registered = acquire(adapterCode); |
| | | try |
| | | { |
| | | return operation.apply(registered.adapter); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 在实例级串行边界内按测试数据观测契约执行。 |
| | | * 实例缺失或未提供该契约时明确失败,不回退到其他实例。 |
| | | */ |
| | | public <T> T executeTestData(String adapterCode, Function<TestDataObservationAdapter, T> operation) |
| | | { |
| | | Objects.requireNonNull(operation, "operation"); |
| | | RegisteredAdapter registered = acquire(adapterCode); |
| | | try |
| | | { |
| | | if (!(registered.adapter instanceof TestDataObservationAdapter observation)) |
| | | throw new AdapterRegistryException( |
| | | "Device adapter does not expose test data observation: " + adapterCode); |
| | | return operation.apply(observation); |
| | | } |
| | | finally |
| | | { |
| | | registered.operationLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** 取用实例并持有其串行锁;调用方必须在 finally 中释放。 */ |
| | | private RegisteredAdapter acquire(String adapterCode) |
| | | { |
| | | RegisteredAdapter registered; |
| | | synchronized (this) |
| | | { |
| | | registered = adapters.get(adapterCode); |
| | | if (registered == null) |
| | | throw new AdapterRegistryException("Device adapter is not enabled: " + adapterCode); |
| | | registered.operationLock.lock(); |
| | | } |
| | | return registered; |
| | | } |
| | | |
| | | public synchronized boolean contains(String adapterCode) |
| | | { |
| | | return adapters.containsKey(adapterCode); |