Skip to content

Commit 550be33

Browse files
committed
Skip set_* functions when adding to an array. (#704)
With `$append`/`$prepend` the intermediate structure doesn't exist by definition.
1 parent 2c297fa commit 550be33

File tree

5 files changed

+246
-10
lines changed

5 files changed

+246
-10
lines changed

metafix/src/main/java/org/metafacture/metafix/FixPath.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@
2929
* With all get/set/update/create/delete logic collected here.
3030
*
3131
* @author Fabian Steeg (fsteeg)
32-
*
3332
*/
34-
/*package-private*/ class FixPath {
33+
public class FixPath {
3534

3635
private static final String ASTERISK = "*";
3736

@@ -40,7 +39,12 @@
4039

4140
private String[] path;
4241

43-
/*package-private*/ FixPath(final String path) {
42+
/**
43+
* Creates an instance of {@link FixPath} based on the given path string.
44+
*
45+
* @param path the path string
46+
*/
47+
public FixPath(final String path) {
4448
this(Value.split(path));
4549
}
4650

@@ -305,9 +309,29 @@ private Value insertInto(final Value value, final InsertMode mode, final Value n
305309
}
306310
}
307311

312+
/**
313+
* Checks whether the given field is adding to an array.
314+
*
315+
* @param field the field
316+
*
317+
* @return true if the given field is adding to an array
318+
*/
319+
public static boolean isAddingToArray(final String field) {
320+
return field.equals(ReservedField.$prepend.name()) || field.equals(ReservedField.$append.name());
321+
}
322+
323+
/**
324+
* Checks whether any of the path segments are adding to an array.
325+
*
326+
* @return true if any of the path segments are adding to an array
327+
*/
328+
public boolean isAddingToArray() {
329+
return Arrays.stream(path).anyMatch(FixPath::isAddingToArray);
330+
}
331+
308332
private Value getContainerValue(final Hash hash, final String field, final String newPath, final String nextField) {
309333
Value result = hash.get(field);
310-
final boolean isAddingToArray = nextField.equals(ReservedField.$prepend.name()) || nextField.equals(ReservedField.$append.name());
334+
final boolean isAddingToArray = isAddingToArray(nextField);
311335
if (result == null) {
312336
result = (isAddingToArray ? Value.newArray() : Value.newHash()).withPathSet(newPath);
313337
hash.put(field, result);
@@ -326,6 +350,15 @@ private String[] tail(final String[] fields) {
326350
return Arrays.copyOfRange(fields, 1, fields.length);
327351
}
328352

353+
/**
354+
* Creates an instance of {@link FixPath} based on the parent path.
355+
*
356+
* @return an instance of {@link FixPath}, or {@code null} if already at the top level
357+
*/
358+
public FixPath getParentPath() {
359+
return path.length > 1 ? new FixPath(Arrays.copyOfRange(path, 0, path.length - 1)) : null;
360+
}
361+
329362
private enum ReservedField {
330363
$prepend, $append, $first, $last;
331364

metafix/src/main/java/org/metafacture/metafix/api/FixFunction.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.metafacture.framework.StandardEventNames;
2020
import org.metafacture.io.ObjectWriter;
21+
import org.metafacture.metafix.FixPath;
2122
import org.metafacture.metafix.Metafix;
2223
import org.metafacture.metafix.Record;
2324
import org.metafacture.metafix.Value;
@@ -203,8 +204,9 @@ default Stream<Value> flatten(final Stream<Value> stream) {
203204
* @return true if the given field's parent field exists in the record
204205
*/
205206
default boolean parentFieldExists(final Record record, final String field) {
206-
final int index = field.lastIndexOf(Value.FIELD_PATH_SEPARATOR);
207-
return index < 1 || record.containsPath(field.substring(0, index));
207+
final FixPath path = new FixPath(field);
208+
final FixPath parentPath = path.getParentPath();
209+
return parentPath == null || !path.isAddingToArray() && record.containsPath(parentPath.toString());
208210
}
209211

210212
}

metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ public void shouldDoListAsWithMultipleListsOfDifferentSizes() {
810810
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
811811
"set_array('sourceOrga[]')",
812812
"do list_as(orgId: 'ccm:university[]', orgName: 'ccm:university_DISPLAYNAME[]', orgLoc: 'ccm:university_LOCATION[]')",
813-
" set_hash('sourceOrga[].$append')",
813+
" add_hash('sourceOrga[].$append')",
814814
" copy_field(orgId, 'sourceOrga[].$last.id')",
815815
" copy_field(orgName, 'sourceOrga[].$last.name')",
816816
" copy_field(orgLoc, 'sourceOrga[].$last.location')",

metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java

Lines changed: 204 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,209 @@ public void setHashReplaceExisting() {
19791979
});
19801980
}
19811981

1982+
@Test
1983+
public void addArrayAppend() {
1984+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
1985+
"add_array('array[].$append.test[]')"
1986+
),
1987+
i -> {
1988+
i.startRecord("1");
1989+
i.startEntity("array[]");
1990+
i.literal("1", "foo");
1991+
i.endEntity();
1992+
i.endRecord();
1993+
},
1994+
(o, f) -> {
1995+
o.get().startRecord("1");
1996+
o.get().startEntity("array[]");
1997+
o.get().literal("1", "foo");
1998+
o.get().startEntity("2");
1999+
o.get().startEntity("test[]");
2000+
f.apply(3).endEntity();
2001+
o.get().endRecord();
2002+
}
2003+
);
2004+
}
2005+
2006+
@Test
2007+
public void setArrayAppend() {
2008+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2009+
"set_array('array[].$append.test[]')"
2010+
),
2011+
i -> {
2012+
i.startRecord("1");
2013+
i.startEntity("array[]");
2014+
i.literal("1", "foo");
2015+
i.endEntity();
2016+
i.endRecord();
2017+
},
2018+
o -> {
2019+
o.get().startRecord("1");
2020+
o.get().startEntity("array[]");
2021+
o.get().literal("1", "foo");
2022+
o.get().endEntity();
2023+
o.get().endRecord();
2024+
}
2025+
);
2026+
}
2027+
2028+
@Test
2029+
public void setArrayLast() {
2030+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2031+
"set_array('array[].$last')"
2032+
),
2033+
i -> {
2034+
i.startRecord("1");
2035+
i.startEntity("array[]");
2036+
i.literal("1", "foo");
2037+
i.endEntity();
2038+
i.endRecord();
2039+
},
2040+
(o, f) -> {
2041+
o.get().startRecord("1");
2042+
o.get().startEntity("array[]");
2043+
o.get().startEntity("1[]");
2044+
f.apply(2).endEntity();
2045+
o.get().endRecord();
2046+
}
2047+
);
2048+
}
2049+
2050+
@Test
2051+
public void addFieldAppend() {
2052+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2053+
"add_field('array[].$append', 'test')"
2054+
),
2055+
i -> {
2056+
i.startRecord("1");
2057+
i.startEntity("array[]");
2058+
i.literal("1", "foo");
2059+
i.endEntity();
2060+
i.endRecord();
2061+
},
2062+
o -> {
2063+
o.get().startRecord("1");
2064+
o.get().startEntity("array[]");
2065+
o.get().literal("1", "foo");
2066+
o.get().literal("2", "test");
2067+
o.get().endEntity();
2068+
o.get().endRecord();
2069+
}
2070+
);
2071+
}
2072+
2073+
@Test
2074+
public void setFieldAppend() {
2075+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2076+
"set_field('array[].$append', 'test')"
2077+
),
2078+
i -> {
2079+
i.startRecord("1");
2080+
i.startEntity("array[]");
2081+
i.literal("1", "foo");
2082+
i.endEntity();
2083+
i.endRecord();
2084+
},
2085+
o -> {
2086+
o.get().startRecord("1");
2087+
o.get().startEntity("array[]");
2088+
o.get().literal("1", "foo");
2089+
o.get().endEntity();
2090+
o.get().endRecord();
2091+
}
2092+
);
2093+
}
2094+
2095+
@Test
2096+
public void setFieldLast() {
2097+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2098+
"set_field('array[].$last', 'test')"
2099+
),
2100+
i -> {
2101+
i.startRecord("1");
2102+
i.startEntity("array[]");
2103+
i.literal("1", "foo");
2104+
i.endEntity();
2105+
i.endRecord();
2106+
},
2107+
o -> {
2108+
o.get().startRecord("1");
2109+
o.get().startEntity("array[]");
2110+
o.get().literal("1", "test");
2111+
o.get().endEntity();
2112+
o.get().endRecord();
2113+
}
2114+
);
2115+
}
2116+
2117+
@Test
2118+
public void addHashAppend() {
2119+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2120+
"add_hash('array[].$append.test')"
2121+
),
2122+
i -> {
2123+
i.startRecord("1");
2124+
i.startEntity("array[]");
2125+
i.literal("1", "foo");
2126+
i.endEntity();
2127+
i.endRecord();
2128+
},
2129+
(o, f) -> {
2130+
o.get().startRecord("1");
2131+
o.get().startEntity("array[]");
2132+
o.get().literal("1", "foo");
2133+
o.get().startEntity("2");
2134+
o.get().startEntity("test");
2135+
f.apply(3).endEntity();
2136+
o.get().endRecord();
2137+
}
2138+
);
2139+
}
2140+
2141+
@Test
2142+
public void setHashAppend() {
2143+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2144+
"set_hash('array[].$append.test')"
2145+
),
2146+
i -> {
2147+
i.startRecord("1");
2148+
i.startEntity("array[]");
2149+
i.literal("1", "foo");
2150+
i.endEntity();
2151+
i.endRecord();
2152+
},
2153+
o -> {
2154+
o.get().startRecord("1");
2155+
o.get().startEntity("array[]");
2156+
o.get().literal("1", "foo");
2157+
o.get().endEntity();
2158+
o.get().endRecord();
2159+
}
2160+
);
2161+
}
2162+
2163+
@Test
2164+
public void setHashLast() {
2165+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2166+
"set_hash('array[].$last')"
2167+
),
2168+
i -> {
2169+
i.startRecord("1");
2170+
i.startEntity("array[]");
2171+
i.literal("1", "foo");
2172+
i.endEntity();
2173+
i.endRecord();
2174+
},
2175+
(o, f) -> {
2176+
o.get().startRecord("1");
2177+
o.get().startEntity("array[]");
2178+
o.get().startEntity("1");
2179+
f.apply(2).endEntity();
2180+
o.get().endRecord();
2181+
}
2182+
);
2183+
}
2184+
19822185
@Test
19832186
public void paste() {
19842187
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
@@ -2449,7 +2652,7 @@ public void appendArray() {
24492652
public void mixedArray() {
24502653
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
24512654
"set_array('@context[]', 'https://w3id.org/kim/lrmi-profile/draft/context.jsonld')",
2452-
"set_hash('@context[].$append', '@language': 'de')"),
2655+
"add_hash('@context[].$append', '@language': 'de')"),
24532656
i -> {
24542657
i.startRecord("1");
24552658
i.endRecord();

metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/set_arrayIntoArrayOfObjectsWithAppend/expected.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,5 @@
1212
}, {
1313
"name" : "Blacky",
1414
"type" : "bird"
15-
}, { }, {
16-
"test" : [ "test", "test", "test" ]
1715
} ]
1816
}

0 commit comments

Comments
 (0)