diff --git a/metafix/src/main/java/org/metafacture/metafix/Fix.xtext b/metafix/src/main/java/org/metafacture/metafix/Fix.xtext index f107b2c2..09bd671b 100644 --- a/metafix/src/main/java/org/metafacture/metafix/Fix.xtext +++ b/metafix/src/main/java/org/metafacture/metafix/Fix.xtext @@ -16,13 +16,13 @@ Expression: ; Unless: - 'unless' name = ValidID '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')' + 'unless' name = QualifiedName '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')' elements += Expression* 'end' ; If: - 'if' name = ValidID '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')' + 'if' name = QualifiedName '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')' elements += Expression* elseIf = ElsIf? else = Else? @@ -30,7 +30,7 @@ If: ; ElsIf: - 'elsif' name = ValidID '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')' + 'elsif' name = QualifiedName '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')' elements += Expression* ; @@ -46,7 +46,7 @@ Do: ; MethodCall: - name = ValidID '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* ','? )? ( options = Options )? ')' + name = QualifiedName '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* ','? )? ( options = Options )? ')' ; Options: diff --git a/metafix/src/main/java/org/metafacture/metafix/FixConditional.java b/metafix/src/main/java/org/metafacture/metafix/FixConditional.java new file mode 100644 index 00000000..d3f61b37 --- /dev/null +++ b/metafix/src/main/java/org/metafacture/metafix/FixConditional.java @@ -0,0 +1,90 @@ +/* + * Copyright 2021 Fabian Steeg, hbz + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.metafacture.metafix; + +import org.metafacture.metafix.api.FixPredicate; + +import java.util.List; +import java.util.Map; + +public enum FixConditional implements FixPredicate { + + all_contain { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return testConditional(record, params, ALL, CONTAINS); + } + }, + any_contain { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return testConditional(record, params, ANY, CONTAINS); + } + }, + none_contain { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return !any_contain.test(metafix, record, params, options); + } + }, + + all_equal { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return testConditional(record, params, ALL, EQUALS); + } + }, + any_equal { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return testConditional(record, params, ANY, EQUALS); + } + }, + none_equal { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return !any_equal.test(metafix, record, params, options); + } + }, + + exists { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return record.containsField(params.get(0)); + } + }, + + all_match { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return testConditional(record, params, ALL, MATCHES); + } + }, + any_match { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return testConditional(record, params, ANY, MATCHES); + } + }, + none_match { + @Override + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return !any_match.test(metafix, record, params, options); + } + } + +} diff --git a/metafix/src/main/java/org/metafacture/metafix/FixMethod.java b/metafix/src/main/java/org/metafacture/metafix/FixMethod.java index 3ad98280..d91ca193 100644 --- a/metafix/src/main/java/org/metafacture/metafix/FixMethod.java +++ b/metafix/src/main/java/org/metafacture/metafix/FixMethod.java @@ -16,35 +16,35 @@ package org.metafacture.metafix; +import org.metafacture.metafix.api.FixFunction; import org.metafacture.metamorph.api.Maps; import org.metafacture.metamorph.maps.FileMap; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; -import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.UnaryOperator; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import java.util.stream.Stream; -enum FixMethod { +public enum FixMethod implements FixFunction { // SCRIPT-LEVEL METHODS: nothing { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { // do nothing } }, put_filemap { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String fileName = params.get(0); final FileMap fileMap = new FileMap(); @@ -56,16 +56,19 @@ public void apply(final Metafix metafix, final Record record, final List } }, put_map { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { metafix.putMap(params.get(0), options); } }, put_var { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { metafix.getVars().put(params.get(0), params.get(1)); } }, put_vars { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { metafix.getVars().putAll(options); } @@ -74,11 +77,13 @@ public void apply(final Metafix metafix, final Record record, final List // RECORD-LEVEL METHODS: add_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.append(params.get(0), params.get(1)); } }, array { // array-from-hash + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String field = params.get(0); @@ -93,11 +98,13 @@ public void apply(final Metafix metafix, final Record record, final List } }, copy_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.copy(params); } }, format { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String field = params.get(0); @@ -108,6 +115,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, hash { // hash-from-array + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String field = params.get(0); @@ -119,12 +127,14 @@ public void apply(final Metafix metafix, final Record record, final List } }, move_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.copy(params); record.removeNested(params.get(0)); } }, parse_text { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String field = params.get(0); @@ -162,6 +172,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, paste { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String joinChar = options.get("join_char"); record.replace(params.get(0), params.subList(1, params.size()).stream() @@ -175,6 +186,7 @@ private boolean literalString(final String s) { } }, random { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String field = params.get(0); final int max = getInteger(params, 1); @@ -183,16 +195,19 @@ public void apply(final Metafix metafix, final Record record, final List } }, reject { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.setReject(true); } }, remove_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { params.forEach(record::removeNested); } }, rename { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String search = params.get(1); final String replace = params.get(2); @@ -223,11 +238,13 @@ private Value renameValue(final Value value, final UnaryOperator operato } }, retain { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.retainFields(params); } }, set_array { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String field = params.get(0); final List toAdd = params.subList(1, params.size()); @@ -240,11 +257,13 @@ public void apply(final Metafix metafix, final Record record, final List } }, set_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.replace(params.get(0), params.get(1)); } }, set_hash { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String field = params.get(0); @@ -260,6 +279,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, vacuum { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.removeEmptyValues(); } @@ -270,17 +290,20 @@ public void apply(final Metafix metafix, final Record record, final List // TODO SPEC: switch to morph-style named params in general? append { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String value = params.get(1); record.transformFields(params, s -> s + value); } }, capitalize { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformFields(params, s -> s.substring(0, 1).toUpperCase() + s.substring(1)); } }, count { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformField(params.get(0), (m, c) -> m .ifArray(a -> c.accept(new Value(a.size()))) @@ -289,11 +312,13 @@ public void apply(final Metafix metafix, final Record record, final List } }, downcase { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformFields(params, String::toLowerCase); } }, filter { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final Pattern search = Pattern.compile(params.get(1)); final boolean invert = getBoolean(options, "invert"); @@ -306,12 +331,14 @@ public void apply(final Metafix metafix, final Record record, final List } }, index { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String search = params.get(1); record.transformFields(params, s -> String.valueOf(s.indexOf(search))); // TODO: multiple } }, join_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String joinChar = params.size() > 1 ? params.get(1) : ""; record.transformField(params.get(0), (m, c) -> m @@ -320,6 +347,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, lookup { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final Map map; @@ -341,12 +369,14 @@ public void apply(final Metafix metafix, final Record record, final List } }, prepend { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String value = params.get(1); record.transformFields(params, s -> value + s); } }, replace_all { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String search = params.get(1); final String replace = params.get(2); @@ -355,6 +385,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, reverse { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformField(params.get(0), (m, c) -> m .ifArray(a -> { @@ -367,6 +398,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, sort_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final boolean numeric = getBoolean(options, "numeric"); final boolean reverse = getBoolean(options, "reverse"); @@ -383,6 +415,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, split_field { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String splitChar = params.size() > 1 ? params.get(1) : "\\s+"; final Pattern splitPattern = Pattern.compile(splitChar); @@ -398,11 +431,13 @@ public void apply(final Metafix metafix, final Record record, final List } }, substring { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformFields(params, s -> s.substring(getInteger(params, 1), getInteger(params, 2) - 1)); } }, sum { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformField(params.get(0), (m, c) -> m .ifArray(a -> c.accept(new Value(a.stream().map(Value::asString).mapToInt(Integer::parseInt).sum()))) @@ -410,11 +445,13 @@ public void apply(final Metafix metafix, final Record record, final List } }, trim { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformFields(params, String::trim); } }, uniq { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformField(params.get(0), (m, c) -> m .ifArray(a -> c.accept(newArray(unique(a.stream())))) @@ -422,6 +459,7 @@ public void apply(final Metafix metafix, final Record record, final List } }, upcase { + @Override public void apply(final Metafix metafix, final Record record, final List params, final Map options) { record.transformFields(params, String::toUpperCase); } @@ -437,23 +475,4 @@ public void apply(final Metafix metafix, final Record record, final List private static final Random RANDOM = new Random(); - private static boolean getBoolean(final Map options, final String key) { - return Boolean.parseBoolean(options.get(key)); - } - - private static int getInteger(final List params, final int index) { - return Integer.parseInt(params.get(index)); - } - - private static Value newArray(final Stream stream) { - return Value.newArray(a -> stream.forEach(a::add)); - } - - private static Stream unique(final Stream stream) { - final Set set = new HashSet<>(); - return stream.filter(set::add); - } - - abstract void apply(Metafix metafix, Record record, List params, Map options); - } diff --git a/metafix/src/main/java/org/metafacture/metafix/FixPredicate.java b/metafix/src/main/java/org/metafacture/metafix/FixPredicate.java deleted file mode 100644 index 6d280c58..00000000 --- a/metafix/src/main/java/org/metafacture/metafix/FixPredicate.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2021 Fabian Steeg, hbz - * - * Licensed under the Apache License, Version 2.0 the "License"; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.metafacture.metafix; - -import java.util.List; -import java.util.function.Predicate; -import java.util.stream.Stream; - -enum FixPredicate { - - contain { - @Override - public Predicate of(final String string) { - return v -> v.toString().contains(string); - } - }, - equal { - @Override - public Predicate of(final String string) { - return v -> v.toString().equals(string); - } - }, - match { - @Override - public Predicate of(final String string) { - return v -> v.toString().matches(string); - } - }; - - abstract Predicate of(String string); - - enum Quantifier { - - all { - @Override - protected boolean test(final Record record, final String fieldName, final Predicate p) { - return testStream(record, fieldName, s -> s.allMatch(p)); - } - - }, - any { - @Override - protected boolean test(final Record record, final String fieldName, final Predicate p) { - return testStream(record, fieldName, s -> s.anyMatch(p)); - } - }, - none { - @Override - protected boolean test(final Record record, final String fieldName, final Predicate p) { - return !any.test(record, fieldName, p); - } - }; - - boolean testStream(final Record record, final String fieldName, final Predicate> p) { - final Value value = record.find(fieldName); - return value != null && p.test(value.asList(null).asArray().stream()); - } - - public boolean test(final Record record, final FixPredicate p, final List params) { - return test(record, params.get(0), p.of(params.get(1))); - } - - protected abstract boolean test(Record record, String fieldName, Predicate p); - } - -} diff --git a/metafix/src/main/java/org/metafacture/metafix/RecordTransformer.java b/metafix/src/main/java/org/metafacture/metafix/RecordTransformer.java index 38b314d2..5a10fa81 100644 --- a/metafix/src/main/java/org/metafacture/metafix/RecordTransformer.java +++ b/metafix/src/main/java/org/metafacture/metafix/RecordTransformer.java @@ -17,8 +17,10 @@ package org.metafacture.metafix; import org.metafacture.commons.StringUtil; +import org.metafacture.commons.reflection.ReflectionUtil; import org.metafacture.framework.MetafactureException; -import org.metafacture.metafix.FixPredicate.Quantifier; +import org.metafacture.metafix.api.FixFunction; +import org.metafacture.metafix.api.FixPredicate; import org.metafacture.metafix.fix.Do; import org.metafacture.metafix.fix.ElsIf; import org.metafacture.metafix.fix.Else; @@ -32,9 +34,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -158,44 +161,39 @@ private void processUnless(final Unless unless, final List params) { private boolean testConditional(final String conditional, final List params) { LOG.debug(": {} parameters: {}", conditional, params); - boolean result = false; - if ("exists".equals(conditional)) { - return record.containsField(params.get(0)); - } - if (!conditional.contains("_")) { - throw new IllegalArgumentException("Missing quantifier prefix (all_, any_, none_) for " + conditional); - } - final String[] quantifierAndPredicate = conditional.split("_"); + try { - final Quantifier quantifier = FixPredicate.Quantifier.valueOf(quantifierAndPredicate[0]); - final FixPredicate predicate = FixPredicate.valueOf(quantifierAndPredicate[1]); - result = quantifier.test(record, predicate, params); + final FixPredicate predicate = getInstance(conditional, FixPredicate.class, FixConditional::valueOf); + return predicate.test(metafix, record, params, options(null)); // TODO: options } catch (final IllegalArgumentException e) { throw new MetafactureException(e); } + // TODO, possibly: use morph functions here (& in processFunction): // final FunctionFactory functionFactory = new FunctionFactory(); // functionFactory.registerClass("not_equals", NotEquals.class); // functionFactory.registerClass("replace_all", Replace.class); // final Function function = functionFactory.newInstance(conditional, // resolvedAttributeMap(params, theIf.getOptions())); - return result; } private void processFunction(final Expression expression, final List params) { try { - final FixMethod method = FixMethod.valueOf(expression.getName()); - final Map options = options(((MethodCall) expression).getOptions()); - method.apply(metafix, record, params, options); + final FixFunction function = getInstance(expression.getName(), FixFunction.class, FixMethod::valueOf); + function.apply(metafix, record, params, options(((MethodCall) expression).getOptions())); } catch (final IllegalArgumentException e) { throw new MetafactureException(e); } } + private T getInstance(final String name, final Class baseType, final Function enumFunction) { + return name.contains(".") ? ReflectionUtil.loadClass(name, baseType).newInstance() : enumFunction.apply(name); + } + private Map options(final Options options) { - final Map map = new HashMap<>(); + final Map map = new LinkedHashMap<>(); if (options != null) { for (int i = 0; i < options.getKeys().size(); i += 1) { map.put(options.getKeys().get(i), options.getValues().get(i)); diff --git a/metafix/src/main/java/org/metafacture/metafix/api/FixFunction.java b/metafix/src/main/java/org/metafacture/metafix/api/FixFunction.java new file mode 100644 index 00000000..842ecc3f --- /dev/null +++ b/metafix/src/main/java/org/metafacture/metafix/api/FixFunction.java @@ -0,0 +1,51 @@ +/* + * Copyright 2022 hbz NRW + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.metafacture.metafix.api; + +import org.metafacture.metafix.Metafix; +import org.metafacture.metafix.Record; +import org.metafacture.metafix.Value; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +@FunctionalInterface +public interface FixFunction { + + void apply(Metafix metafix, Record record, List params, Map options); + + default boolean getBoolean(final Map options, final String key) { + return Boolean.parseBoolean(options.get(key)); + } + + default int getInteger(final List params, final int index) { + return Integer.parseInt(params.get(index)); + } + + default Value newArray(final Stream stream) { + return Value.newArray(a -> stream.forEach(a::add)); + } + + default Stream unique(final Stream stream) { + final Set set = new HashSet<>(); + return stream.filter(set::add); + } + +} diff --git a/metafix/src/main/java/org/metafacture/metafix/api/FixPredicate.java b/metafix/src/main/java/org/metafacture/metafix/api/FixPredicate.java new file mode 100644 index 00000000..ce621656 --- /dev/null +++ b/metafix/src/main/java/org/metafacture/metafix/api/FixPredicate.java @@ -0,0 +1,49 @@ +/* + * Copyright 2022 hbz NRW + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.metafacture.metafix.api; + +import org.metafacture.metafix.Metafix; +import org.metafacture.metafix.Record; +import org.metafacture.metafix.Value; + +import java.util.List; +import java.util.Map; +import java.util.function.BiPredicate; +import java.util.function.Predicate; +import java.util.stream.Stream; + +@FunctionalInterface +public interface FixPredicate { + + BiPredicate, Predicate> ALL = Stream::allMatch; + BiPredicate, Predicate> ANY = Stream::anyMatch; + + BiPredicate CONTAINS = String::contains; + BiPredicate EQUALS = String::equals; + BiPredicate MATCHES = String::matches; + + boolean test(Metafix metafix, Record record, List params, Map options); + + default boolean testConditional(final Record record, final List params, final BiPredicate, Predicate> qualifier, final BiPredicate conditional) { + final String field = params.get(0); + final String string = params.get(1); + + final Value value = record.find(field); + return value != null && qualifier.test(value.asList(null).asArray().stream(), v -> conditional.test(v.toString(), string)); + } + +} diff --git a/metafix/src/test/java/org/metafacture/metafix/MetafixIfTest.java b/metafix/src/test/java/org/metafacture/metafix/MetafixIfTest.java index 6984f150..d550b4a0 100644 --- a/metafix/src/test/java/org/metafacture/metafix/MetafixIfTest.java +++ b/metafix/src/test/java/org/metafacture/metafix/MetafixIfTest.java @@ -629,4 +629,42 @@ public void shouldResolveVariablesInUnless() { ); } + @Test + public void shouldApplyCustomJavaPredicate() { + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "if org.metafacture.metafix.util.TestPredicate(name, Test)", + " add_field('type', 'TEST')", + "end" + ), + i -> { + i.startRecord("1"); + i.literal("name", "Max"); + i.endRecord(); + + i.startRecord("2"); + i.literal("name", "Test"); + i.endRecord(); + + i.startRecord("3"); + i.literal("test", "Some University"); + i.endRecord(); + }, + o -> { + o.get().startRecord("1"); + o.get().literal("name", "Max"); + o.get().endRecord(); + + o.get().startRecord("2"); + o.get().literal("name", "Test"); + o.get().literal("type", "TEST"); + o.get().endRecord(); + + o.get().startRecord("3"); + o.get().literal("test", "Some University"); + o.get().literal("type", "TEST"); + o.get().endRecord(); + } + ); + } + } diff --git a/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java b/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java index d3b8fed2..ce1bf92c 100644 --- a/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java +++ b/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java @@ -1321,4 +1321,25 @@ public void shouldRemoveDuplicates() { ); } + @Test + public void shouldApplyCustomJavaFunction() { + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "org.metafacture.metafix.util.TestFunction(data, foo: '42', bar: 'baz')" + ), + i -> { + i.startRecord("1"); + i.literal("title", "marc"); + i.endRecord(); + }, + o -> { + o.get().startRecord("1"); + o.get().literal("title", "marc"); + o.get().literal("test", "DATA"); + o.get().literal("foo", "42"); + o.get().literal("bar", "baz"); + o.get().endRecord(); + } + ); + } + } diff --git a/metafix/src/test/java/org/metafacture/metafix/util/TestFunction.java b/metafix/src/test/java/org/metafacture/metafix/util/TestFunction.java new file mode 100644 index 00000000..7d25825e --- /dev/null +++ b/metafix/src/test/java/org/metafacture/metafix/util/TestFunction.java @@ -0,0 +1,40 @@ +/* + * Copyright 2022 hbz NRW + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.metafacture.metafix.util; + +import org.metafacture.metafix.FixMethod; +import org.metafacture.metafix.Metafix; +import org.metafacture.metafix.Record; +import org.metafacture.metafix.api.FixFunction; + +import java.util.List; +import java.util.Map; + +public class TestFunction implements FixFunction { + + public TestFunction() { + } + + public void apply(final Metafix metafix, final Record record, final List params, final Map options) { + params.add(params.get(0).toUpperCase()); + params.set(0, "test"); + FixMethod.add_field.apply(metafix, record, params, options); + + options.forEach(record::append); + } + +} diff --git a/metafix/src/test/java/org/metafacture/metafix/util/TestPredicate.java b/metafix/src/test/java/org/metafacture/metafix/util/TestPredicate.java new file mode 100644 index 00000000..c9d1cd3a --- /dev/null +++ b/metafix/src/test/java/org/metafacture/metafix/util/TestPredicate.java @@ -0,0 +1,37 @@ +/* + * Copyright 2022 hbz NRW + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.metafacture.metafix.util; + +import org.metafacture.metafix.FixConditional; +import org.metafacture.metafix.Metafix; +import org.metafacture.metafix.Record; +import org.metafacture.metafix.api.FixPredicate; + +import java.util.List; +import java.util.Map; + +public class TestPredicate implements FixPredicate { + + public TestPredicate() { + } + + public boolean test(final Metafix metafix, final Record record, final List params, final Map options) { + return !FixConditional.exists.test(metafix, record, params, options) || + FixConditional.any_equal.test(metafix, record, params, options); + } + +} diff --git a/misc/vim/syntax/metafacture-fix.vim b/misc/vim/syntax/metafacture-fix.vim index 4a5030f0..bc35c151 100644 --- a/misc/vim/syntax/metafacture-fix.vim +++ b/misc/vim/syntax/metafacture-fix.vim @@ -10,7 +10,7 @@ syn keyword fixPreProc use syn keyword fixSelector reject select syn match fixBareString /\v[^[:space:]\\,;:=>()"'\$*]+/ syn match fixComment /\v(#|\/\/).*$/ -syn match fixFunction /\v([a-z][_0-9a-zA-Z]*\.)*[a-z][_0-9a-zA-Z]*\s*\(/me=e-1,he=e-1 +syn match fixFunction /\v([a-z][_0-9a-zA-Z]*\.)*[a-zA-Z][_0-9a-zA-Z]*\s*\(/me=e-1,he=e-1 syn match fixOperator /\v(\&\&|\|\|)/ syn match fixWildcard /\v\$(append|first|last|prepend)>/ syn match fixWildcard /\v\*/