Skip to content

Commit

Permalink
Extend Vars support. (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
blackwinter committed Dec 9, 2021
1 parent 4e26885 commit 53ebbda
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 19 deletions.
10 changes: 10 additions & 0 deletions metafix/src/main/java/org/metafacture/metafix/FixMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ enum FixMethod {

// SCRIPT-LEVEL METHODS:

put_var {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
metafix.putVar(params.get(0), params.get(1));
}
},
put_vars {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
options.forEach(metafix::putVar);
}
},
put_map {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
metafix.putMap(params.get(0), options);
Expand Down
16 changes: 10 additions & 6 deletions metafix/src/main/java/org/metafacture/metafix/Metafix.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ public Metafix(final Reader morphDef) {
}

public Metafix(final Reader fixDef, final Map<String, String> vars) {
buildPipeline(fixDef, vars);
fix = FixStandaloneSetup.parseFix(fixDef);
this.vars = vars;
init();
}

Expand All @@ -114,11 +115,6 @@ public void literal(final String name, final String value) {
});
}

private void buildPipeline(final Reader fixDef, final Map<String, String> theVars) {
this.fix = FixStandaloneSetup.parseFix(fixDef);
this.vars = theVars;
}

@Override
public void startRecord(final String identifier) {
currentRecord = new Record();
Expand Down Expand Up @@ -247,6 +243,14 @@ public Map<String, String> getVars() {
return vars;
}

public void putVar(final String key, final String value) {
if (vars == NO_VARS) {
vars = new HashMap<>();
}

vars.put(key, value);
}

public Record getCurrentRecord() {
return currentRecord;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.metafacture.metafix.fix.Options;
import org.metafacture.metafix.fix.Unless;

import org.eclipse.emf.common.util.EList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -73,9 +72,13 @@ private String resolveVars(final String string) {
return string == null ? null : StringUtil.format(string, Metafix.VAR_START, Metafix.VAR_END, false, metafix.getVars());
}

private List<String> resolveParams(final List<String> params) {
return params.stream().map(this::resolveVars).collect(Collectors.toList());
}

private void processSubexpressions(final List<Expression> expressions) {
for (final Expression sub : expressions) {
final EList<String> params = sub.getParams();
final List<String> params = resolveParams(sub.getParams());
if (sub instanceof Do) {
processBind((Do) sub, params);
}
Expand All @@ -91,7 +94,7 @@ else if (sub instanceof Unless) {
}
}

private void processBind(final Do theDo, final EList<String> params) {
private void processBind(final Do theDo, final List<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 -> {
Expand Down Expand Up @@ -131,27 +134,27 @@ record = fullRecord;
}
}

private void processIf(final If ifExp, final EList<String> parameters) {
private void processIf(final If ifExp, final List<String> params) {
final ElsIf elsIfExp = ifExp.getElseIf();
final Else elseExp = ifExp.getElse();
if (testConditional(ifExp.getName(), parameters)) {
if (testConditional(ifExp.getName(), params)) {
processSubexpressions(ifExp.getElements());
}
else if (elsIfExp != null && testConditional(elsIfExp.getName(), elsIfExp.getParams())) {
else if (elsIfExp != null && testConditional(elsIfExp.getName(), resolveParams(elsIfExp.getParams()))) {
processSubexpressions(elsIfExp.getElements());
}
else if (elseExp != null) {
processSubexpressions(elseExp.getElements());
}
}

private void processUnless(final Unless unless, final EList<String> parameters) {
if (!testConditional(unless.getName(), parameters)) {
private void processUnless(final Unless unless, final List<String> params) {
if (!testConditional(unless.getName(), params)) {
processSubexpressions(unless.getElements());
}
}

private boolean testConditional(final String conditional, final EList<String> params) {
private boolean testConditional(final String conditional, final List<String> params) {
LOG.debug("<IF>: {} parameters: {}", conditional, params);
boolean result = false;
if ("exists".equals(conditional)) {
Expand All @@ -174,16 +177,15 @@ private boolean testConditional(final String conditional, final EList<String> pa
// functionFactory.registerClass("not_equals", NotEquals.class);
// functionFactory.registerClass("replace_all", Replace.class);
// final Function function = functionFactory.newInstance(conditional,
// resolvedAttributeMap(parameters, theIf.getOptions()));
// resolvedAttributeMap(params, theIf.getOptions()));
return result;
}

private void processFunction(final Expression expression, final List<String> params) {
try {
final FixMethod method = FixMethod.valueOf(expression.getName());
final List<String> resolvedParams = params.stream().map(this::resolveVars).collect(Collectors.toList());
final Map<String, String> options = options(((MethodCall) expression).getOptions());
method.apply(metafix, record, resolvedParams, options);
method.apply(metafix, record, params, options);
}
catch (final IllegalArgumentException e) {
throw new MetafactureException(e);
Expand Down
120 changes: 120 additions & 0 deletions metafix/src/test/java/org/metafacture/metafix/MetafixIfTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.metafacture.framework.StreamReceiver;

import com.google.common.collect.ImmutableMap;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
Expand Down Expand Up @@ -515,4 +516,123 @@ public void ifAnyMatchElsif() {
o.get().endRecord();
});
}

@Test
public void shouldResolveVariablesInIf() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"if any_contain('name', 'Uni$[var]sity')",
" add_field('type', 'Organization')",
"end"
),
ImmutableMap.of("var", "ver"),
i -> {
i.startRecord("1");
i.literal("name", "Mary");
i.literal("name", "A University");
i.endRecord();

i.startRecord("2");
i.literal("name", "Mary");
i.literal("name", "Max");
i.endRecord();

i.startRecord("3");
i.endRecord();
},
o -> {
o.get().startRecord("1");
o.get().startEntity("name");
o.get().literal("1", "Mary");
o.get().literal("2", "A University");
o.get().endEntity();
o.get().literal("type", "Organization");
o.get().endRecord();

o.get().startRecord("2");
o.get().startEntity("name");
o.get().literal("1", "Mary");
o.get().literal("2", "Max");
o.get().endEntity();
o.get().endRecord();

o.get().startRecord("3");
o.get().endRecord();
}
);
}

@Test
public void shouldResolveVariablesInElsIf() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"if any_match('name', '.*University.*')",
" add_field('type', 'Organization')",
"elsif any_match('$[var]e', '[^ ]* [^ ]*')",
" add_field('type', 'Person')",
"else",
" add_field('type', 'Unknown')",
"end"
),
ImmutableMap.of("var", "nam"),
i -> {
i.startRecord("1");
i.literal("name", "Max Power");
i.endRecord();

i.startRecord("2");
i.literal("name", "Some University");
i.endRecord();

i.startRecord("3");
i.literal("name", "Filibandrina");
i.endRecord();
},
o -> {
o.get().startRecord("1");
o.get().literal("name", "Max Power");
o.get().literal("type", "Person");
o.get().endRecord();

o.get().startRecord("2");
o.get().literal("name", "Some University");
o.get().literal("type", "Organization");
o.get().endRecord();

o.get().startRecord("3");
o.get().literal("name", "Filibandrina");
o.get().literal("type", "Unknown");
o.get().endRecord();
}
);
}

@Test
public void shouldResolveVariablesInUnless() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"unless any_match('name', '.*Uni$[var]sity.*')",
" add_field('type', 'Person')",
"end"
),
ImmutableMap.of("var", "ver"),
i -> {
i.startRecord("1");
i.literal("name", "Max");
i.endRecord();

i.startRecord("2");
i.literal("name", "Some University");
i.endRecord();
},
o -> {
o.get().startRecord("1");
o.get().literal("name", "Max");
o.get().literal("type", "Person");
o.get().endRecord();

o.get().startRecord("2");
o.get().literal("name", "Some University");
o.get().endRecord();
}
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

import org.metafacture.framework.helpers.DefaultStreamReceiver;

import com.google.common.collect.ImmutableMap;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
Expand All @@ -37,6 +40,48 @@ public class MetafixScriptTest {
public MetafixScriptTest() {
}

@Test
public void shouldPutSingleVariable() {
assertVar("put_var('varName', 'value')",
null,
ImmutableMap.of("varName", "value"));
}

@Test
public void shouldPutMultipleVariables() {
assertVar("put_var('varName', 'value')\nput_var('varName2', 'value2')",
null,
ImmutableMap.of("varName", "value", "varName2", "value2"));
}

@Test
public void shouldPutMultipleVariablesFromMap() {
assertVar("put_vars(varName: 'value', varName2: 'value2')",
null,
ImmutableMap.of("varName", "value", "varName2", "value2"));
}

@Test
public void shouldResolveVariablesInSingleVariable() {
assertVar("put_var('varName', 'value$[var]')",
ImmutableMap.of("var", "1"),
ImmutableMap.of("varName", "value1"));
}

@Test
public void shouldResolveVariablesInMultipleVariables() {
assertVar("put_var('varName', 'value$[var]')\nput_var('$[varName]Var', 'value2')",
ImmutableMap.of("var", "1"),
ImmutableMap.of("varName", "value1", "value1Var", "value2"));
}

@Test
public void shouldNotResolveVariablesInMultipleVariablesFromMap() {
assertVar("put_vars(varName: 'value$[var]', '$[varName]Var': 'value2')",
ImmutableMap.of("var", "1"),
ImmutableMap.of("varName", "value$[var]", "$[varName]Var", "value2"));
}

@Test
public void shouldPutEmptyInternalMap() {
assertMap("put_map('" + MAP_NAME + "')", MAP_NAME);
Expand Down Expand Up @@ -83,6 +128,10 @@ public void shouldPutExternalFileMapWithNameAndOptions() {
assertMap("put_filemap('" + TSV_MAP + "', '" + MAP_NAME + "', sep_char: '\t')", MAP_NAME);
}

private void assertVar(final String fixDef, final Map<String, String> vars, final Map<String, String> result) {
assertFix(fixDef, vars, f -> result.forEach((k, v) -> Assertions.assertEquals(v, f.getVars().get(k))));
}

private void assertMap(final String fixDef, final String mapName) {
assertFix(fixDef, f -> assertMap(f, mapName));
}
Expand All @@ -93,8 +142,12 @@ private void assertMap(final Metafix metafix, final String mapName) {
}

private void assertFix(final String fixDef, final Consumer<Metafix> consumer) {
assertFix(fixDef, null, consumer);
}

private void assertFix(final String fixDef, final Map<String, String> vars, final Consumer<Metafix> consumer) {
try {
final Metafix metafix = new Metafix(fixDef);
final Metafix metafix = vars == null ? new Metafix(fixDef) : new Metafix(fixDef, new HashMap<>(vars));

// Prepare and trigger script execution
metafix.setReceiver(new DefaultStreamReceiver());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public class MetafixTest {
public MetafixTest() {
}

@Test
public void shouldPutVar() {
final Metafix metafix = new Metafix();
metafix.putVar(KEY, VALUE);

Assertions.assertEquals(VALUE, metafix.getVars().get(KEY));
}

@Test
public void shouldGetMapNames() {
final Metafix metafix = new Metafix();
Expand Down

0 comments on commit 53ebbda

Please sign in to comment.