Skip to content

Commit 719615f

Browse files
authored
Merge pull request #2542 from jacomago/setValue_for_PVAStructureArray
Adding the ability to update PVAStructureArray and PVAAnyArray
2 parents 84f83d7 + 701afd5 commit 719615f

File tree

5 files changed

+204
-5
lines changed

5 files changed

+204
-5
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
*
3+
* Copyright (C) 2023 European Spallation Source ERIC.
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU General Public License
7+
* as published by the Free Software Foundation; either version 2
8+
* of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18+
*/
19+
20+
package org.epics.pva.data;
21+
22+
/**
23+
* Exception for when updating a PVAStructure array with a value that
24+
* includes a PVAStructure which does not match the element type of the array.
25+
*/
26+
public class ElementTypeException extends Exception {
27+
28+
/**
29+
* Constructor returns an exception with a message based on the
30+
* new Element type and the current element type.
31+
*
32+
* @param newElementType New invalid element type
33+
* @param elementType Current valid element type
34+
*/
35+
public ElementTypeException(PVAStructure newElementType, PVAStructure elementType) {
36+
super("Element " + newElementType + " must be of type " + elementType);
37+
}
38+
}

core/pva/src/main/java/org/epics/pva/data/PVAAnyArray.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,26 @@ public PVAAnyArray(String name, final PVAny... elements) {
5757
*/
5858
private volatile PVAny[] elements;
5959

60+
/**
61+
* Set the array of elements
62+
*
63+
* @param elements Desired new set of elements */
64+
public void set(final PVAny[] elements) {
65+
this.elements = elements;
66+
}
67+
6068
@Override
6169
public void setValue(Object new_value) throws Exception {
62-
63-
// Cannot set array, only individual elements
64-
throw new Exception("Cannot set " + getType() + " " + name + " to " + new_value);
70+
if (new_value instanceof PVAAnyArray)
71+
{
72+
PVAAnyArray newValueArray = (PVAAnyArray) new_value;
73+
final PVAny[] other = newValueArray.elements;
74+
elements = Arrays.copyOf(other, other.length);
75+
}
76+
else if (new_value instanceof PVAny[])
77+
set(((PVAny[]) new_value));
78+
else
79+
throw new Exception("Cannot set " + formatType() + " to " + new_value);
6580
}
6681

6782
/** @return Current value */

core/pva/src/main/java/org/epics/pva/data/PVAStructureArray.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,36 @@ public PVAStructure[] get()
7272
return elements;
7373
}
7474

75+
/**
76+
* Set the array of elements
77+
*
78+
* @param elements Desired new set of elements */
79+
public void set(final PVAStructure[] elements) throws ElementTypeException {
80+
for (PVAStructure element: elements) {
81+
if (!element.cloneType(this.getElementType().getName()).equals(this.getElementType())) {
82+
throw new ElementTypeException(element, this.getElementType());
83+
}
84+
}
85+
this.elements = elements;
86+
}
87+
7588
@Override
7689
public void setValue(final Object new_value) throws Exception
7790
{
78-
// Cannot set structure, only individual elements
79-
throw new Exception("Cannot set " + getStructureName() + " " + name + " to " + new_value);
91+
if (new_value instanceof PVAStructureArray)
92+
{
93+
PVAStructureArray newValueArray = (PVAStructureArray) new_value;
94+
if (newValueArray.getElementType().equals(this.element_type)) {
95+
final PVAStructure[] other = newValueArray.elements;
96+
elements = Arrays.copyOf(other, other.length);
97+
} else {
98+
throw new ElementTypeException(newValueArray.getElementType(), this.element_type);
99+
}
100+
}
101+
else if (new_value instanceof PVAStructure[])
102+
set(((PVAStructure[]) new_value));
103+
else
104+
throw new Exception("Cannot set " + formatType() + " to " + new_value);
80105
}
81106

82107
/** @return Structure type name */

core/pva/src/test/java/org/epics/pva/data/PVAAnyArrayTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,60 @@ void update() throws Exception {
8888
PVAAnyArray cloneArray = anyArray.cloneData();
8989
cloneArray.get()[1].get().setValue(new PVAString("element1", "newElement2"));
9090

91+
assertNotEquals(cloneArray, anyArray);
9192
anyArray.update(0, cloneArray, new BitSet());
9293

9394
assertEquals(cloneArray, anyArray);
9495
}
96+
97+
@Test
98+
void setValue() throws Exception {
99+
// Create a Structure Array for testing
100+
PVAny[] anys = new PVAny[2];
101+
PVAStructure structure = new PVAStructure("structure0", "struct 0", new PVAString("element0", "element0value"));
102+
anys[0] = new PVAny("any s", structure);
103+
anys[1] = new PVAny("any string", new PVAString("element1", "valueElement1"));
104+
PVAAnyArray anyArray = new PVAAnyArray("anyArray", anys );
105+
106+
// Clone the structure
107+
PVAAnyArray cloneArray = anyArray.cloneData();
108+
// Modify to be different to the original array
109+
cloneArray.get()[1].get().setValue(new PVAString("element1", "newElement2"));
110+
111+
assertNotEquals(cloneArray, anyArray);
112+
113+
// Update the original to match the modified clone
114+
anyArray.setValue(cloneArray.cloneData());
115+
116+
assertEquals(cloneArray, anyArray);
117+
118+
// Modify the clone again
119+
cloneArray.get()[1].get().setValue(new PVAString("element1", "newElement3"));
120+
assertNotEquals(cloneArray, anyArray);
121+
122+
// Update the original to match the modified clone via the PVAny[]
123+
cloneArray.setValue(anyArray.get());
124+
assertEquals(cloneArray, anyArray);
125+
126+
}
127+
@Test
128+
void set() throws Exception {
129+
PVAny[] anys = new PVAny[2];
130+
PVAStructure structure = new PVAStructure("structure0", "struct 0", new PVAString("element0", "element0value"));
131+
anys[0] = new PVAny("any s", structure);
132+
anys[1] = new PVAny("any string", new PVAString("element1", "valueElement1"));
133+
PVAAnyArray anyArray = new PVAAnyArray("anyArray", anys );
134+
135+
// Clone the structure
136+
PVAAnyArray cloneArray = anyArray.cloneData();
137+
// Modify to be different to the original array
138+
cloneArray.get()[1].get().setValue(new PVAString("element1", "newElement2"));
139+
140+
assertNotEquals(cloneArray, anyArray);
141+
142+
// Update the original to match the modified clone
143+
anyArray.set(cloneArray.cloneData().get());
144+
145+
assertEquals(cloneArray, anyArray);
146+
}
95147
}

core/pva/src/test/java/org/epics/pva/data/PVAStructureArrayTest.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,77 @@ void update() throws Exception {
3939
PVAStructureArray cloneArray = structureArray.cloneData();
4040
cloneArray.get()[0].get("element0").setValue(new PVAString("element0", "newElement2"));
4141

42+
assertNotEquals(cloneArray, structureArray);
43+
4244
structureArray.update(0, cloneArray, new BitSet());
4345

4446
assertEquals(cloneArray, structureArray);
4547
}
48+
49+
@Test
50+
void setValue() throws Exception {
51+
// Create a Structure Array for testing
52+
PVAStructure[] structures = new PVAStructure[2];
53+
structures[0] = new PVAStructure("structure0", "struct 0", new PVAString("element0", "element0value"));
54+
PVAStructure second = structures[0].cloneType("structure1");
55+
second.get("element0").setValue(new PVAString("element0", "newElement1"));
56+
structures[1] = second;
57+
PVAStructureArray structureArray = new PVAStructureArray("structureArray", structures[0].cloneType("stype"),structures );
58+
59+
// Clone the structure
60+
PVAStructureArray cloneArray = structureArray.cloneData();
61+
// Modify to be different to the original array
62+
cloneArray.get()[0].get("element0").setValue(new PVAString("element0", "newElement2"));
63+
64+
assertNotEquals(cloneArray, structureArray);
65+
66+
// Update the original to match the modified clone
67+
structureArray.setValue(cloneArray.cloneData());
68+
69+
assertEquals(cloneArray, structureArray);
70+
71+
// Modify the clone again
72+
cloneArray.get()[0].get("element0").setValue(new PVAString("element0", "newElement3"));
73+
assertNotEquals(cloneArray, structureArray);
74+
75+
// Update the original to match the modified clone via the PVAStructure[]
76+
structureArray.setValue(cloneArray.get());
77+
assertEquals(cloneArray, structureArray);
78+
79+
// Check errors are thrown when incompatible types are passed in
80+
PVAStructureArray diffTypeArray = new PVAStructureArray("name",
81+
new PVAStructure("different", "diff"),
82+
new PVAStructure("different", "diff"));
83+
assertThrows(ElementTypeException.class,() -> structureArray.setValue(diffTypeArray));
84+
assertThrows(ElementTypeException.class, () -> structureArray.setValue(diffTypeArray.get()));
85+
86+
}
87+
@Test
88+
void set() throws Exception {
89+
// Create a Structure Array for testing
90+
PVAStructure[] structures = new PVAStructure[2];
91+
structures[0] = new PVAStructure("structure0", "struct 0", new PVAString("element0", "element0value"));
92+
PVAStructure second = structures[0].cloneType("structure1");
93+
second.get("element0").setValue(new PVAString("element0", "newElement1"));
94+
structures[1] = second;
95+
PVAStructureArray structureArray = new PVAStructureArray("structureArray", structures[0].cloneType("stype"),structures );
96+
97+
// Clone the structure
98+
PVAStructureArray cloneArray = structureArray.cloneData();
99+
// Modify to be different to the original array
100+
cloneArray.get()[0].get("element0").setValue(new PVAString("element0", "newElement2"));
101+
102+
assertNotEquals(cloneArray, structureArray);
103+
104+
// Update the original to match the modified clone
105+
structureArray.set(cloneArray.cloneData().get());
106+
107+
assertEquals(cloneArray, structureArray);
108+
109+
// Check errors are thrown when incompatible types are passed in
110+
PVAStructureArray diffTypeArray = new PVAStructureArray("name",
111+
new PVAStructure("different", "diff"),
112+
new PVAStructure("different", "diff"));
113+
assertThrows(ElementTypeException.class, () -> structureArray.set(diffTypeArray.get()));
114+
}
46115
}

0 commit comments

Comments
 (0)