yeg
2026-09-29 b78295e8da96c3e5e76befeef9582ce5273dbb74
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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;
import com.battery.device.api.TestDataObservationAdapter;
 
/** 管理启用设备适配器的运行时实例及其会话生命周期。 */
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;
        }
 
        synchronized (this)
        {
            RegisteredAdapter current = adapters.get(config.adapterCode());
            if (current != null && current.config.equals(config)) return;
            if (!factories.containsKey(normalizeType(config.adapterType())))
                throw new AdapterRegistryException("Unsupported device adapter type: " + config.adapterType());
        }
 
        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 = acquire(adapterCode);
        try
        {
            return operation.apply(registered.adapter);
        }
        finally
        {
            registered.operationLock.unlock();
        }
    }
 
    /**
     * 在实例级串行边界内按测试数据观测契约执行。
     * 实例缺失或未提供该契约时明确失败,不回退到其他实例。
     */
    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);
    }
 
    /** 关闭全部已注册实例并清空实例表;逐个等待在途操作结束。 */
    @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;
        }
    }
}