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 * @version $Id: IfClosure.html 972421 2015-11-14 20:00:04Z tn $
030 */
031public class IfClosure<E> implements Closure<E>, Serializable {
032
033    /** Serial version UID */
034    private static final long serialVersionUID = 3518477308466486130L;
035
036    /** The test */
037    private final Predicate<? super E> iPredicate;
038    /** The closure to use if true */
039    private final Closure<? super E> iTrueClosure;
040    /** The closure to use if false */
041    private final Closure<? super E> iFalseClosure;
042
043    /**
044     * Factory method that performs validation.
045     * <p>
046     * This factory creates a closure that performs no action when
047     * the predicate is false.
048     *
049     * @param <E> the type that the closure acts on
050     * @param predicate  predicate to switch on
051     * @param trueClosure  closure used if true
052     * @return the <code>if</code> closure
053     * @throws IllegalArgumentException if either argument is null
054     * @since 3.2
055     */
056    public static <E> Closure<E> ifClosure(final Predicate<? super E> predicate, final Closure<? super E> trueClosure) {
057        return IfClosure.<E>ifClosure(predicate, trueClosure, NOPClosure.<E>nopClosure());
058    }
059
060    /**
061     * Factory method that performs validation.
062     *
063     * @param <E> the type that the closure acts on
064     * @param predicate  predicate to switch on
065     * @param trueClosure  closure used if true
066     * @param falseClosure  closure used if false
067     * @return the <code>if</code> closure
068     * @throws IllegalArgumentException if any argument is null
069     */
070    public static <E> Closure<E> ifClosure(final Predicate<? super E> predicate,
071                                           final Closure<? super E> trueClosure,
072                                           final Closure<? super E> falseClosure) {
073        if (predicate == null) {
074            throw new IllegalArgumentException("Predicate must not be null");
075        }
076        if (trueClosure == null || falseClosure == null) {
077            throw new IllegalArgumentException("Closures must not be null");
078        }
079        return new IfClosure<E>(predicate, trueClosure, falseClosure);
080    }
081
082    /**
083     * Constructor that performs no validation.
084     * Use <code>ifClosure</code> if you want that.
085     * <p>
086     * This constructor creates a closure that performs no action when
087     * the predicate is false.
088     *
089     * @param predicate  predicate to switch on, not null
090     * @param trueClosure  closure used if true, not null
091     * @since 3.2
092     */
093    public IfClosure(final Predicate<? super E> predicate, final Closure<? super E> trueClosure) {
094        this(predicate, trueClosure, NOPClosure.nopClosure());
095    }
096
097    /**
098     * Constructor that performs no validation.
099     * Use <code>ifClosure</code> if you want that.
100     *
101     * @param predicate  predicate to switch on, not null
102     * @param trueClosure  closure used if true, not null
103     * @param falseClosure  closure used if false, not null
104     */
105    public IfClosure(final Predicate<? super E> predicate, final Closure<? super E> trueClosure,
106                     final Closure<? super E> falseClosure) {
107        super();
108        iPredicate = predicate;
109        iTrueClosure = trueClosure;
110        iFalseClosure = falseClosure;
111    }
112
113    /**
114     * Executes the true or false closure according to the result of the predicate.
115     *
116     * @param input  the input object
117     */
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}