Getting a lambda expression for translation at runtime is a virtually impossible task (so far), I'll try to give you two suggestions:
1 - Think of a simpler solution that does not involve a translation in the way you described;
2 - If you really need to do this, I believe the lambda-from-string can help you with a slightly different solution (Function instead of Predicate).
I tried to simplify as much as I could, but still I still do not think it's a very interesting solution for production (mainly due to performance).
SOLUTION
Instead of trying to catch the lambda expression at runtime we can eval of an expression (String) by applying the translation and converting the String into a > Function .
pom.xml
<dependency>
<groupId>pl.joegreen</groupId>
<artifactId>lambda-from-string</artifactId>
<version>1.6</version>
</dependency>
We started by defining an expression translation interface:
public interface FunctionTranslator<T> {
void eval(String lambda, LambdaFactory factory) throws LambdaCreationException;
T getFunction();
}
Implementing the translator of an expression that compares integers:
public class CompareIntegersFunctionTranslator implements FunctionTranslator<Function<Integer, Boolean>> {
private final String TRANSLATOR_PATTERN = "{$var%s} === %s";
private final TypeReference<Function<Integer, Boolean>> TYPE_REFERENCE = new TypeReference<Function<Integer,Boolean>>(){};
private String translatedLambda;
private Function<Integer, Boolean> function;
@Override
public void eval(String lambda, LambdaFactory factory) throws LambdaCreationException {
this.function = factory.createLambda(lambda, TYPE_REFERENCE);
this.translatedLambda = translate(lambda);
}
@Override
public Function<Integer, Boolean> getFunction() {
return function;
}
private String translate(String expression) {
String [] splited = expression.split("");
return String
.format(TRANSLATOR_PATTERN,
splited[0].toUpperCase(),
splited[splited.length - 1]);
}
@Override
public String toString() {
return translatedLambda;
}
}
Implementing the translator of an expression that sums integers:
public class SumIntegersFunctionTranslator implements FunctionTranslator<Function<Integer, Integer>> {
private final String TRANSLATOR_PATTERN = "{$var%s} += 1";
private final TypeReference<Function<Integer, Integer>> TYPE_REFERENCE = new TypeReference<Function<Integer, Integer>>(){};
private String translatedLambda;
private Function<Integer, Integer> function;
@Override
public void eval(String lambda, LambdaFactory factory) throws LambdaCreationException {
this.function = factory.createLambda(lambda, TYPE_REFERENCE);
this.translatedLambda = translate(lambda);
}
@Override
public Function<Integer, Integer> getFunction() {
return function;
}
private String translate(String expression) {
String [] splited = expression.split("");
return String
.format(TRANSLATOR_PATTERN,
splited[0].toUpperCase(),
splited[splited.length - 1]);
}
@Override
public String toString() {
return translatedLambda;
}
}
Translation strategy implementation:
public enum FunctionTranslatorStrategy {
COMPARE_INTEGERS(new CompareIntegersFunctionTranslator()),
SUM_INTEGERS(new SumIntegersFunctionTranslator());
FunctionTranslator<?> translator;
FunctionTranslatorStrategy(FunctionTranslator<?> translator) {
this.translator = translator;
}
public FunctionTranslator<?> getFunctionTranslator() {
return translator;
}
}
Implementation of a translator factory:
public class FunctionFactory {
private static final LambdaFactory LAMBDA_FACTORY = LambdaFactory.get();
@SuppressWarnings("unchecked")
public static <T> FunctionTranslator<T> create(
String lambda,
FunctionTranslatorStrategy strategy) throws LambdaCreationException {
FunctionTranslator<T> translator = (FunctionTranslator<T>) strategy.getFunctionTranslator();
translator.eval(lambda, LAMBDA_FACTORY);
return translator;
}
}
Testing:
public static void main(String[] args) throws LambdaCreationException {
FunctionTranslator<Function<Integer, Boolean>> compare = FunctionFactory
.create("a -> a == 1",
FunctionTranslatorStrategy.COMPARE_INTEGERS);
System.out.println(compare.toString()); // {$varA} === 1
System.out.println(compare.getFunction().apply(1)); // true
System.out.println(compare.getFunction().apply(2)); // false
FunctionTranslator<Function<Integer, Integer>> sum = FunctionFactory
.create("b -> b + 1",
FunctionTranslatorStrategy.SUM_INTEGERS);
System.out.println(sum.toString()); // {$varB} += 1
System.out.println(sum.getFunction().apply(1)); // 2
System.out.println(sum.getFunction().apply(2)); // 3
}
Note that there is repeated code and the translation method is very basic (maybe regex to improve). It is possible to greatly improve this implementation and make things simpler, this is just an idea of where to go.