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

Commit

Permalink
Allow custom Java predicates to be called from Fix. (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
blackwinter committed Jan 14, 2022
1 parent ee0e578 commit 01cac68
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 29 deletions.
6 changes: 3 additions & 3 deletions metafix/src/main/java/org/metafacture/metafix/Fix.xtext
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ 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?
'end'
;

ElsIf:
'elsif' name = ValidID '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')'
'elsif' name = QualifiedName '(' ( params += (QualifiedName|STRING) ( ',' params += (QualifiedName|STRING) )* )? ')'
elements += Expression*
;

Expand Down
24 changes: 3 additions & 21 deletions metafix/src/main/java/org/metafacture/metafix/FixConditional.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@

package org.metafacture.metafix;

import org.metafacture.metafix.api.FixPredicate;

import java.util.List;
import java.util.Map;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Stream;

enum FixConditional {
public enum FixConditional implements FixPredicate {

all_contain {
@Override
Expand Down Expand Up @@ -86,23 +85,6 @@ public boolean test(final Metafix metafix, final Record record, final List<Strin
public boolean test(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
return !any_match.test(metafix, record, params, options);
}
};

public static final BiPredicate<Stream<Value>, Predicate<Value>> ALL = (s, p) -> s.allMatch(p);
public static final BiPredicate<Stream<Value>, Predicate<Value>> ANY = (s, p) -> s.anyMatch(p);

public static final BiPredicate<Value, String> CONTAINS = (v, s) -> v.toString().contains(s);
public static final BiPredicate<Value, String> EQUALS = (v, s) -> v.toString().equals(s);
public static final BiPredicate<Value, String> MATCHES = (v, s) -> v.toString().matches(s);

private static boolean testConditional(final Record record, final List<String> params, final BiPredicate<Stream<Value>, Predicate<Value>> qualifier, final BiPredicate<Value, String> 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, string));
}

abstract boolean test(Metafix metafix, Record record, List<String> params, Map<String, String> options);

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.metafacture.commons.reflection.ReflectionUtil;
import org.metafacture.framework.MetafactureException;
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;
Expand All @@ -36,6 +37,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -161,7 +163,7 @@ private boolean testConditional(final String conditional, final List<String> par
LOG.debug("<IF>: {} parameters: {}", conditional, params);

try {
final FixConditional predicate = FixConditional.valueOf(conditional);
final FixPredicate predicate = getInstance(conditional, FixPredicate.class, FixConditional::valueOf);
return predicate.test(metafix, record, params, options(null)); // TODO: options
}
catch (final IllegalArgumentException e) {
Expand All @@ -177,18 +179,19 @@ private boolean testConditional(final String conditional, final List<String> par
}

private void processFunction(final Expression expression, final List<String> params) {
final String name = expression.getName();

try {
final FixFunction function = name.contains(".") ?
ReflectionUtil.loadClass(name, FixFunction.class).newInstance() : FixMethod.valueOf(name);
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> T getInstance(final String name, final Class<T> baseType, final Function<String, ? extends T> enumFunction) {
return name.contains(".") ? ReflectionUtil.loadClass(name, baseType).newInstance() : enumFunction.apply(name);
}

private Map<String, String> options(final Options options) {
final Map<String, String> map = new LinkedHashMap<>();
if (options != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Stream<Value>, Predicate<Value>> ALL = Stream::allMatch;
BiPredicate<Stream<Value>, Predicate<Value>> ANY = Stream::anyMatch;

BiPredicate<String, String> CONTAINS = String::contains;
BiPredicate<String, String> EQUALS = String::equals;
BiPredicate<String, String> MATCHES = String::matches;

boolean test(Metafix metafix, Record record, List<String> params, Map<String, String> options);

default boolean testConditional(final Record record, final List<String> params, final BiPredicate<Stream<Value>, Predicate<Value>> qualifier, final BiPredicate<String, String> 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));
}

}
38 changes: 38 additions & 0 deletions metafix/src/test/java/org/metafacture/metafix/MetafixIfTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -635,4 +635,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();
}
);
}

}
Original file line number Diff line number Diff line change
@@ -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<String> params, final Map<String, String> options) {
return !FixConditional.exists.test(metafix, record, params, options) ||
FixConditional.any_equal.test(metafix, record, params, options);
}

}

0 comments on commit 01cac68

Please sign in to comment.