MultiArgExpressionProcessor.java
- package org.jbehave.core.expressions;
- import java.util.Collections;
- import java.util.List;
- import java.util.Optional;
- import java.util.function.Consumer;
- import java.util.function.Function;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class MultiArgExpressionProcessor<T> implements ExpressionProcessor<T> {
- private static final int ARGS_GROUP = 1;
- private final Pattern pattern;
- private final String expressionName;
- private final int minArgNumber;
- private final int maxArgNumber;
- private final Function<String, ExpressionArguments> argsParser;
- private final Function<List<String>, T> evaluator;
- public MultiArgExpressionProcessor(String expressionName, int minArgNumber, int maxArgNumber,
- Function<String, ExpressionArguments> argsParser, Function<List<String>, T> evaluator) {
- this.pattern = Pattern.compile("^" + expressionName + "\\((.*)\\)$", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
- this.expressionName = expressionName;
- this.minArgNumber = minArgNumber;
- this.maxArgNumber = maxArgNumber;
- this.argsParser = argsParser;
- this.evaluator = evaluator;
- }
- public MultiArgExpressionProcessor(String expressionName, int minArgNumber, int maxArgNumber,
- Function<List<String>, T> evaluator) {
- this(expressionName, minArgNumber, maxArgNumber, ExpressionArguments::new, evaluator);
- }
- public MultiArgExpressionProcessor(String expressionName, int expectedArgNumber,
- Function<List<String>, T> evaluator) {
- this(expressionName, expectedArgNumber, expectedArgNumber, evaluator);
- }
- public MultiArgExpressionProcessor(String expressionName, int expectedArgNumber,
- Function<String, ExpressionArguments> argsParser, Function<List<String>, T> evaluator) {
- this(expressionName, expectedArgNumber, expectedArgNumber, argsParser, evaluator);
- }
- @Override
- public Optional<T> execute(String expression) {
- Matcher expressionMatcher = pattern.matcher(expression);
- if (expressionMatcher.find()) {
- List<String> args = parseArgs(expressionMatcher.group(ARGS_GROUP));
- T expressionResult = evaluator.apply(args);
- return Optional.of(expressionResult);
- }
- return Optional.empty();
- }
- private List<String> parseArgs(String argsAsString) {
- if (minArgNumber == 1 && maxArgNumber == 1) {
- return Collections.singletonList(argsAsString);
- }
- List<String> args = argsParser.apply(argsAsString).getArguments();
- int argsNumber = args.size();
- if (minArgNumber == maxArgNumber) {
- if (argsNumber != minArgNumber) {
- throwException(argsAsString, argsNumber, error -> error.append(minArgNumber));
- }
- } else if (argsNumber < minArgNumber || argsNumber > maxArgNumber) {
- throwException(argsAsString, argsNumber, error -> error.append("from ").append(minArgNumber).append(" to "
- ).append(maxArgNumber));
- }
- return args;
- }
- private void throwException(String argsAsString, int argsNumber, Consumer<StringBuilder> expectationsAppender) {
- StringBuilder errorMessageBuilder = new StringBuilder("The expected number of arguments for '")
- .append(expressionName)
- .append("' expression is ");
- expectationsAppender.accept(errorMessageBuilder);
- errorMessageBuilder.append(", but found ")
- .append(argsNumber)
- .append(" argument");
- if (argsNumber != 1) {
- errorMessageBuilder.append('s');
- }
- if (argsNumber > 0) {
- errorMessageBuilder.append(": '").append(argsAsString).append('\'');
- }
- throw new IllegalArgumentException(errorMessageBuilder.toString());
- }
- }