Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Vars support. #91

Merged
merged 3 commits into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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