Skip to content

Commit 45bb75b

Browse files
committed
Add support for nested paths in retain() Fix function. (#145)
1 parent 6cf83ae commit 45bb75b

File tree

7 files changed

+644
-4
lines changed

7 files changed

+644
-4
lines changed

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

+70-3
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
import java.util.concurrent.atomic.AtomicReference;
3939
import java.util.function.BiConsumer;
4040
import java.util.function.Consumer;
41+
import java.util.function.Function;
4142
import java.util.function.Predicate;
4243
import java.util.regex.Matcher;
4344
import java.util.regex.Pattern;
4445
import java.util.stream.Collectors;
46+
import java.util.stream.IntStream;
4547
import java.util.stream.Stream;
4648

4749
/**
@@ -303,6 +305,13 @@ private Value withPathAppend(final String field) {
303305
.orElseThrow());
304306
}
305307

308+
private void retainFields(final Collection<String> fields) {
309+
matchType()
310+
.ifArray(a -> a.retainFields(fields))
311+
.ifHash(h -> h.retainFields(fields))
312+
.orElseThrow();
313+
}
314+
306315
enum Type {
307316
Array,
308317
Hash,
@@ -387,6 +396,23 @@ private abstract static class AbstractValueType implements JsonValue {
387396
@Override
388397
public abstract void toJson(JsonGenerator jsonGenerator);
389398

399+
protected <T> Map<T, Collection<String>> retainFields(final Collection<String> fields, final Function<String, Set<T>> function) {
400+
final Map<T, Collection<String>> retainFields = new HashMap<>();
401+
402+
fields.forEach(p -> {
403+
final String[] parts = p.split(FIELD_PATH_SEPARATOR, 2);
404+
405+
function.apply(parts[0]).forEach(f -> {
406+
final Collection<String> retainNested = retainFields.computeIfAbsent(f, k -> new HashSet<>());
407+
if (parts.length > 1) {
408+
retainNested.add(parts[1]);
409+
}
410+
});
411+
});
412+
413+
return retainFields;
414+
}
415+
390416
}
391417

392418
/**
@@ -428,10 +454,46 @@ public Stream<Value> stream() {
428454
return list.stream();
429455
}
430456

457+
private IntStream indexes() {
458+
return IntStream.range(0, size());
459+
}
460+
431461
private void removeEmptyValues() {
432462
list.removeIf(REMOVE_EMPTY_VALUES);
433463
}
434464

465+
private void retainFields(final Collection<String> fields) {
466+
final Map<Integer, Collection<String>> retainFields = retainFields(fields, this::findFields);
467+
468+
final int max = size() - 1;
469+
indexes().map(i -> max - i).forEach(i -> {
470+
final Collection<String> retainNested = retainFields.get(i);
471+
if (retainNested == null) {
472+
remove(i);
473+
}
474+
else if (!retainNested.isEmpty()) {
475+
get(i).retainFields(retainNested);
476+
}
477+
});
478+
}
479+
480+
private Set<Integer> findFields(final String pattern) {
481+
final Set<Integer> fieldSet = new LinkedHashSet<>();
482+
483+
if ("*".equals(pattern)) {
484+
indexes().forEach(fieldSet::add);
485+
}
486+
else {
487+
final int index = Integer.parseInt(pattern) - 1; // TODO: 0-based Catmandu vs. 1-based Metafacture
488+
489+
if (index >= 0 && index < size()) {
490+
fieldSet.add(index);
491+
}
492+
}
493+
494+
return fieldSet;
495+
}
496+
435497
public void forEach(final Consumer<Value> consumer) {
436498
list.forEach(consumer);
437499
}
@@ -696,10 +758,15 @@ public void removeField(final String field) {
696758
* @param fields the field names
697759
*/
698760
public void retainFields(final Collection<String> fields) {
699-
final Set<String> retainFields = new HashSet<>();
700-
fields.forEach(f -> retainFields.addAll(findFields(f)));
761+
final Map<String, Collection<String>> retainFields = retainFields(fields, this::findFields);
701762

702-
map.keySet().retainAll(retainFields);
763+
map.keySet().retainAll(retainFields.keySet());
764+
765+
retainFields.forEach((k, v) -> {
766+
if (!v.isEmpty()) {
767+
getField(k).retainFields(v);
768+
}
769+
});
703770
}
704771

705772
/**

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

+83
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,89 @@ public void retain() {
23352335
});
23362336
}
23372337

2338+
@Test // checkstyle-disable-line JavaNCSS
2339+
public void retainNested() {
2340+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
2341+
"retain('a.b.c','a.[cd].b','b[].2.c','c[].*.a','c[].2.b')"
2342+
),
2343+
i -> {
2344+
i.startRecord("1");
2345+
i.startEntity("a");
2346+
i.startEntity("a");
2347+
i.literal("b", "1");
2348+
i.literal("c", "2");
2349+
i.endEntity();
2350+
i.startEntity("b");
2351+
i.literal("c", "1");
2352+
i.literal("d", "2");
2353+
i.endEntity();
2354+
i.startEntity("c");
2355+
i.literal("b", "1");
2356+
i.literal("c", "2");
2357+
i.endEntity();
2358+
i.endEntity();
2359+
i.startEntity("b[]");
2360+
i.startEntity("1");
2361+
i.literal("a", "1");
2362+
i.literal("b", "2");
2363+
i.endEntity();
2364+
i.startEntity("2");
2365+
i.literal("a", "1");
2366+
i.literal("b", "2");
2367+
i.literal("c", "3");
2368+
i.endEntity();
2369+
i.startEntity("3");
2370+
i.literal("c", "4");
2371+
i.endEntity();
2372+
i.endEntity();
2373+
i.startEntity("c[]");
2374+
i.startEntity("1");
2375+
i.literal("a", "1");
2376+
i.literal("b", "2");
2377+
i.endEntity();
2378+
i.startEntity("2");
2379+
i.literal("a", "1");
2380+
i.literal("b", "2");
2381+
i.literal("c", "3");
2382+
i.endEntity();
2383+
i.startEntity("3");
2384+
i.literal("c", "4");
2385+
i.endEntity();
2386+
i.endEntity();
2387+
i.startEntity("d");
2388+
i.literal("e", "5");
2389+
i.endEntity();
2390+
i.literal("e", "6");
2391+
i.endRecord();
2392+
},
2393+
(o, f) -> {
2394+
o.get().startRecord("1");
2395+
o.get().startEntity("a");
2396+
o.get().startEntity("b");
2397+
o.get().literal("c", "1");
2398+
o.get().endEntity();
2399+
o.get().startEntity("c");
2400+
o.get().literal("b", "1");
2401+
f.apply(2).endEntity();
2402+
o.get().startEntity("b[]");
2403+
o.get().startEntity("1");
2404+
o.get().literal("c", "3");
2405+
f.apply(2).endEntity();
2406+
o.get().startEntity("c[]");
2407+
o.get().startEntity("1");
2408+
o.get().literal("a", "1");
2409+
o.get().endEntity();
2410+
o.get().startEntity("2");
2411+
o.get().literal("a", "1");
2412+
o.get().literal("b", "2");
2413+
o.get().endEntity();
2414+
o.get().startEntity("3");
2415+
f.apply(2).endEntity();
2416+
o.get().endRecord();
2417+
}
2418+
);
2419+
}
2420+
23382421
@Test
23392422
public void shouldDeleteEmptyArrays() {
23402423
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(

metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/retainCertainSubfields/todo.txt

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"node" : {
3+
"properties" : {
4+
"ccm:educationallearningresourcetype" : [ "https://w3id.org/kim/hcrt/image" ]
5+
}
6+
},
7+
"lrt" : [ "https://w3id.org/kim/hcrt/image" ]
8+
}

0 commit comments

Comments
 (0)