/*******************************************************************************
* Copyright 2014 JHC Systems Limited
*
* 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.
*******************************************************************************/
package jhc.redsniff.internal.finders;
import static jhc.redsniff.internal.finders.OnlyFinder.only;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import jhc.redsniff.action.ActionPerformer;
import jhc.redsniff.action.ActionableFinder;
import jhc.redsniff.core.Finder;
import jhc.redsniff.core.MFinder;
import jhc.redsniff.core.SFinder;
import jhc.redsniff.internal.core.CollectionOf;
import jhc.redsniff.internal.core.Item;
import jhc.redsniff.internal.core.Quantity;
import jhc.redsniff.internal.finders.within.SFinderWithinMFinder;
import jhc.redsniff.internal.finders.within.SFinderWithinSFinder;
public abstract class AsActionableFinder {
private static final class TheOnlyActionableFinder<E, C> extends
WrappingSFinder<E, C> implements ActionableFinder<E, Item<E>, C> {
private TheOnlyActionableFinder(SFinder<E, C> wrappedFinder) {
super(wrappedFinder);
}
@Override
public <OE extends C, OC> SFinder<E, OC> within(
SFinder<OE, OC> scopeFinder) {
return SFinderWithinSFinder.finderWithin(this, scopeFinder);
}
@Override
public <OE extends C, OC> SFinderWithinMFinder<E, C, OE, OC> withinEach(
MFinder<OE, OC> scopeFinder) {
return new SFinderWithinMFinder<E, C, OE, OC>(this, scopeFinder);
}
@Override
public void performAction(ActionPerformer<E> performer, Item<E> item) {
performer.performAction(item.get());
}
@Override
public SFinder<E, C> asOptimizedFinder() {
return new TheOnlyActionableFinder<>(wrappedFinder.asOptimizedFinder());
}
@Override
public void describeTypeOfActionTo(Description description) {
//nothing to add
}
}
private static final class EachItemActionableMFinder<E, C> extends
WrappingMFinder<E, C> implements
ActionableFinder<E, CollectionOf<E>, C> {
private EachItemActionableMFinder(MFinder<E, C> wrappedFinder) {
super(wrappedFinder);
}
//TODO this 'each' behaviour should probably be part of a special type of ActionPerformer wrapper, rather than on the finder
@Override
public void performAction(ActionPerformer<E> performer,
CollectionOf<E> items) {
for (E item : items)
performer.performAction(item);
}
@Override
public MFinder<E, C> asOptimizedFinder() {
return new EachItemActionableMFinder<E, C>(
wrappedFinder.asOptimizedFinder());
}
@Override
public MFinder<E, C> that(Matcher<? super E> elementMatcher) {
return new EachItemActionableMFinder<>(
wrappedFinder.that(elementMatcher));
}
@Override
public MFinder<E, C> optimizedWith(Matcher<? super E> matcher) {
return new EachItemActionableMFinder<>(
wrappedFinder.optimizedWith(matcher));
}
@Override
public void describeTypeOfActionTo(Description description) {
description.appendText(" each one found");
}
}
public static <E, C> ActionableFinder<E, CollectionOf<E>, C> each(
MFinder<E, C> finder) {
return new EachItemActionableMFinder<E, C>(finder);
}
public static <E, Q extends Quantity<E>, C> ActionableFinder<E, Item<E>, C> theOnly(
Finder<E, Q, C> finder) {
return new TheOnlyActionableFinder<E, C>(only(finder));
}
}