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 java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import net.sf.expectit.MultiResult; import net.sf.expectit.Result; /** * A class to accommodate results of the multiple matches. * * @author Alexey Gavrilov */ class MultiMatcher implements Matcher<MultiResult> { private final Matcher<?>[] matchers; private final boolean allOperation; public MultiMatcher(boolean allOperation, Matcher<?>... matchers) { this.matchers = matchers; this.allOperation = allOperation; } @Override public MultiResult matches(String input, boolean isEof) { List<Result> results = new ArrayList<Result>(); List<Result> successResults = new ArrayList<Result>(); Result firstFailResult = null; for (Matcher<?> matcher : matchers) { Result result = matcher.matches(input, isEof); if (result.isSuccessful()) { successResults.add(result); } else if (firstFailResult == null) { firstFailResult = result; } results.add(result); } Result delegate; if (allOperation) { delegate = getAllOfResult(successResults, firstFailResult); } else { delegate = getAnyOfResult(successResults, results); } return new MultiResultImpl(delegate, results); } private Result getAllOfResult(List<Result> successResults, Result firstFailResult) { if (firstFailResult == null) { return findResultWithMaxEnd(successResults); } return firstFailResult; } private Result getAnyOfResult(List<Result> successResults, List<Result> results) { if (successResults.size() > 0) { return findResultWithMaxEnd(successResults); } else { return results.get(0); } } /** * Find the result with the maximum end position and use it as delegate. */ private static Result findResultWithMaxEnd(List<Result> successResults) { return Collections.max( successResults, new Comparator<Result>() { @Override public int compare(Result o1, Result o2) { return Integer.valueOf(o1.end()).compareTo(o2.end()); } }); } @Override public String toString() { StringBuilder matchersString = matchersToString(matchers); if (allOperation) { return String.format("allOf(%s)", matchersString); } return String.format("anyOf(%s)", matchersString); } static StringBuilder matchersToString(final Matcher ... matchers) { StringBuilder matchersString = new StringBuilder(); for (Matcher<?> matcher : matchers) { if (matchersString.length() > 0) { matchersString.append(','); } matchersString.append(String.valueOf(matcher)); } return matchersString; } }