Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
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);
}
};
}
}