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

Commit

Permalink
Restrict bind scope to the bound value if no var is set (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
fsteeg committed Dec 3, 2021
1 parent eba3159 commit 1b1ee8e
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,33 @@ else if (sub instanceof Unless) {
private void processBind(final Do theDo, final EList<String> params) {
if (theDo.getName().equals("list")) { // TODO impl multiple binds via FixBind enum
final Map<String, String> options = options(theDo.getOptions());
record.findList(options.get("path"), a -> a.forEach(value -> {
record.put(options.get("var"), value);
processSubexpressions(theDo.getElements());
record.remove(options.get("var"));
}));
record.findList(options.get("path"), a -> {
for (int i = 0; i < a.size(); ++i) {
final Value value = a.get(i);
final String var = options.get("var");
// with var -> keep full record in scope, add the var:
if (var != null) {
record.put(var, value);
processSubexpressions(theDo.getElements());
record.remove(var);
}
// w/o var -> use the currently bound value as the record:
else {
if (value.isHash()) {
final Record fullRecord = record.shallowClone();
record = new Record();
record.addAll(value.asHash());
processSubexpressions(theDo.getElements());
a.set(i, new Value(record));
record = fullRecord;
}
else {
// TODO: bind to arrays (if that makes sense) and strings (access with '.')
throw new IllegalStateException(Value.UNEXPECTED + value);
}
}
}
});
}
else {
LOG.warn("Unprocessed bind: {}", theDo);
Expand Down
9 changes: 6 additions & 3 deletions metafix/src/main/java/org/metafacture/metafix/Value.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* or a {@link java.lang.String String}.
*/
public class Value {

/*package-private*/ static final String UNEXPECTED = "expected array or hash, got ";
/*package-private*/ static final String APPEND_FIELD = "$append";
private static final String LAST_FIELD = "$last";
private static final String ASTERISK = "*";
Expand Down Expand Up @@ -419,6 +419,11 @@ private void insert(final InsertMode mode, final String[] fields, final String n
break;
}
}

/*package-private*/ void set(final int i, final Value value) {
list.set(i, value);
}

}

/**
Expand All @@ -428,8 +433,6 @@ public static class Hash extends AbstractValueType {

private static final String FIELD_PATH_SEPARATOR = "\\.";

private static final String UNEXPECTED = "expected array or hash, got ";

private final Map<String, Value> map = new LinkedHashMap<>();

/**
Expand Down
68 changes: 68 additions & 0 deletions metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,74 @@ public void doListFullRecordInScope() {
});
}

@Test
public void bindingScopeWithVar() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"do list('path':'foo','var':'loop')",
" copy_field('test','loop.baz')",
" copy_field('loop.bar','loop.qux')",
"end"),
i -> {
i.startRecord("1");
i.startEntity("foo");
i.literal("bar", "1");
i.endEntity();
i.startEntity("foo");
i.literal("bar", "2");
i.endEntity();
i.literal("test", "42");
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("foo");
o.get().startEntity("1");
o.get().literal("bar", "1");
o.get().literal("baz", "42");
o.get().literal("qux", "1");
f.apply(1).endEntity();
o.get().startEntity("2");
o.get().literal("bar", "2");
o.get().literal("baz", "42");
o.get().literal("qux", "2");
f.apply(2).endEntity();
o.get().literal("test", "42");
o.get().endRecord();
});
}

@Test
public void bindingScopeWithoutVar() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"do list('path':'foo')",
" copy_field('test','baz')",
" copy_field('bar','qux')",
"end"),
i -> {
i.startRecord("1");
i.startEntity("foo");
i.literal("bar", "1");
i.endEntity();
i.startEntity("foo");
i.literal("bar", "2");
i.endEntity();
i.literal("test", "42");
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("foo");
o.get().startEntity("1");
o.get().literal("bar", "1");
o.get().literal("qux", "1");
f.apply(1).endEntity();
o.get().startEntity("2");
o.get().literal("bar", "2");
o.get().literal("qux", "2");
f.apply(2).endEntity();
o.get().literal("test", "42");
o.get().endRecord();
});
}

@Test
public void doListPathWithDots() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
Expand Down

0 comments on commit 1b1ee8e

Please sign in to comment.