Skip to content

Commit ea55aca

Browse files
authored
Merge pull request #231 from kit-data-manager/fix-#226-allow-arrays-of-literals-as-property-values
Fix #226 allow arrays of literals as property values
2 parents 5ecc98f + c506c5f commit ea55aca

File tree

3 files changed

+104
-39
lines changed

3 files changed

+104
-39
lines changed

src/main/java/edu/kit/datamanager/ro_crate/entities/AbstractEntity.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,12 @@ public void removeProperties(Collection<String> keys) {
158158
}
159159

160160
/**
161-
* Add a JSON property to the entity. Here the value of the property is a
162-
* String.
161+
* Adds a property to the entity.
162+
* <p>
163+
* It may override values, if the key already exists.
163164
*
164-
* @param key the name of the property (term).
165-
* @param value the value that the property has.
165+
* @param key the key of the property.
166+
* @param value value of the property.
166167
*/
167168
public void addProperty(String key, String value) {
168169
if (key != null && value != null) {
@@ -172,11 +173,12 @@ public void addProperty(String key, String value) {
172173
}
173174

174175
/**
175-
* This is another way of adding a property, this time the value is a long
176-
* integer.
176+
* Adds a property to the entity.
177+
* <p>
178+
* It may override values, if the key already exists.
177179
*
178-
* @param key the String key of the property.
179-
* @param value the long value.
180+
* @param key the key of the property.
181+
* @param value value of the property.
180182
*/
181183
public void addProperty(String key, long value) {
182184
if (key != null) {
@@ -186,10 +188,12 @@ public void addProperty(String key, long value) {
186188
}
187189

188190
/**
189-
* Another way of adding a property this time the value is a double.
191+
* Adds a property to the entity.
192+
* <p>
193+
* It may override values, if the key already exists.
190194
*
191-
* @param key the string key of the property.
192-
* @param value double value of the property.
195+
* @param key the key of the property.
196+
* @param value value of the property.
193197
*/
194198
public void addProperty(String key, double value) {
195199
if (key != null) {
@@ -199,11 +203,17 @@ public void addProperty(String key, double value) {
199203
}
200204

201205
/**
202-
* This is the most generic way of adding a property. The value is a
203-
* JsonNode that could contain anything possible. This is way firstly it is
204-
* validated that it follows the correct guidelines.
206+
* Adds a generic property to the entity.
207+
* <p>
208+
* It may fail with an error message on stdout, in which case the
209+
* value is not added.
210+
* It may override values, if the key already exists.
211+
* This is the most generic way to add a property. The value is a
212+
* JsonNode that could contain anything possible. It is limited to
213+
* objects allowed to flattened documents, which means any literal,
214+
* an array of literals, or an object with an @id property.
205215
*
206-
* @param key String key of the property.
216+
* @param key String key of the property.
207217
* @param value The JsonNode representing the value.
208218
*/
209219
public void addProperty(String key, JsonNode value) {
@@ -222,8 +232,8 @@ private static boolean addProperty(ObjectNode whereToAdd, String key, JsonNode v
222232
}
223233

224234
/**
225-
* Add a property that looks like this: "name" : {"@id" : "id"} If the name
226-
* property already exists add a second @id to it.
235+
* Add a property that looks like this: "name" : {"@id" : "id"} If the
236+
* name property already exists add a second @id to it.
227237
*
228238
* @param name the "key" of the property.
229239
* @param id the "id" of the property.

src/main/resources/json_schemas/entity_field_structure_schema.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
"items": {
88
"anyOf": [
99
{ "$ref": "#/$defs/idProperty"},
10-
{"type": "string"}
10+
{"type": "string"},
11+
{"type": "number"},
12+
{"type": "boolean"},
13+
{"type": "null"}
1114
]
1215

1316
}
@@ -30,14 +33,15 @@
3033
],
3134
"$defs" : {
3235
"idProperty": {
33-
"type": "object",
36+
"type": ["object"],
3437
"properties": {
3538
"@id": {
36-
"type": "string"
39+
"type": ["string"]
3740
}
3841
},
42+
"required": ["@id"],
3943
"additionalProperties": false
4044
}
4145

42-
}
46+
}
4347
}

src/test/java/edu/kit/datamanager/ro_crate/entities/data/DataEntityTest.java

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package edu.kit.datamanager.ro_crate.entities.data;
22

3+
import com.fasterxml.jackson.databind.JsonNode;
34
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.node.ArrayNode;
46
import com.fasterxml.jackson.databind.node.ObjectNode;
57

68
import java.io.IOException;
@@ -9,14 +11,18 @@
911
import edu.kit.datamanager.ro_crate.HelpFunctions;
1012
import edu.kit.datamanager.ro_crate.entities.data.DataEntity.DataEntityBuilder;
1113
import edu.kit.datamanager.ro_crate.objectmapper.MyObjectMapper;
12-
import java.net.MalformedURLException;
1314
import java.net.URI;
1415

1516
import java.net.URISyntaxException;
17+
import java.nio.file.Path;
1618
import java.nio.file.Paths;
1719
import java.util.Arrays;
1820
import java.util.List;
21+
import java.util.stream.Stream;
22+
1923
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.params.ParameterizedTest;
25+
import org.junit.jupiter.params.provider.MethodSource;
2026

2127
import static org.junit.jupiter.api.Assertions.assertEquals;
2228
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@@ -93,12 +99,14 @@ void testUriCheck() {
9399

94100
assertNotNull(dataEntity);
95101

96-
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
97-
new DataEntity.DataEntityBuilder()
98-
.addType("File")
99-
.setLocationWithExceptions(URI.create("zzz://wrong/url"))
100-
.build();
101-
});
102+
Exception exception = assertThrows(
103+
IllegalArgumentException.class,
104+
() ->
105+
new DataEntity.DataEntityBuilder()
106+
.addType("File")
107+
.setLocationWithExceptions(URI.create("zzz://wrong/url"))
108+
.build()
109+
);
102110

103111
assertEquals("This Data Entity remote ID does not resolve to a valid URL.", exception.getMessage());
104112

@@ -114,22 +122,25 @@ void testPathCheck() throws IOException {
114122
.addProperty("name", "RO-Crate specification")
115123
.setEncodingFormat("application/json")
116124
.build();
117-
assertEquals(dataEntity.getId(), "example.json");
125+
assertEquals("example.json", dataEntity.getId());
118126
HelpFunctions.compareEntityWithFile(dataEntity, "/json/entities/data/localFile.json");
119127

128+
String fileName = "cp7glop.ai";
129+
Path filePath = Paths.get(fileName);
130+
120131
dataEntity = new FileEntity.FileEntityBuilder()
121-
.setLocationWithExceptions(Paths.get("cp7glop.ai"))
122-
.setId("cp7glop.ai")
132+
.setLocationWithExceptions(filePath)
133+
.setId(fileName)
123134
.addProperty("name", "Diagram showing trend to increase")
124135
.setEncodingFormat("application/pdf")
125136
.build();
126-
assertEquals(dataEntity.getId(), "cp7glop.ai");
127-
assertEquals(dataEntity.getPath(), Paths.get("cp7glop.ai"));
128-
assertEquals(dataEntity.getProperty("encodingFormat").asText(), "application/pdf");
137+
assertEquals(fileName, dataEntity.getId());
138+
assertEquals(dataEntity.getPath(), filePath);
139+
assertEquals("application/pdf", dataEntity.getProperty("encodingFormat").asText());
129140
}
130141

131142
@Test
132-
void testEncodedUrl() throws MalformedURLException, URISyntaxException {
143+
void testEncodedUrl() throws URISyntaxException {
133144
//this entity id is a valid URL so there should not be any console information
134145
DataEntity dataEntity = new DataEntity.DataEntityBuilder()
135146
.addType("File")
@@ -156,15 +167,15 @@ void testEncodedUrl() throws MalformedURLException, URISyntaxException {
156167
.build();
157168

158169
assertTrue(dataEntity.getTypes().contains("File"));
159-
assertEquals(dataEntity.getId(), "almost-50%25.json");
170+
assertEquals("almost-50%25.json", dataEntity.getId());
160171

161172
// even if the Path is not correctly encoded, the data entity will be added with an encoded Path.
162173
dataEntity = new DataEntity.DataEntityBuilder()
163174
.addType("File")
164175
.setLocationWithExceptions(Paths.get("/json/crate/Results and Diagrams/almost-50%.json"))
165176
.setId("almost-50%.json")
166177
.build();
167-
assertEquals(dataEntity.getId(), "almost-50%25.json");
178+
assertEquals("almost-50%25.json", dataEntity.getId());
168179

169180
}
170181

@@ -179,10 +190,50 @@ void testRemoveProperty() {
179190

180191
dataEntity.removeProperty("url");
181192
assertNull(dataEntity.getProperty("url"));
182-
assertEquals(dataEntity.getProperties().size(), 4);
193+
assertEquals(4, dataEntity.getProperties().size());
183194

184195
List<String> keyList = Arrays.asList("encodingFormat", "name");
185196
dataEntity.removeProperties(keyList);
186-
assertEquals(dataEntity.getProperties().size(), 2);
197+
assertEquals(2, dataEntity.getProperties().size());
198+
}
199+
200+
@Test
201+
void testMixedArrayProperties() {
202+
ObjectMapper mapper = new ObjectMapper();
203+
204+
ArrayNode propertyValue = mapper.createArrayNode();
205+
propertyValue
206+
.add(1)
207+
.add("2")
208+
.add(3.14)
209+
.add(true)
210+
.add((JsonNode) null)
211+
.add(mapper.nullNode());
212+
String propertyName = "mixedArray";
213+
214+
DataEntity entity = new DataEntityBuilder()
215+
.addProperty(propertyName, propertyValue)
216+
.build();
217+
assertEquals(propertyValue, entity.getProperty(propertyName));
218+
}
219+
220+
@ParameterizedTest
221+
@MethodSource("provideInvalidPropertyValues")
222+
void testNestedArrayProperties(ArrayNode propertyValue) {
223+
String propertyName = "invalidArray";
224+
DataEntity entity = new DataEntityBuilder()
225+
.addProperty(propertyName, propertyValue)
226+
.build();
227+
assertNull(entity.getProperty(propertyName));
228+
}
229+
230+
private static Stream<ArrayNode> provideInvalidPropertyValues() {
231+
ObjectMapper mapper = new ObjectMapper();
232+
ArrayNode withSubArray = mapper.createArrayNode().add(1).add("2");
233+
withSubArray.addArray();
234+
ArrayNode withSubObject = mapper.createArrayNode().add(1).add("2");
235+
withSubObject.addObject();
236+
237+
return Stream.of(withSubArray, withSubObject);
187238
}
188239
}

0 commit comments

Comments
 (0)