    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.collections4.functors;
    018
    019import java.io.Serializable;
    020
    021import org.apache.commons.collections4.Closure;
    022import org.apache.commons.collections4.Predicate;
    023
    024/**
    025 * Closure implementation acts as an if statement calling one or other closure
    026 * based on a predicate.
    027 *
    028 * @since 3.0
    029 */
    030public class IfClosure<E> implements Closure<E>, Serializable {
    031
    032    /** Serial version UID */
    033    private static final long serialVersionUID = 3518477308466486130L;
    034
    035    /** The test */
    036    private final Predicate<? super E> iPredicate;
    037    /** The closure to use if true */
    038    private final Closure<? super E> iTrueClosure;
    039    /** The closure to use if false */
    040    private final Closure<? super E> iFalseClosure;
    041
    042    /**
    043     * Factory method that performs validation.
    044     * <p>
    045     * This factory creates a closure that performs no action when
    046     * the predicate is false.
    047     *
    048     * @param <E> the type that the closure acts on
    049     * @param predicate  predicate to switch on
    050     * @param trueClosure  closure used if true
    051     * @return the <code>if</code> closure
    052     * @throws NullPointerException if either argument is null
    053     * @since 3.2
    054     */
    055    public static <E> Closure<E> ifClosure(final Predicate<? super E> predicate, final Closure<? super E> trueClosure) {
    056        return IfClosure.<E>ifClosure(predicate, trueClosure, NOPClosure.<E>nopClosure());
    057    }
    058
    059    /**
    060     * Factory method that performs validation.
    061     *
    062     * @param <E> the type that the closure acts on
    063     * @param predicate  predicate to switch on
    064     * @param trueClosure  closure used if true
    065     * @param falseClosure  closure used if false
    066     * @return the <code>if</code> closure
    067     * @throws NullPointerException if any argument is null
    068     */
    069    public static <E> Closure<E> ifClosure(final Predicate<? super E> predicate,
    070                                           final Closure<? super E> trueClosure,
    071                                           final Closure<? super E> falseClosure) {
    072        if (predicate == null) {
    073            throw new NullPointerException("Predicate must not be null");
    074        }
    075        if (trueClosure == null || falseClosure == null) {
    076            throw new NullPointerException("Closures must not be null");
    077        }
    078        return new IfClosure<>(predicate, trueClosure, falseClosure);
    079    }
    080
    081    /**
    082     * Constructor that performs no validation.
    083     * Use <code>ifClosure</code> if you want that.
    084     * <p>
    085     * This constructor creates a closure that performs no action when
    086     * the predicate is false.
    087     *
    088     * @param predicate  predicate to switch on, not null
    089     * @param trueClosure  closure used if true, not null
    090     * @since 3.2
    091     */
    092    public IfClosure(final Predicate<? super E> predicate, final Closure<? super E> trueClosure) {
    093        this(predicate, trueClosure, NOPClosure.nopClosure());
    094    }
    095
    096    /**
    097     * Constructor that performs no validation.
    098     * Use <code>ifClosure</code> if you want that.
    099     *
    100     * @param predicate  predicate to switch on, not null
    101     * @param trueClosure  closure used if true, not null
    102     * @param falseClosure  closure used if false, not null
    103     */
    104    public IfClosure(final Predicate<? super E> predicate, final Closure<? super E> trueClosure,
    105                     final Closure<? super E> falseClosure) {
    106        super();
    107        iPredicate = predicate;
    108        iTrueClosure = trueClosure;
    109        iFalseClosure = falseClosure;
    110    }
    111
    112    /**
    113     * Executes the true or false closure according to the result of the predicate.
    114     *
    115     * @param input  the input object
    116     */
    117    @Override
    118    public void execute(final E input) {
    119        if (iPredicate.evaluate(input)) {
    120            iTrueClosure.execute(input);
    121        } else {
    122            iFalseClosure.execute(input);
    123        }
    124    }
    125
    126    /**
    127     * Gets the predicate.
    128     *
    129     * @return the predicate
    130     * @since 3.1
    131     */
    132    public Predicate<? super E> getPredicate() {
    133        return iPredicate;
    134    }
    135
    136    /**
    137     * Gets the closure called when true.
    138     *
    139     * @return the closure
    140     * @since 3.1
    141     */
    142    public Closure<? super E> getTrueClosure() {
    143        return iTrueClosure;
    144    }
    145
    146    /**
    147     * Gets the closure called when false.
    148     *
    149     * @return the closure
    150     * @since 3.1
    151     */
    152    public Closure<? super E> getFalseClosure() {
    153        return iFalseClosure;
    154    }
    155
    156}