Skip to content
This repository has been archived by the owner on Jan 27, 2025. It is now read-only.

Commit

Permalink
Merge branch '102-path' (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
fsteeg committed Feb 17, 2022
2 parents 0212600 + 2304294 commit 6b05dcf
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 48 deletions.
47 changes: 31 additions & 16 deletions metafix/src/main/java/org/metafacture/metafix/FixPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,25 @@ public FixPath(final String path) {
this(Value.split(path));
}

/*package-private*/ FixPath(final String[] path) {
private FixPath(final String[] path) {
this.path = path;
}

public Value findIn(final Hash hash) {
final String field = path[0];
if (field.equals(ASTERISK)) {
final String currentSegment = path[0];
final FixPath remainingPath = new FixPath(tail(path));

if (currentSegment.equals(ASTERISK)) {
// TODO: search in all elements of value.asHash()?
return new FixPath(tail(path)).findIn(hash);
return remainingPath.findIn(hash);
}
return path.length == 1 || !hash.containsField(field) ? hash.get(field) :
findNested(hash, field, tail(path));

final Value value = hash.get(currentSegment);
return value == null || path.length == 1 ? value : value.extractType((m, c) -> m
.ifArray(a -> c.accept(remainingPath.findIn(a)))
.ifHash(h -> c.accept(remainingPath.findIn(h)))
.orElseThrow()
);
}

/*package-private*/ Value findIn(final Array array) {
Expand Down Expand Up @@ -101,6 +108,24 @@ public Value appendIn(final Hash hash, final String newValue) {
return new FixPath(path).insertInto(hash, InsertMode.APPEND, new Value(newValue));
}

/*package-private*/ void appendIn(final Hash hash, final Value v) {
// TODO: impl and call just value.append
if (v != null) {
v.matchType()
.ifString(s -> appendIn(hash, s))
//.ifArray(a -> /* TODO: see MetafixMethodTest.moveToNestedArray */)
.ifHash(h -> {
if (path.length == 1) {
hash.add(path[0], v);
}
else {
appendIn(hash, new FixPath(tail(path)).findIn(h));
}
})
.orElseThrow();
}
}

@Override
public String toString() {
return Arrays.asList(path).toString();
Expand Down Expand Up @@ -285,15 +310,6 @@ private void transformValueAt(final Array array, final int index, final String[]
}
}

private Value findNested(final Hash hash, final String field, final String[] remainingFields) {
final Value value = hash.get(field);
return value == null ? null : value.extractType((m, c) -> m
.ifArray(a -> c.accept(new FixPath(remainingFields).findIn(a)))
.ifHash(h -> c.accept(new FixPath(remainingFields).findIn(h)))
.orElseThrow()
);
}

private void insertIntoReferencedObject(final Array array, final InsertMode mode, final Value newValue) {
// TODO replace switch, extract to enum behavior like reservedField.insertIntoReferencedObject(this)?
switch (ReservedField.fromString(path[0])) {
Expand Down Expand Up @@ -379,5 +395,4 @@ private Value getReferencedValue(final Hash hash, final String field) {
}
return referencedValue;
}

}
39 changes: 8 additions & 31 deletions metafix/src/main/java/org/metafacture/metafix/Value.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.metafacture.commons.tries.SimpleRegexTrie;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -38,7 +37,7 @@

/**
* Represents a record value, i.e., either an {@link Array}, a {@link Hash},
* or a {@link java.lang.String String}.
* or a {@link String}.
*/
public class Value {

Expand Down Expand Up @@ -250,10 +249,6 @@ public String toString() {
);
}

private static String[] tail(final String[] fields) {
return Arrays.copyOfRange(fields, 1, fields.length);
}

/*package-private*/ static String[] split(final String fieldPath) {
return fieldPath.split(FIELD_PATH_SEPARATOR);
}
Expand Down Expand Up @@ -577,31 +572,7 @@ public void removeField(final String field) {
public void copy(final List<String> params) {
final String oldName = params.get(0);
final String newName = params.get(1);
asList(new FixPath(oldName).findIn(this), a -> a.forEach(v -> appendValue(split(newName), v)));
}

private void appendValue(final String[] newName, final Value v) {
// TODO: impl and call just value.append
if (v != null) {
switch (v.type) {
case String:
new FixPath(String.join(".", newName)).appendIn(this, v.asString());
break;
case Array:
// TODO: do something here?
break;
case Hash:
if (newName.length == 1) {
add(newName[0], v);
}
else {
appendValue(newName, new FixPath(tail(newName)).findIn(v.asHash()));
}
break;
default:
break;
}
}
asList(new FixPath(oldName).findIn(this), a -> a.forEach(v -> new FixPath(newName).appendIn(this, v)));
}

/**
Expand Down Expand Up @@ -653,6 +624,12 @@ public String toString() {
return map.toString();
}

/**
* Avoids {@link ConcurrentModificationException} when modifying the hash based on matched fields.
*
* @param pattern the field name pattern
* @param consumer the action to be performed for each value
*/
/*package-private*/ void modifyFields(final String pattern, final Consumer<String> consumer) {
findFields(pattern).collect(Collectors.toSet()).forEach(consumer);
}
Expand Down
52 changes: 52 additions & 0 deletions metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,58 @@ public void shouldIterateOverListWithWildcard() {
shouldIterateOverList("n?me", 3);
}

private void shouldIterateOverListOfHashes(final String path, final int expectedCount) {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"do list(path: '" + path + "', 'var': '$i')",
" add_field('trace', 'true')",
"end",
"retain('trace')"
),
i -> {
i.startRecord("1");
i.startEntity("name");
i.literal("value", "Mary");
i.endEntity();
i.startEntity("name");
i.literal("value", "University");
i.endEntity();
i.startEntity("nome");
i.literal("value", "Max");
i.endEntity();
i.endRecord();
},
(o, f) -> {
o.get().startRecord("1");
f.apply(expectedCount).literal("trace", "true");
o.get().endRecord();
}
);
}

@Test
public void shouldIterateOverListOfHashes() {
shouldIterateOverListOfHashes("name.value", 2);
}

@Test
// See https://github.com/metafacture/metafacture-fix/issues/119
public void shouldIterateOverListOfHashesWithCharacterClass() {
shouldIterateOverListOfHashes("n[ao]me.value", 3);
}

@Test
// See https://github.com/metafacture/metafacture-fix/issues/119
@Disabled("See https://github.com/metafacture/metafacture-fix/issues/143")
public void shouldIterateOverListOfHashesWithAlternation() {
shouldIterateOverListOfHashes("name.value|nome.value", 3);
}

@Test
// See https://github.com/metafacture/metafacture-fix/issues/119
public void shouldIterateOverListOfHashesWithWildcard() {
shouldIterateOverListOfHashes("n?me.value", 3);
}

@Test // checkstyle-disable-line JavaNCSS
// See https://github.com/metafacture/metafacture-fix/issues/119
public void shouldPerformComplexOperationWithPathWildcard() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1717,7 +1717,47 @@ public void shouldSplitArrayField() {
}

@Test
@Disabled("See https://github.com/metafacture/metafacture-fix/issues/106")
@Disabled("Arrays in arrays need to be preserved. See disabled isArray in FixPath#appendIn.")
public void moveToNestedArray() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"move_field('date[]', 'd[]')"
),
i -> {
i.startRecord("1");
i.startEntity("date[]");
i.startEntity("1[]");
i.literal("1", "1918");
i.literal("2", "17");
i.literal("3", "16");
i.endEntity();
i.startEntity("2[]");
i.literal("1", "2021");
i.literal("2", "22");
i.literal("3", "23");
i.endEntity();
i.endEntity();
i.endRecord();
},
(o, f) -> {
o.get().startRecord("1");
o.get().startEntity("d[]");
o.get().startEntity("1[]");
o.get().literal("1", "1918");
o.get().literal("2", "17");
o.get().literal("3", "16");
o.get().endEntity();
o.get().startEntity("2[]");
o.get().literal("1", "2021");
o.get().literal("2", "22");
o.get().literal("3", "23");
f.apply(2).endEntity();
o.get().endRecord();
}
);
}

@Test
@Disabled("Arrays in arrays need to be preserved. See disabled isArray in FixPath#appendIn.")
public void shouldSplitMarkedArrayFieldIntoArrayOfArrays() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"split_field('date[]', '-')"
Expand Down

0 comments on commit 6b05dcf

Please sign in to comment.