Skip to content

Commit 0239a9a

Browse files
committed
Support Matrix in AttributeReader and AttributeWriter
1 parent 35f0317 commit 0239a9a

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

opc-ua-sdk/sdk-server/src/main/java/org/eclipse/milo/opcua/sdk/server/AttributeReader.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,15 @@ public static DataValue readAttribute(
116116
try {
117117
NumericRange range = NumericRange.parse(indexRange);
118118

119-
Object valueAtRange = NumericRange.readFromValueAtRange(dv.getValue().getValue(), range);
119+
Object valueAtRange;
120+
if (dv.getValue().getValue() instanceof Matrix matrix) {
121+
valueAtRange = NumericRange.readFromValueAtRange(matrix.nestedArrayValue(), range);
122+
if (ArrayUtil.getValueRank(valueAtRange) > 1) {
123+
valueAtRange = new Matrix(valueAtRange);
124+
}
125+
} else {
126+
valueAtRange = NumericRange.readFromValueAtRange(dv.getValue(), range);
127+
}
120128

121129
return dvb.setValue(Variant.of(valueAtRange))
122130
.applyTimestamps(attributeId, timestamps)

opc-ua-sdk/sdk-server/src/main/java/org/eclipse/milo/opcua/sdk/server/AttributeWriter.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,7 @@
2828
import org.eclipse.milo.opcua.stack.core.NodeIds;
2929
import org.eclipse.milo.opcua.stack.core.StatusCodes;
3030
import org.eclipse.milo.opcua.stack.core.UaException;
31-
import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString;
32-
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
33-
import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
34-
import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject;
35-
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
36-
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
37-
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
31+
import org.eclipse.milo.opcua.stack.core.types.builtin.*;
3832
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte;
3933
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
4034
import org.eclipse.milo.opcua.stack.core.util.ArrayUtil;
@@ -107,10 +101,24 @@ public static StatusCode writeAttribute(
107101
try {
108102
NumericRange range = NumericRange.parse(indexRange);
109103

110-
Object current = node.getAttribute(AccessContext.INTERNAL, attributeId);
104+
Object currentValue = node.getAttribute(AccessContext.INTERNAL, attributeId);
105+
if (currentValue instanceof DataValue dataValue) {
106+
currentValue = dataValue.getValue().getValue();
107+
}
108+
if (currentValue instanceof Matrix matrix) {
109+
currentValue = matrix.nestedArrayValue();
110+
}
111+
112+
Object updateValue = updateVariant.getValue();
113+
if (updateValue instanceof Matrix matrix) {
114+
updateValue = matrix.nestedArrayValue();
115+
}
116+
117+
Object valueAtRange = NumericRange.writeToValueAtRange(currentValue, updateValue, range);
111118

112-
Object valueAtRange =
113-
NumericRange.writeToValueAtRange(Variant.of(current), updateVariant, range);
119+
if (ArrayUtil.getValueRank(valueAtRange) > 1) {
120+
valueAtRange = new Matrix(valueAtRange);
121+
}
114122

115123
updateVariant = new Variant(valueAtRange);
116124
} catch (UaException e) {
@@ -252,6 +260,10 @@ private static DataValue validateDataType(
252260
}
253261
}
254262

263+
if (o instanceof Matrix matrix) {
264+
o = matrix.nestedArrayValue();
265+
}
266+
255267
Class<?> valueClass = o.getClass().isArray() ? ArrayUtil.getType(o) : o.getClass();
256268

257269
Class<?> expectedClass = getExpectedClass(server, dataType, valueClass);
@@ -296,6 +308,10 @@ private static void validateArrayType(
296308
Object o = variant.getValue();
297309
if (o == null) return;
298310

311+
if (o instanceof Matrix matrix) {
312+
o = matrix.nestedArrayValue();
313+
}
314+
299315
boolean valueIsArray = o.getClass().isArray();
300316

301317
switch (valueRank) {

opc-ua-stack/stack-core/src/main/java/org/eclipse/milo/opcua/stack/core/util/ArrayUtil.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,26 @@ public static int[] getDimensions(Object array) {
104104
return dimensions.toArray();
105105
}
106106

107+
/**
108+
* Get the ValueRank of an Object that may or may not be an array.
109+
*
110+
* <p>The return value is either -1 (scalar) or the number of dimensions (>=1).
111+
*
112+
* @param array the Object to check.
113+
* @return the ValueRank of the object.
114+
*/
115+
public static int getValueRank(Object array) {
116+
Class<?> type = array.getClass();
117+
int rank = 0;
118+
119+
while (type.isArray()) {
120+
rank++;
121+
type = type.getComponentType();
122+
}
123+
124+
return rank == 0 ? -1 : rank;
125+
}
126+
107127
public static Class<?> getType(Object array) {
108128
Class<?> type = array.getClass();
109129

opc-ua-stack/stack-core/src/test/java/org/eclipse/milo/opcua/stack/core/util/ArrayUtilTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import static org.junit.jupiter.api.Assertions.assertEquals;
1515

1616
import java.lang.reflect.Array;
17+
import org.junit.jupiter.api.Test;
1718
import org.junit.jupiter.params.ParameterizedTest;
1819
import org.junit.jupiter.params.provider.MethodSource;
1920

@@ -93,4 +94,12 @@ public static Object[][] getTypedArrays() {
9394
public void testGetType(Object array, Class<?> type) throws Exception {
9495
assertEquals(type, ArrayUtil.getType(array));
9596
}
97+
98+
@Test
99+
void getValueRank() {
100+
assertEquals(-1, ArrayUtil.getValueRank(0));
101+
assertEquals(1, ArrayUtil.getValueRank(new int[1]));
102+
assertEquals(2, ArrayUtil.getValueRank(new int[1][1]));
103+
assertEquals(3, ArrayUtil.getValueRank(new int[1][1][1]));
104+
}
96105
}

0 commit comments

Comments
 (0)