Skip to content

Commit 74d61a4

Browse files
committed
~ clean up type hierarchy and codecs
1 parent 4db7395 commit 74d61a4

File tree

18 files changed

+1055
-924
lines changed

18 files changed

+1055
-924
lines changed

milo-examples/client-examples/src/main/java/org/eclipse/milo/examples/client/UnifiedAutomationReadCustomDataTypeExample1.java

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 the Eclipse Milo Authors
2+
* Copyright (c) 2025 the Eclipse Milo Authors
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -18,9 +18,10 @@
1818
import java.util.UUID;
1919
import java.util.concurrent.CompletableFuture;
2020
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
21-
import org.eclipse.milo.opcua.sdk.core.types.DynamicEnum;
22-
import org.eclipse.milo.opcua.sdk.core.types.DynamicOptionSet;
23-
import org.eclipse.milo.opcua.sdk.core.types.DynamicStruct;
21+
import org.eclipse.milo.opcua.sdk.core.types.DynamicEnumType;
22+
import org.eclipse.milo.opcua.sdk.core.types.DynamicOptionSetType;
23+
import org.eclipse.milo.opcua.sdk.core.types.DynamicStructType;
24+
import org.eclipse.milo.opcua.sdk.core.types.DynamicType;
2425
import org.eclipse.milo.opcua.stack.core.encoding.EncodingContext;
2526
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
2627
import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString;
@@ -64,40 +65,40 @@ public void run(OpcUaClient client, CompletableFuture<OpcUaClient> future) throw
6465
private void readWriteReadPerson(OpcUaClient client) throws Exception {
6566
NodeId nodeId = NodeId.parse("ns=3;s=Person1");
6667

67-
DynamicStruct value = readScalarValue(client, nodeId);
68+
DynamicStructType value = (DynamicStructType) readScalarValue(client, nodeId);
6869
logger.info("Person1: {}", value);
6970

7071
Random r = new Random();
71-
DynamicEnum gender = (DynamicEnum) value.getMembers().get("Gender");
72+
DynamicEnumType gender = (DynamicEnumType) value.getMembers().get("Gender");
7273
value.getMembers().put("Name", "Fat Boy" + r.nextInt(100));
73-
value.getMembers().put("Gender", new DynamicEnum(gender.getDataType(), r.nextInt(2)));
74+
value.getMembers().put("Gender", new DynamicEnumType(gender.getDataType(), r.nextInt(2)));
7475

7576
StatusCode status = writeValue(client, nodeId, value);
7677
System.out.println("write status: " + status);
7778

78-
value = readScalarValue(client, nodeId);
79+
value = (DynamicStructType) readScalarValue(client, nodeId);
7980
logger.info("Person1': {}", value);
8081
}
8182

8283
private void readWriteReadWorkOrder(OpcUaClient client) throws Exception {
8384
NodeId nodeId = NodeId.parse("ns=3;s=Demo.Static.Scalar.WorkOrder");
8485

85-
DynamicStruct value = readScalarValue(client, nodeId);
86+
DynamicStructType value = (DynamicStructType) readScalarValue(client, nodeId);
8687
logger.info("WorkOrder: {}", value);
8788

8889
value.getMembers().put("ID", UUID.randomUUID());
8990

9091
StatusCode status = writeValue(client, nodeId, value);
9192
System.out.println("write status: " + status);
9293

93-
value = readScalarValue(client, nodeId);
94+
value = (DynamicStructType) readScalarValue(client, nodeId);
9495
logger.info("WorkOrder': {}", value);
9596
}
9697

9798
private void readWriteCarExtras(OpcUaClient client) throws Exception {
9899
NodeId nodeId = NodeId.parse("ns=3;s=Demo.Static.Scalar.CarExtras");
99100

100-
DynamicOptionSet value = (DynamicOptionSet) readScalarValue(client, nodeId);
101+
DynamicOptionSetType value = (DynamicOptionSetType) readScalarValue(client, nodeId);
101102
logger.info("CarExtras: {}", value);
102103

103104
byte b = requireNonNull(value.getValue().bytes())[0];
@@ -106,33 +107,32 @@ private void readWriteCarExtras(OpcUaClient client) throws Exception {
106107
StatusCode status = writeValue(client, nodeId, value);
107108
System.out.println("write status: " + status);
108109

109-
value = (DynamicOptionSet) readScalarValue(client, nodeId);
110+
value = (DynamicOptionSetType) readScalarValue(client, nodeId);
110111
logger.info("CarExtras': {}", value);
111112
}
112113

113114
private void readWorkOrderArray(OpcUaClient client) throws Exception {
114115
NodeId nodeId = NodeId.parse("ns=3;s=Demo.Static.Arrays.WorkOrder");
115116

116-
DynamicStruct[] value = readArrayValue(client, nodeId);
117+
DynamicType[] value = readArrayValue(client, nodeId);
117118

118119
logger.info("WorkOrderArray:");
119120
for (int i = 0; i < value.length; i++) {
120121
logger.info(" WorkOrder[{}]: {}", i, value[i]);
121122
}
122123
}
123124

124-
private static DynamicStruct readScalarValue(OpcUaClient client, NodeId nodeId) throws Exception {
125+
private static DynamicType readScalarValue(OpcUaClient client, NodeId nodeId) throws Exception {
125126
DataValue dataValue =
126127
client.readValues(0.0, TimestampsToReturn.Neither, List.of(nodeId)).get(0);
127128

128129
ExtensionObject xo = (ExtensionObject) dataValue.getValue().getValue();
129130
assert xo != null;
130131

131-
return (DynamicStruct) xo.decode(client.getDynamicEncodingContext());
132+
return (DynamicType) xo.decode(client.getDynamicEncodingContext());
132133
}
133134

134-
private static DynamicStruct[] readArrayValue(OpcUaClient client, NodeId nodeId)
135-
throws Exception {
135+
private static DynamicType[] readArrayValue(OpcUaClient client, NodeId nodeId) throws Exception {
136136
DataValue dataValue =
137137
client.readValues(0.0, TimestampsToReturn.Neither, List.of(nodeId)).get(0);
138138

@@ -141,13 +141,12 @@ private static DynamicStruct[] readArrayValue(OpcUaClient client, NodeId nodeId)
141141

142142
EncodingContext ctx = client.getDynamicEncodingContext();
143143

144-
return Arrays.stream(xos)
145-
.map(xo -> (DynamicStruct) xo.decode(ctx))
146-
.toArray(DynamicStruct[]::new);
144+
return Arrays.stream(xos).map(xo -> (DynamicType) xo.decode(ctx)).toArray(DynamicType[]::new);
147145
}
148146

149-
private static StatusCode writeValue(OpcUaClient client, NodeId nodeId, DynamicStruct value)
147+
private static StatusCode writeValue(OpcUaClient client, NodeId nodeId, DynamicType value)
150148
throws Exception {
149+
151150
ExtensionObject xo =
152151
ExtensionObject.encodeDefaultBinary(
153152
client.getDynamicEncodingContext(), value, value.getDataType().getBinaryEncodingId());
@@ -160,7 +159,7 @@ private static StatusCode writeValue(OpcUaClient client, NodeId nodeId, DynamicS
160159
@Override
161160
public String getEndpointUrl() {
162161
// Change this if UaCPPServer is running somewhere other than localhost.
163-
return "opc.tcp://localhost:48010";
162+
return "opc.tcp://192.168.1.66:48010";
164163
}
165164

166165
@Override

opc-ua-sdk/integration-tests/src/test/java/org/eclipse/milo/opcua/sdk/client/DynamicMatrixTestTypeTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 the Eclipse Milo Authors
2+
* Copyright (c) 2025 the Eclipse Milo Authors
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -14,7 +14,7 @@
1414
import static org.junit.jupiter.api.Assertions.assertNotNull;
1515

1616
import org.eclipse.milo.opcua.sdk.client.nodes.UaVariableNode;
17-
import org.eclipse.milo.opcua.sdk.core.types.DynamicStruct;
17+
import org.eclipse.milo.opcua.sdk.core.types.DynamicStructType;
1818
import org.eclipse.milo.opcua.sdk.test.AbstractClientServerTest;
1919
import org.eclipse.milo.opcua.sdk.test.MatrixTestType;
2020
import org.eclipse.milo.opcua.stack.core.UaException;
@@ -38,7 +38,7 @@ public void read() throws UaException {
3838
ExtensionObject xo = (ExtensionObject) value.getValue().getValue();
3939
assert xo != null;
4040

41-
DynamicStruct decoded = (DynamicStruct) xo.decode(client.getDynamicEncodingContext());
41+
DynamicStructType decoded = (DynamicStructType) xo.decode(client.getDynamicEncodingContext());
4242
assertEquals(
4343
MatrixTestType.TYPE_ID,
4444
decoded.getTypeId().absolute(client.getNamespaceTable()).orElseThrow());

opc-ua-sdk/sdk-client/src/main/java/org/eclipse/milo/opcua/sdk/client/OpcUaClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 the Eclipse Milo Authors
2+
* Copyright (c) 2025 the Eclipse Milo Authors
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -39,7 +39,7 @@
3939
import org.eclipse.milo.opcua.sdk.client.subscriptions.OpcUaSubscription;
4040
import org.eclipse.milo.opcua.sdk.client.subscriptions.PublishingManager;
4141
import org.eclipse.milo.opcua.sdk.client.typetree.DataTypeTreeBuilder;
42-
import org.eclipse.milo.opcua.sdk.core.types.DynamicCodecFactory;
42+
import org.eclipse.milo.opcua.sdk.core.types.codec.DynamicCodecFactory;
4343
import org.eclipse.milo.opcua.sdk.core.typetree.DataType;
4444
import org.eclipse.milo.opcua.sdk.core.typetree.DataTypeTree;
4545
import org.eclipse.milo.opcua.stack.core.AttributeId;

opc-ua-sdk/sdk-core/src/main/java/org/eclipse/milo/opcua/sdk/core/types/DynamicEnum.java renamed to opc-ua-sdk/sdk-core/src/main/java/org/eclipse/milo/opcua/sdk/core/types/DynamicEnumType.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
import org.eclipse.milo.opcua.stack.core.types.structured.EnumField;
2424
import org.jspecify.annotations.Nullable;
2525

26-
public class DynamicEnum implements UaEnumeratedType {
26+
public final class DynamicEnumType extends DynamicType implements UaEnumeratedType {
2727

2828
private final DataType dataType;
2929
private final String name;
3030
private final int value;
3131
private final LocalizedText displayName;
3232
private final LocalizedText description;
3333

34-
public DynamicEnum(DataType dataType, int value) {
34+
public DynamicEnumType(DataType dataType, int value) {
3535
this.dataType = dataType;
3636

3737
EnumDefinition definition = (EnumDefinition) dataType.getDataTypeDefinition();
@@ -53,7 +53,7 @@ public DynamicEnum(DataType dataType, int value) {
5353
throw new IllegalArgumentException("value: " + value);
5454
}
5555

56-
public DynamicEnum(
56+
public DynamicEnumType(
5757
DataType dataType,
5858
String name,
5959
int value,
@@ -76,6 +76,7 @@ public int getValue() {
7676
return value;
7777
}
7878

79+
@Override
7980
public DataType getDataType() {
8081
return dataType;
8182
}
@@ -95,7 +96,7 @@ public LocalizedText getDescription() {
9596
@Override
9697
public boolean equals(Object o) {
9798
if (o == null || getClass() != o.getClass()) return false;
98-
DynamicEnum that = (DynamicEnum) o;
99+
DynamicEnumType that = (DynamicEnumType) o;
99100
return value == that.value
100101
&& Objects.equals(dataType.getNodeId(), that.dataType.getNodeId())
101102
&& Objects.equals(name, that.name);
@@ -108,17 +109,17 @@ public int hashCode() {
108109

109110
@Override
110111
public String toString() {
111-
return new StringJoiner(", ", DynamicEnum.class.getSimpleName() + "[", "]")
112+
return new StringJoiner(", ", DynamicEnumType.class.getSimpleName() + "[", "]")
112113
.add("name='" + name + "'")
113114
.add("value=" + value)
114115
.toString();
115116
}
116117

117-
public static DynamicEnum newInstance(DataType dataType, int value) {
118-
return new DynamicEnum(dataType, value);
118+
public static DynamicEnumType newInstance(DataType dataType, int value) {
119+
return new DynamicEnumType(dataType, value);
119120
}
120121

121-
public static Function<Integer, DynamicEnum> newInstanceFactory(DataType dataType) {
122-
return value -> new DynamicEnum(dataType, value);
122+
public static Function<Integer, DynamicEnumType> newInstanceFactory(DataType dataType) {
123+
return value -> new DynamicEnumType(dataType, value);
123124
}
124125
}

opc-ua-sdk/sdk-core/src/main/java/org/eclipse/milo/opcua/sdk/core/types/DynamicOptionSet.java renamed to opc-ua-sdk/sdk-core/src/main/java/org/eclipse/milo/opcua/sdk/core/types/DynamicOptionSetType.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,43 @@
1818
import java.util.Map;
1919
import java.util.StringJoiner;
2020
import org.eclipse.milo.opcua.sdk.core.typetree.DataType;
21+
import org.eclipse.milo.opcua.stack.core.types.UaStructuredType;
2122
import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString;
23+
import org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId;
2224
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
2325
import org.eclipse.milo.opcua.stack.core.types.structured.EnumDefinition;
2426
import org.eclipse.milo.opcua.stack.core.types.structured.EnumField;
2527
import org.eclipse.milo.opcua.stack.core.util.Lazy;
2628
import org.jspecify.annotations.Nullable;
2729

28-
public class DynamicOptionSet extends DynamicStruct {
30+
public final class DynamicOptionSetType extends DynamicType implements UaStructuredType {
2931

3032
private final Lazy<Map<Integer, EnumField>> lazyFieldMap = new Lazy<>();
3133

32-
public DynamicOptionSet(DataType dataType) {
34+
private final DataType dataType;
35+
private final LinkedHashMap<String, Object> members;
36+
37+
public DynamicOptionSetType(DataType dataType) {
3338
this(dataType, new LinkedHashMap<>());
3439
}
3540

36-
public DynamicOptionSet(DataType dataType, LinkedHashMap<String, Object> members) {
37-
super(dataType, members);
41+
public DynamicOptionSetType(DataType dataType, LinkedHashMap<String, Object> members) {
42+
this.dataType = dataType;
43+
this.members = members;
44+
}
45+
46+
@Override
47+
public ExpandedNodeId getTypeId() {
48+
return dataType.getNodeId().expanded();
49+
}
50+
51+
@Override
52+
public DataType getDataType() {
53+
return dataType;
54+
}
55+
56+
public LinkedHashMap<String, Object> getMembers() {
57+
return members;
3858
}
3959

4060
public ByteString getValue() {
@@ -76,7 +96,7 @@ private Map<Integer, EnumField> getFieldMap() {
7696
() -> {
7797
Map<Integer, EnumField> fieldMap = Collections.synchronizedMap(new HashMap<>());
7898

79-
EnumDefinition definition = (EnumDefinition) getDataType().getDataTypeDefinition();
99+
EnumDefinition definition = (EnumDefinition) dataType.getDataTypeDefinition();
80100
assert definition != null;
81101

82102
EnumField[] fields = requireNonNullElse(definition.getFields(), new EnumField[0]);
@@ -91,7 +111,7 @@ private Map<Integer, EnumField> getFieldMap() {
91111

92112
@Override
93113
public String toString() {
94-
return new StringJoiner(", ", DynamicOptionSet.class.getSimpleName() + "[", "]")
114+
return new StringJoiner(", ", DynamicOptionSetType.class.getSimpleName() + "[", "]")
95115
.add("value=" + toBitString(getValue()))
96116
.add("validBits=" + toBitString(getValidBits()))
97117
.toString();

0 commit comments

Comments
 (0)