From 147428971be43eed90a79f3849f15000d3855390 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 28 九月 2026 15:15:22 +0800
Subject: [PATCH] 实现新威 7.6 直连取数与逐行接收

---
 battery-device-api/src/main/java/com/battery/device/api/registry/DeviceAdapterRegistry.java |   75 ++++++++++++++++++++++++++++++-------
 1 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/battery-device-api/src/main/java/com/battery/device/api/registry/DeviceAdapterRegistry.java b/battery-device-api/src/main/java/com/battery/device/api/registry/DeviceAdapterRegistry.java
index e2072aa..f2c51c5 100644
--- a/battery-device-api/src/main/java/com/battery/device/api/registry/DeviceAdapterRegistry.java
+++ b/battery-device-api/src/main/java/com/battery/device/api/registry/DeviceAdapterRegistry.java
@@ -8,6 +8,7 @@
 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
@@ -34,18 +35,36 @@
             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);
     }
@@ -54,14 +73,7 @@
     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);
@@ -72,6 +84,41 @@
         }
     }
 
+    /**
+     * 在实例级串行边界内按测试数据观测契约执行。
+     * 实例缺失或未提供该契约时明确失败,不回退到其他实例。
+     */
+    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);

--
Gitblit v1.7.1