package org.docbag.expression.parser; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.docbag.expression.EmptyExpression; import org.docbag.expression.Expression; import org.docbag.expression.ExpressionFactory; /** * Regular expressions based implementation of {@link ExpressionParser}. * * <p>The expressionPattern attribute is used to find String representations of {@link Expression} objects.</p> * <p>Once found, the {@link ExpressionFactory} is used to create {@link Expression} instances.</p> * * <p>This class is reusable and thread safe.</p> * * @author Jakub Torbicki */ public class RegExpExpressionParser<R> implements ExpressionParser<String, R> { private final Pattern expressionPattern; private final ExpressionFactory<String, R> factory; public RegExpExpressionParser(String expressionPattern, ExpressionFactory<String, R> factory) { this.expressionPattern = Pattern.compile(expressionPattern, Pattern.MULTILINE | Pattern.DOTALL); this.factory = factory; } /** * @return true if expressionSource matches EXPRESSION_PATTERN */ public boolean isExpression(String expressionSource) { if (expressionSource == null) { throw new NullPointerException("expressionSource not set!"); } return expressionPattern.matcher(expressionSource).matches(); } /** * @return {@link Expression} object if the expressionSource was valid, or {@link EmptyExpression} otherwise */ public Expression<String, R> parseExpression(String expressionSource) { if (expressionSource == null) { throw new NullPointerException("expressionSource not set!"); } Matcher matcher = expressionPattern.matcher(expressionSource); if (matcher.find()) { return factory.createExpression(matcher.group(1)); } return new EmptyExpression(); } /** * The returned list contains all expression tokens together with tokens that don't match expression pattern. * * @param source tokens * @return */ public List<String> split(String source) { if (source == null) { throw new NullPointerException("source can't be null!"); } return Arrays.asList(RegExpUtil.inclusiveSplit(source, expressionPattern, 0)); } }