All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.expectit.matcher.Matchers Maven / Gradle / Ivy

There is a newer version: 0.9.0
Show newest version
package net.sf.expectit.matcher;

/*
 * #%L
 * ExpectIt
 * %%
 * Copyright (C) 2014 Alexey Gavrilov and contributors
 * %%
 * 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.
 * #L%
 */

import static net.sf.expectit.matcher.SimpleResult.failure;
import static net.sf.expectit.matcher.SimpleResult.success;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import net.sf.expectit.MultiResult;
import net.sf.expectit.Result;


/**
 * The matcher factory.
 *
 * @author Alexey Gavrilov
 */
public final class Matchers {

    /**
     * Don't expect to create an instance of this class.
     */
    private Matchers() {
    }

    /**
     * Creates a matcher of {@code String} that matches when examined input fully matches
     * the given regular
     * expression.
     * 

* This method simply compiles the given pattern to a {@link java.util.regex.Pattern} and * passes it to the * {@link #matches(java.util.regex.Pattern)} method. * * @param pattern the pattern that represents regular expression * @return the match result * @see #regexp(java.util.regex.Pattern) */ public static Matcher matches(String pattern) { return matches(Pattern.compile(pattern)); } /** * Creates a matcher of {@code Pattern} that matches when examined input fully matches * the given regular * expression. The operation is equivalent to the {@link java.util.regex.Matcher#matches()} * method. *

* The returning {@code Result} implements the {@link java.util.regex.MatchResult} methods to * query the results * of the regular expression match. *

* If the match succeeded, the input buffer is cleared and {@link net.sf.expectit * .Result#getBefore()} returns * an empty string. * * @param pattern the representation of a regular expression * @return the match result */ public static Matcher matches(Pattern pattern) { return new RegexpMatcher(pattern, false); } /** * Creates a matcher of {@code String} that matches when examined input contains the * given regular * expression. *

* This method simply compiles the given string to a {@link java.util.regex.Pattern} and * passes it to the * {@link #regexp(java.util.regex.Pattern)} method. * * @param pattern the string that represents regular expression * @return the match result * @see #regexp(java.util.regex.Pattern) */ public static Matcher regexp(String pattern) { return regexp(Pattern.compile(pattern)); } /** * Creates a matcher of {@code Pattern} that matches when examined input contains the * given regular * expression. The operation is equivalent to the {@link java.util.regex.Matcher#find()} method. *

* The returning {@code Result} implements the {@link java.util.regex.MatchResult} methods to * query the results * of the regular expression match. *

* If the match succeeded, the input buffer is updated: the input part from the beginning * until the end * position of the match is removed. * * @param pattern the representation of a regular expression * @return the match result */ public static Matcher regexp(Pattern pattern) { return new RegexpMatcher(pattern, true); } /** * Creates a matcher of {@code String} that matches when examined input contains the given * substring. *

* The returning {@code Result} has no groups except the one with {@code 0} index which * represents the exact * string match. *

* If the match succeeded, the input buffer is updated: the input part from the beginning * until the end * position of the match is removed. * * @param string the string to search for * @return the match result */ public static Matcher contains(final String string) { return new Matcher() { @Override public Result matches(String input, boolean isEof) { int pos = input.indexOf(string); return pos != -1 ? success(input, input.substring(0, pos), string) : failure(input, false); } @Override public String toString() { return generateToString("contains", string); } }; } /** * Creates a matcher that matches if the examined input matches all of the specified * matchers. This method * evaluates all the matchers regardless intermediate results. *

* The match result represents a combination of all match operations. If succeeded, * the match result with the * greatest end position is selected to implement the result {@link Result} instance returned * by this method. * If the result is negative, then the one which fails first is returned. *

* If several matchers the have same end position, then the result from the one with the * smaller argument index is * returned. * * @param matchers the vararg array of the matchers * @return the multi match result */ public static Matcher allOf(final Matcher... matchers) { checkNotEmpty(matchers); return new MultiMatcher(true, matchers); } /** * Creates a matcher that matches if the examined input matches any of the specified * matchers. *

* The match result represents a combination of any match operations. If succeeded, * the match result with the * greatest end position is selected to implement the result {@link Result} instance returned * by this method. *

* If several matchers have the same end position, then the result from the one with the * smaller argument index is * returned. * * @param matchers the vararg array of the matchers * @return the multi match result */ public static Matcher anyOf(final Matcher... matchers) { checkNotEmpty(matchers); return new MultiMatcher(false, matchers); } /** * Creates a matcher that matches if input reaches the end of stream. *

* If succeeded, the {@link net.sf.expectit.Result#getBefore()} will return the entire input * buffer, and * the {@link net.sf.expectit.Result#group()} returns an empty string. * * @return the matcher */ public static Matcher eof() { return new Matcher() { @Override public Result matches(String input, boolean isEof) { return isEof ? success(input, input, "") : failure(input, false); } @Override public String toString() { return "eof"; } }; } /** * Creates a matcher that matches if the given {@code matcher} matches the {@code number} of * times. *

* The match result represents a combination of all the performed match operations. If * succeeded, the result * with the greatest end position is returned. *

* * @param number the number of times which the given {@code matcher} must match the input * @param matcher the matcher * @return the result */ public static Matcher times(final int number, final Matcher matcher) { Matcher[] matchers = new Matcher[number]; Arrays.fill(matchers, matcher); return sequence(matchers); } /** * Matches the given matchers one by one. Every successful matches updates the internal * buffer. The consequent * match operation is performed after the previous match has succeeded. * * @param matchers the collection of matchers. * @return the matcher. */ public static Matcher sequence(final Matcher... matchers) { checkNotEmpty(matchers); return new Matcher() { @Override public MultiResult matches(String input, boolean isEof) { int matchCount = 0; Result[] results = new Result[matchers.length]; Arrays.fill(results, failure(input, false)); int beginIndex = 0; for (int i = 0; i < matchers.length; i++) { Result result = matchers[i].matches(input.substring(beginIndex), isEof); if (result.isSuccessful()) { beginIndex += result.end(); results[i] = result; if (++matchCount == matchers.length) { String group = result.group(); Result finalResult = new SimpleResult( true, input, input.substring(0, beginIndex - group.length()), group, result.canStopMatching()); return new MultiResultImpl(finalResult, Arrays.asList(results)); } } else { break; } } final List resultList = Arrays.asList(results); boolean canStopMatching = MultiResultImpl.canStopMatching(resultList); return new MultiResultImpl(failure(input, canStopMatching), resultList); } @Override public String toString() { return String.format("sequence(%s)", MultiMatcher.matchersToString(matchers)); } }; } /** * Creates a matcher that matches when at least one character exists in the input buffer. *

* If the result is successful, the {@link net.sf.expectit.Result#getBefore()} returns an * empty string, the * {@link net.sf.expectit.Result#group()} returns the entire input buffer. * * @return the result */ public static Matcher anyString() { return new Matcher() { @Override public Result matches(String input, boolean isEof) { return input.length() > 0 ? success(input, "", input) : failure(input, false); } @Override public String toString() { return "anyString"; } }; } private static void checkNotEmpty(Matcher[] matchers) { if (matchers.length == 0) { throw new IllegalArgumentException("Matchers cannot be empty"); } } static String generateToString(String name, Object parameter) { return String.format("%s('%s')", name, parameter); } /** * Creates a matcher that matches when the given string is equal to the * input buffer contents. *

* If the result is successful, the {@link net.sf.expectit.Result#getBefore()} returns an * empty string, the {@link net.sf.expectit.Result#group()} returns the entire input buffer. * * @param exact the string to match. * @return the result. */ public static Matcher exact(final String exact) { return new Matcher() { @Override public Result matches(String input, boolean isEof) { return exact.equals(input) ? success(input, "", input) : failure(input, input.length() > exact.length()); } @Override public String toString() { return generateToString("exact", exact); } }; } /** * Creates a matcher that matches when the input buffer starts with the given string. *

* If the result is successful, the {@link net.sf.expectit.Result#getBefore()} returns an * empty string, the {@link net.sf.expectit.Result#group()} returns the given string. * * @param prefix the prefix string to match. * @return the result. */ public static Matcher startsWith(final String prefix) { return new Matcher() { @Override public Result matches(String input, boolean isEof) { return input.startsWith(prefix) ? success(input, "", prefix) : failure(input, input.length() > prefix.length()); } @Override public String toString() { return generateToString("startsWith", prefix); } }; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy